diff --git a/components/ldap.rst b/components/ldap.rst index b1f51043dd4..08caf908fb0 100644 --- a/components/ldap.rst +++ b/components/ldap.rst @@ -20,10 +20,10 @@ You can install the component in 2 different ways: Usage ----- -The :class:`Symfony\\Component\\Ldap\\LdapClient` class provides methods +The :class:`Symfony\\Component\\Ldap\\Ldap` class provides methods to authenticate and query against an LDAP server. -The :class:`Symfony\\Component\\Ldap\\LdapClient` class can be configured +The :class:`Symfony\\Component\\Ldap\\Ldap` class can be configured using the following options: ``host`` @@ -35,11 +35,11 @@ using the following options: ``version`` The version of the LDAP protocol to use -``useSsl`` - Whether or not to secure the connection using SSL +``encryption`` + Your encryption mechanism (``ssl``, ``tls`` or ``none``) -``useStartTls`` - Whether or not to secure the connection using StartTLS +``connection_string`` + You may use this option instead of ``optReferrals`` Specifies whether to automatically follow referrals @@ -47,26 +47,83 @@ using the following options: For example, to connect to a start-TLS secured LDAP server:: - use Symfony\Component\Ldap\LdapClient; + use Symfony\Component\Ldap\Ldap; - $ldap = new LdapClient('my-server', 389, 3, false, true); + $ldap = Ldap::create('ext_ldap', array( + 'host' => 'my-server', + 'encryption' => 'ssl', + )); -The :method:`Symfony\\Component\\Ldap\\LdapClient::bind` method +Or you could directly specify a connection string:: + + use Symfony\Component\Ldap\Ldap; + + $ldap = Ldap::create('ext_ldap', array('connection_string' => 'ldaps://my-server:636')); + +The :method:`Symfony\\Component\\Ldap\\Ldap::bind` method authenticates a previously configured connection using both the distinguished name (DN) and the password of a user:: - use Symfony\Component\Ldap\LdapClient; + use Symfony\Component\Ldap\Ldap; // ... $ldap->bind($dn, $password); Once bound (or if you enabled anonymous authentication on your LDAP server), you may query the LDAP server using the -:method:`Symfony\\Component\\Ldap\\LdapClient::find` method:: +:method:`Symfony\\Component\\Ldap\\Ldap::query` method:: + + use Symfony\Component\Ldap\Ldap; + // ... + + $query = $ldap->query('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))'); + $results = $query->execute(); + + foreach ($results as $entry) { + // Do something with the results + } + +By default, LDAP entries are lazy-loaded. If you wish to fetch +all entries in a single call and do something with the results' +array, you may use the +:method:`Symfony\\Component\\Ldap\\Adapter\\ExtLdap\\Collection::toArray` method:: + + use Symfony\Component\Ldap\Ldap; + // ... + + $query = $ldap->query('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))'); + $results = $query->execute()->toArray(); + + // Do something with the results array + +Creating or updating entries +---------------------------- + +Since version 3.1, The Ldap component provides means to create +new LDAP entries, update or even delete existing ones:: - use Symfony\Component\Ldap\LdapClient; + use Symfony\Component\Ldap\Ldap; + use Symfony\Component\Ldap\Entry; // ... - $ldap->find('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))'); + $entry = new Entry('cn=Fabien Potencier,dc=symfony,dc=com', array( + 'sn' => array('fabpot'), + 'objectClass' => array('inetOrgPerson'), + )); + + $em = $ldap->getEntryManager(); + + // Creating a new entry + $em->add($entry); + + // Finding and updating an existing entry + $query = $ldap->query('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))'); + $result = $query->execute(); + $entry = $result[0]; + $entry->addAttribute('email', array('fabpot@symfony.com')); + $em->update($entry); + + // Removing an existing entry + $em->remove(new Entry('cn=Test User,dc=symfony,dc=com')); .. _Packagist: https://packagist.org/packages/symfony/ldap diff --git a/components/serializer.rst b/components/serializer.rst index 9dfe0555687..ba4a8189a5f 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -44,7 +44,7 @@ Usage Using the Serializer component is really simple. You just need to set up the :class:`Symfony\\Component\\Serializer\\Serializer` specifying -which Encoders and Normalizer are going to be available:: +which encoders and normalizer are going to be available:: use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Encoder\XmlEncoder; @@ -57,10 +57,9 @@ which Encoders and Normalizer are going to be available:: $serializer = new Serializer($normalizers, $encoders); The preferred normalizer is the -:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`, but other -normalizers are available. -To read more about them, refer to the `Normalizers`_ section of this page. All -the examples shown below use the ``ObjectNormalizer``. +:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`, +but other normalizers are available. All the examples shown below use +the ``ObjectNormalizer``. Serializing an Object --------------------- diff --git a/components/validator/resources.rst b/components/validator/resources.rst index da0698b9184..37581c0c2ed 100644 --- a/components/validator/resources.rst +++ b/components/validator/resources.rst @@ -42,7 +42,7 @@ In this example, the validation metadata is retrieved executing the { protected $name; - public static function loadValidatorMatadata(ClassMetadata $metadata) + public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('name', new Assert\NotBlank()); $metadata->addPropertyConstraint('name', new Asert\Length(array( diff --git a/components/yaml.rst b/components/yaml.rst index 6e6791413c8..e26f7c70736 100644 --- a/components/yaml.rst +++ b/components/yaml.rst @@ -127,17 +127,6 @@ error occurred: .. _components-yaml-dump: -Objects for Mappings -.................... - -Yaml :ref:`mappings ` are basically associative -arrays. You can instruct the parser to return mappings as objects (i.e. -``\stdClass`` instances) by setting the fourth argument to ``true``:: - - $object = Yaml::parse('{"foo": "bar"}', false, false, true); - echo get_class($object); // stdClass - echo $object->foo; // bar - Writing YAML Files ~~~~~~~~~~~~~~~~~~ @@ -214,30 +203,29 @@ changed using the third argument as follows:: foo: bar bar: baz -Invalid Types and Object Serialization -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Advanced Usage: Flags +--------------------- -By default the YAML component will encode any "unsupported" type (i.e. -resources and objects) as ``null``. +.. versionadded:: 3.1 + Flags were introduced in Symfony 3.1 and replaced the earlier boolean + arguments. -Instead of encoding as ``null`` you can choose to throw an exception if an invalid -type is encountered in either the dumper or parser as follows:: +.. _objects-for-mappings: - // throw an exception if a resource or object is encountered - Yaml::dump($data, 2, 4, true); +Object Parsing and Dumping +~~~~~~~~~~~~~~~~~~~~~~~~~~ - // throw an exception if an encoded object is found in the YAML string - Yaml::parse($yaml, true); - -However, you can activate object support using the next argument:: +You can dump objects by using the ``DUMP_OBJECT`` flag:: $object = new \stdClass(); $object->foo = 'bar'; - $dumped = Yaml::dump($object, 2, 4, false, true); - // !!php/object:O:8:"stdClass":1:{s:5:"foo";s:7:"bar";} + $dumped = Yaml::dump($object, 2, 4, Yaml::DUMP_OBJECT); + // !php/object:O:8:"stdClass":1:{s:5:"foo";s:7:"bar";} + +And parse them by using the ``PARSE_OBJECT`` flag:: - $parsed = Yaml::parse($dumped, false, true); + $parsed = Yaml::parse($dumped, Yaml::PARSE_OBJECT); var_dump(is_object($parsed)); // true echo $parsed->foo; // bar @@ -250,6 +238,61 @@ representation of the object. parsers will likely not recognize the ``php/object`` tag and non-PHP implementations certainly won't - use with discretion! +.. _invalid-types-and-object-serialization: + +Handling Invalid Types +~~~~~~~~~~~~~~~~~~~~~~ + +By default the parser will encode invalid types as ``null``. You can make the +parser throw exceptions by using the ``PARSE_EXCEPTION_ON_INVALID_TYPE`` +flag:: + + $yaml = '!php/object:O:8:"stdClass":1:{s:5:"foo";s:7:"bar";}'; + Yaml::parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); // throws an exception + +Similarly you can use ``DUMP_EXCEPTION_ON_INVALID_TYPE`` when dumping:: + + $data = new \stdClass(); // by default objects are invalid. + Yaml::dump($data, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); // throws an exception + + echo $yaml; // { foo: bar } + +Date Handling +~~~~~~~~~~~~~ + +By default the YAML parser will convert unquoted strings which look like a +date or a date-time into a Unix timestamp; for example ``2016-05-27`` or +``2016-05-27T02:59:43.1Z`` (ISO-8601_):: + + Yaml::parse('2016-05-27'); // 1464307200 + +You can make it convert to a ``DateTime`` instance by using the ``PARSE_DATETIME`` +flag:: + + $date = Yaml::parse('2016-05-27', Yaml::PARSE_DATETIME); + var_dump(get_class($date)); // DateTime + +Dumping Multi-line Literal Blocks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In YAML multiple lines can be represented as literal blocks, by default the +dumper will encode multiple lines as an inline string:: + + $string = array("string" => "Multiple\nLine\nString"); + $yaml = Yaml::dump($string); + echo $yaml; // string: "Multiple\nLine\nString" + +You can make it use a literal block with the ``DUMP_MULTI_LINE_LITERAL_BLOCK`` +flag:: + + $string = array("string" => "Multiple\nLine\nString"); + $yaml = Yaml::dump($string, 2, 4, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); + echo $yaml; + // string: | + // Multiple + // Line + // String + Learn More ---------- @@ -262,3 +305,4 @@ Learn More .. _YAML: http://yaml.org/ .. _Packagist: https://packagist.org/packages/symfony/yaml .. _`YAML 1.2 version specification`: http://yaml.org/spec/1.2/spec.html +.. _ISO-8601: http://www.iso.org/iso/iso8601 diff --git a/create_framework/unit_testing.rst b/create_framework/unit_testing.rst index 1236c615990..7254dbebe0f 100644 --- a/create_framework/unit_testing.rst +++ b/create_framework/unit_testing.rst @@ -92,7 +92,7 @@ We are now ready to write our first test:: private function getFrameworkForException($exception) { - $matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface'); + $matcher = $this->createMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface'); $matcher ->expects($this->once()) ->method('match') @@ -101,10 +101,10 @@ We are now ready to write our first test:: $matcher ->expects($this->once()) ->method('getContext') - ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext'))) + ->will($this->returnValue($this->createMock('Symfony\Component\Routing\RequestContext'))) ; - $controllerResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); - $argumentResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); + $controllerResolver = $this->createMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); + $argumentResolver = $this->createMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); return new Framework($matcher, $controllerResolver, $argumentResolver); } @@ -149,7 +149,7 @@ Response:: public function testControllerResponse() { - $matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface'); + $matcher = $this->createMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface'); $matcher ->expects($this->once()) ->method('match') @@ -164,7 +164,7 @@ Response:: $matcher ->expects($this->once()) ->method('getContext') - ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext'))) + ->will($this->returnValue($this->createMock('Symfony\Component\Routing\RequestContext'))) ; $controllerResolver = new ControllerResolver(); $argumentResolver = new ArgumentResolver(); diff --git a/form/unit_testing.rst b/form/unit_testing.rst index dca8f7d643c..66923ad830e 100644 --- a/form/unit_testing.rst +++ b/form/unit_testing.rst @@ -127,7 +127,7 @@ make sure the ``FormRegistry`` uses the created instance:: protected function setUp() { // mock any dependencies - $this->entityManager = $this->getMock('Doctrine\Common\Persistence\ObjectManager'); + $this->entityManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock(); parent::setUp(); } @@ -178,7 +178,7 @@ allows you to return a list of extensions to register:: protected function getExtensions() { - $this->validator = $this->getMock( + $this->validator = $this->createMock( 'Symfony\Component\Validator\Validator\ValidatorInterface' ); $this->validator diff --git a/forms.rst b/forms.rst index 6c1ebd9e6a3..09ca3f5b168 100644 --- a/forms.rst +++ b/forms.rst @@ -567,7 +567,7 @@ the correct values of a number of field options. guessed from the validation constraints (if ``Length`` or ``Range`` is used) or from the Doctrine metadata (via the field's length). -.. note:: +.. caution:: These field options are *only* guessed if you're using Symfony to guess the field type (i.e. omit or pass ``null`` as the second argument to ``add()``). diff --git a/reference/constraints/UserPassword.rst b/reference/constraints/UserPassword.rst index caa792b8776..594027ec889 100644 --- a/reference/constraints/UserPassword.rst +++ b/reference/constraints/UserPassword.rst @@ -24,7 +24,7 @@ password, but needs to enter their old password for security. Basic Usage ----------- -Suppose you have a ``PasswordChange`` class, that's used in a form where +Suppose you have a ``ChangePassword`` class, that's used in a form where the user can change their password by entering their old password and a new password. This constraint will validate that the old password matches the user's current password: diff --git a/serializer.rst b/serializer.rst index 1fb8af676c6..f3c39bbe4ab 100644 --- a/serializer.rst +++ b/serializer.rst @@ -210,8 +210,8 @@ A service leveraging `APCu`_ (and APC for PHP < 5.5) is built-in. ), )); -Going Further with the Serializer Component -------------------------------------------- +Going Further with the Serializer +--------------------------------- `ApiPlatform`_ provides an API system supporting `JSON-LD`_ and `Hydra Core Vocabulary`_ hypermedia formats. It is built on top of the Symfony Framework and its Serializer @@ -221,6 +221,12 @@ and a caching system. If you want to leverage the full power of the Symfony Serializer component, take a look at how this bundle works. +.. toctree:: + :maxdepth: 1 + :glob: + + serializer/* + .. _`APCu`: https://github.com/krakjoe/apcu .. _`ApiPlatform`: https://github.com/api-platform/core .. _`JSON-LD`: http://json-ld.org diff --git a/serializer/custom_encoders.rst b/serializer/custom_encoders.rst new file mode 100644 index 00000000000..7c573ec2527 --- /dev/null +++ b/serializer/custom_encoders.rst @@ -0,0 +1,97 @@ +.. index:: + single: Serializer; Custom encoders + +How to Create your Custom Encoder +================================= + +The :doc:`Serializer Component ` uses Normalizers +to transform any data to an array. Then, by leveraging *Encoders*, that data can +be convereted into any data-structure (e.g. JSON). + +The Component provides several built-in encoders that are described +:doc:`in their own section ` but you may want +to use another structure that's not supported. + +Creating a new encoder +---------------------- + +Imagine you want to serialize and deserialize Yaml. For that you'll have to +create your own encoder that uses the +:doc:`Yaml Component `:: + + namespace AppBundle\Encoder; + + use Symfony\Component\Serializer\Encoder\DecoderInterface; + use Symfony\Component\Serializer\Encoder\EncoderInterface; + use Symfony\Component\Yaml\Yaml; + + class YamlEncoder implements EncoderInterface, DecoderInterface + { + public function encode($data, $format, array $context = array()) + { + return Yaml::dump($data); + } + + public function supportsEncoding($format) + { + return 'yaml' === $format; + } + + public function decode($data, $format, array $context = array()) + { + return Yaml::parse($data); + } + + public function supportsDecoding($format) + { + return 'yaml' === $format; + } + } + +Registering it in your app +-------------------------- + +If you use the Symfony Framework. then you probably want to register this encoder +as a service in your app. Then, you only need to tag it with ``serializer.encoder`` +to inject your custom encoder into the Serializer. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + services: + app.encoder.yaml: + class: AppBundle\Encoder\YamlEncoder + tags: + - { name: serializer.encoder } + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // app/config/services.php + $container + ->register( + 'app.encoder.yaml', + 'AppBundle\Encoder\YamlEncoder' + ) + ->addTag('serializer.encoder') + ; + +Now you'll be able to serialize and deserialize Yaml! + +.. _tracker: https://github.com/symfony/symfony/issues diff --git a/serializer/encoders.rst b/serializer/encoders.rst new file mode 100644 index 00000000000..9b268273d35 --- /dev/null +++ b/serializer/encoders.rst @@ -0,0 +1,63 @@ +.. index:: + single: Serializer, Encoders + +Encoders +======== + +Encoders basically turn **arrays** into **formats** and vice versa. +They implement +:class:`Symfony\\Component\\Serializer\\Encoder\\EncoderInterface` for +encoding (array to format) and +:class:`Symfony\\Component\\Serializer\\Encoder\\DecoderInterface` for +decoding (format to array). + +You can add new encoders to a Serializer instance by using its second constructor argument:: + + use Symfony\Component\Serializer\Serializer; + use Symfony\Component\Serializer\Encoder\XmlEncoder; + use Symfony\Component\Serializer\Encoder\JsonEncoder; + + $encoders = array(new XmlEncoder(), new JsonEncoder()); + $serializer = new Serializer(array(), $encoders); + +Built-in Encoders +----------------- + +Two encoders are used in the example above: + +* :class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder` to encode/decode XML +* :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder` to encode/decode JSON + +The ``XmlEncoder`` +~~~~~~~~~~~~~~~~~~ + +This encoder transforms arrays into XML and vice versa. + +For example, take an object normalized as following:: + + array('foo' => array(1, 2), 'bar' => true); + +The ``XmlEncoder`` will encode this object like that:: + + + + 1 + 2 + 1 + + +Be aware that this encoder will consider keys beginning with ``@`` as attributes:: + + $encoder = new XmlEncoder(); + $encoder->encode(array('foo' => array('@bar' => 'value'))); + // will return: + // + // + // + // + +The ``JsonEncoder`` +~~~~~~~~~~~~~~~~~~~ + +The ``JsonEncoder`` is much simpler and is based on the PHP +:phpfunction:`json_encode` and :phpfunction:`json_decode` functions. diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst index cdea401e3a4..941fb677388 100644 --- a/service_container/alias_private.rst +++ b/service_container/alias_private.rst @@ -30,9 +30,9 @@ to be *not* public (i.e. private): .. code-block:: yaml services: - foo: - class: Example\Foo - public: false + foo: + class: Example\Foo + public: false .. code-block:: xml @@ -87,11 +87,11 @@ services. .. code-block:: yaml services: - app.phpmailer: - class: AppBundle\Mail\PhpMailer + app.phpmailer: + class: AppBundle\Mail\PhpMailer - app.mailer: - alias: app.phpmailer + app.mailer: + alias: app.phpmailer .. code-block:: xml diff --git a/service_container/tags.rst b/service_container/tags.rst index 93e2d8214c8..6ab22faf53a 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -195,7 +195,7 @@ Create a Compiler Pass ~~~~~~~~~~~~~~~~~~~~~~ You can now use a :ref:`compiler pass ` to ask the -container for any services with the ``acme_mailer.transport`` tag:: +container for any services with the ``app.mail_transport`` tag:: // src/AppBundle/DependencyInjection/Compiler/MailTransportPass.php namespace AppBundle\DependencyInjection\Compiler; diff --git a/testing/database.rst b/testing/database.rst index d353bcfb8bb..42c5fd36e4b 100644 --- a/testing/database.rst +++ b/testing/database.rst @@ -73,7 +73,7 @@ it's easy to pass a mock object within a test:: public function testCalculateTotalSalary() { // First, mock the object to be used in the test - $employee = $this->getMock(Employee::class); + $employee = $this->createMock(Employee::class); $employee->expects($this->once()) ->method('getSalary') ->will($this->returnValue(1000));