Uploaded image for project: 'eZ Publish / Platform'
  1. eZ Publish / Platform
  2. EZP-27098

Errors in "Creating a Tweet Field Type" tutorial

    XMLWordPrintable

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Medium Medium
    • None
    • None
    • Documentation
    • None

    Description

      There are few errors in the third tutorial in the documentation (https://doc.ez.no/display/DEVELOPER/Creating+a+Tweet+Field+Type).

      Tutorial 3, step 2:
      Aside from things already covered the developer needs to override the parent class constructor in the following way:

          public function __construct($arg = array())
          {
              if (!is_array($arg)) {
                  $arg = array('url' => $arg);
              }
      
              parent::__construct($arg);
          }
      

      Without this addition the "fromHash" method from class Type.php will work incorrectly.

      Tutorial 3, step 3, "Validation methods":
      There is missing information about adding the required schema field:

          protected $validatorConfigurationSchema = array(
              'TweetValueValidator' => array(
                  'authorList' => array(
                      'type' => 'array',
                      'default' => array()
                  )
              )
          );
      

      Also, function "validateValidatorConfiguration" shown in the tutorial is not working (it returns error independently of schema). It should look more like this (warning: this change would require also changing the text of the tutorial preceding the code):

          public function validateValidatorConfiguration($validatorConfiguration)
          {
              $validationErrors = array();
      
              foreach ($validatorConfiguration as $validatorIdentifier => $constraints) {
                  // Report unknown validators
                  if ($validatorIdentifier !== 'TweetValueValidator') {
                      $validationErrors[] = new ValidationError("Validator '$validatorIdentifier' is unknown");
                      continue;
                  }
      
                  // Validate arguments from TweetValueValidator
                  foreach ($constraints as $name => $value) {
                      switch ($name) {
                          case 'authorList':
                              if (!is_array($value)) {
                                  $validationErrors[] = new ValidationError("Invalid authorList argument");
                              }
                              foreach ($value as $authorName) {
                                  if (!preg_match('/^[a-z0-9_]{1,15}$/i', $authorName)) {
                                      $validationErrors[] = new ValidationError("Invalid twitter username");
                                  }
                              }
                              break;
                          default:
                              $validationErrors[] = new ValidationError("Validator parameter '$name' is unknown");
                      }
                  }
              }
      
              return $validationErrors;
          }
      

      "validate" function should then look like this:

          public function validate(FieldDefinition $fieldDefinition, SPIValue $fieldValue)
          {
              $errors = array();
      
              if ($this->isEmptyValue($fieldValue)) {
                  return $errors;
              }
      
              // Tweet Url validation
              if (!preg_match('#^https?://twitter.com/([^/]+)/status/[0-9]+$#', $fieldValue->url, $m)) {
                  $errors[] = new ValidationError(
                      "Invalid twitter status url %url%",
                      null,
                      array('%url%' => $fieldValue->url)
                  );
                  return $errors;
              }
      
              $author = $m[1];
              $validatorConfiguration = $fieldDefinition->getValidatorConfiguration();
              if (!$this->authorApproved($author, $validatorConfiguration)) {
                  $errors[] = new ValidationError(
                      "Twitter user %user% is not in the approved author list",
                      null,
                      array('%user%' => $m[1])
                  );
              }
      
              return $errors;
          }
      
          private function authorApproved($author, $validatorConfiguration)
          {
              return !isset($validatorConfiguration['TweetValueValidator'])
                  || empty($validatorConfiguration['TweetValueValidator']['authorList'])
                  || in_array($author, $validatorConfiguration['TweetValueValidator']['authorList']);
          }
      

      Tutorial 3, step 3, "Fetching data from the Twitter API":
      "getEmbed" function from the "TwitterClient.php" file should verify the existence of the correct variable. Otherwise, it throws a Notice:

          public function getEmbed($statusUrl)
          {
              $parts = explode('/', $statusUrl);
      
              if (isset($parts[5])) {
                  $response = file_get_contents(
                      sprintf(
                          'https://api.twitter.com/1/statuses/oembed.json?id=%s&align=center',
                          $parts[5]
                      )
                  );
      
      
                  $data = json_decode($response, true);
                  return $data['html'];
              }
      
              return '';
          }
      

      Tutorial 3, step 4:
      In the service definition there is an argument missing:

              arguments: ['@ezsystems.tweetbundle.twitter.client']
      

      The whole definition should then look like this:

      services:
          ezsystems.tweetbundle.fieldtype.eztweet:
              parent: ezpublish.fieldType
              class: 'EzSystems\TweetFieldTypeBundle\eZ\Publish\FieldType\Tweet\Type'
              tags:
                  - {name: ezpublish.fieldType, alias: eztweet}
              arguments: ['@ezsystems.tweetbundle.twitter.client']
      

      Tutorial 3, step 5:
      Methods toStorageValue and toFieldValue should look like this:

          public function toStorageValue(FieldValue $value, StorageFieldValue $storageFieldValue)
          {
              $storageFieldValue->dataText = json_encode($value->data);
              $storageFieldValue->sortKeyString = $value->sortKey;
          }
      
          public function toFieldValue(StorageFieldValue $value, FieldValue $fieldValue)
          {
              $fieldValue->data = json_decode($value->dataText, true);
              $fieldValue->sortKey = $value->sortKeyString;
          }
      

      Without this change you can't save Content of the Content Type that contains our custom Field Type.

      Tutorial 3, step 6:
      Aside from things already covered the developer also needs to create a template with "eztweet_settings" block. For example, he can create a file Resources\views\platformui\content_type\view\eztweet.html.twig with this conent:

      {% block eztweet_settings %}
      {% endblock %}
      

      Next, he can add it to configuration, which means adding following lines to Resources\config\ezpublish_field_templates.yml :

              fielddefinition_settings_templates:
                  - {template: "EzSystemsTweetFieldTypeBundle:platformui/content_type/view:eztweet.html.twig", priority: 0}
      

      Without this addition you can't save new Content Type, that contains our custom field.

      Attachments

        Activity

          People

            Unassigned Unassigned
            jacek.foremski-obsolete@ez.no Jacek Foremski (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: