Details
-
Bug
-
Resolution: Done
-
Medium
-
None
-
None
-
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.