Elgg  Version 3.0
ElggPluginManifest.php
Go to the documentation of this file.
1 <?php
2 
20 
26  protected $parser;
27 
32  protected $namespace_root = 'http://www.elgg.org/plugin_manifest/';
33 
37  private $depsStructPlugin = [
38  'type' => '',
39  'name' => '',
40  'version' => '',
41  'comparison' => 'ge'
42  ];
43 
47  private $depsStructPriority = [
48  'type' => '',
49  'priority' => '',
50  'plugin' => ''
51  ];
52 
53  /*
54  * The expected structure of elgg_release requires element
55  */
56  private $depsStructElgg = [
57  'type' => '',
58  'version' => '',
59  'comparison' => 'ge'
60  ];
61 
65  private $depsStructPhpVersion = [
66  'type' => '',
67  'version' => '',
68  'comparison' => 'ge'
69  ];
70 
74  private $depsStructPhpIni = [
75  'type' => '',
76  'name' => '',
77  'value' => '',
78  'comparison' => '='
79  ];
80 
84  private $depsStructPhpExtension = [
85  'type' => '',
86  'name' => '',
87  'version' => '',
88  'comparison' => '='
89  ];
90 
94  private $depsConflictsStruct = [
95  'type' => '',
96  'name' => '',
97  'version' => '',
98  'comparison' => '='
99  ];
100 
104  private $depsProvidesStruct = [
105  'type' => '',
106  'name' => '',
107  'version' => ''
108  ];
109 
113  private $screenshotStruct = [
114  'description' => '',
115  'path' => ''
116  ];
117 
121  private $contributorStruct = [
122  'name' => '',
123  'email' => '',
124  'website' => '',
125  'username' => '',
126  'description' => '',
127  ];
128 
134  protected $apiVersion;
135 
141  protected $pluginID;
142 
152  public function __construct($manifest, $plugin_id = null) {
153  if ($plugin_id) {
154  $this->pluginID = $plugin_id;
155  }
156 
157  // see if we need to construct the xml object.
158  if ($manifest instanceof \ElggXMLElement) {
159  $manifest_obj = $manifest;
160  } else {
161  $raw_xml = '';
162  if (substr(trim($manifest), 0, 1) == '<') {
163  // this is a string
164  $raw_xml = $manifest;
165  } elseif (is_file($manifest)) {
166  // this is a file
167  $raw_xml = file_get_contents($manifest);
168  }
169  if ($raw_xml) {
170  $manifest_obj = new \ElggXMLElement($raw_xml);
171  } else {
172  $manifest_obj = null;
173  }
174  }
175 
176  if (!$manifest_obj) {
177  $msg = elgg_echo('PluginException:InvalidManifest', [$this->getPluginID()]);
178  throw PluginException::factory('InvalidManifest', null, $msg);
179  }
180 
181  // set manifest api version
182  if (isset($manifest_obj->attributes['xmlns'])) {
183  $namespace = $manifest_obj->attributes['xmlns'];
184  $version = str_replace($this->namespace_root, '', $namespace);
185  } else {
186  $version = '1.7';
187  }
188 
189  $this->apiVersion = $version;
190 
191  $parser_class_name = '\ElggPluginManifestParser' . str_replace('.', '', $this->apiVersion);
192 
193  // @todo currently the autoloader freaks out if a class doesn't exist.
194  try {
195  $class_exists = class_exists($parser_class_name);
196  } catch (Exception $e) {
197  $class_exists = false;
198  }
199 
200  if ($class_exists) {
201  $this->parser = new $parser_class_name($manifest_obj, $this);
202  } else {
203  $msg = elgg_echo('PluginException:NoAvailableParser', [$this->apiVersion, $this->getPluginID()]);
204  throw PluginException::factory('NoAvailableParser', null, $msg);
205  }
206 
207  if (!$this->parser->parse()) {
208  $msg = elgg_echo('PluginException:ParserError', [$this->apiVersion, $this->getPluginID()]);
209  throw PluginException::factory('ParseError', null, $msg);
210  }
211  }
212 
218  public function getApiVersion() {
219  return $this->apiVersion;
220  }
221 
227  public function getPluginID() {
228  if ($this->pluginID) {
229  return $this->pluginID;
230  } else {
231  return elgg_echo('unknown');
232  }
233  }
234 
243  public function getManifest() {
244  return $this->parser->getManifest();
245  }
246 
247  /***************************************
248  * Parsed and Normalized Manifest Data *
249  ***************************************/
250 
256  public function getName() {
257  $name = $this->parser->getAttribute('name');
258 
259  if (!$name && $this->pluginID) {
260  $name = ucwords(str_replace('_', ' ', $this->pluginID));
261  }
262 
263  return $name;
264  }
265 
272  public function getID() {
273  return trim((string) $this->parser->getAttribute('id'));
274  }
275 
276 
282  public function getDescription() {
283  return (string) $this->parser->getAttribute('description');
284  }
285 
291  public function getBlurb() {
292  $blurb = $this->parser->getAttribute('blurb');
293 
294  if (!$blurb) {
295  $blurb = elgg_get_excerpt($this->getDescription());
296  }
297 
298  return $blurb;
299  }
300 
306  public function getLicense() {
307  // license vs licence. Use license.
308  $en_us = $this->parser->getAttribute('license');
309 
310  return (string) ($en_us ?: $this->parser->getAttribute('licence'));
311  }
312 
318  public function getRepositoryURL() {
319  return (string) $this->parser->getAttribute('repository');
320  }
321 
327  public function getBugTrackerURL() {
328  return (string) $this->parser->getAttribute('bugtracker');
329  }
330 
336  public function getDonationsPageURL() {
337  return (string) $this->parser->getAttribute('donations');
338  }
339 
345  public function getVersion() {
346  return $this->parser->getAttribute('version');
347  }
348 
354  public function getAuthor() {
355  return (string) $this->parser->getAttribute('author');
356  }
357 
363  public function getCopyright() {
364  return (string) $this->parser->getAttribute('copyright');
365  }
366 
372  public function getWebsite() {
373  return (string) $this->parser->getAttribute('website');
374  }
375 
381  public function getCategories() {
382  $bundled_plugins = [
383  'activity',
384  'blog',
385  'bookmarks',
386  'ckeditor',
387  'custom_index',
388  'dashboard',
389  'developers',
390  'diagnostics',
391  'discussions',
392  'embed',
393  'externalpages',
394  'file',
395  'friends',
396  'friends_collections',
397  'garbagecollector',
398  'groups',
399  'invitefriends',
400  'likes',
401  'login_as',
402  'members',
403  'messageboard',
404  'messages',
405  'notifications',
406  'pages',
407  'profile',
408  'reportedcontent',
409  'search',
410  'site_notifications',
411  'system_log',
412  'tagcloud',
413  'thewire',
414  'uservalidationbyemail',
415  'web_services',
416  ];
417 
418  $cats = $this->parser->getAttribute('category');
419 
420  if (!$cats) {
421  $cats = [];
422  }
423 
424  if (in_array('bundled', $cats) && !in_array($this->getPluginID(), $bundled_plugins)) {
425  unset($cats[array_search('bundled', $cats)]);
426  }
427 
428  return $cats;
429  }
430 
436  public function getScreenshots() {
437  $ss = $this->parser->getAttribute('screenshot');
438 
439  if (!$ss) {
440  $ss = [];
441  }
442 
443  $normalized = [];
444  foreach ($ss as $s) {
445  $normalized[] = $this->buildStruct($this->screenshotStruct, $s);
446  }
447 
448  return $normalized;
449  }
450 
456  public function getContributors() {
457  $ss = $this->parser->getAttribute('contributor');
458 
459  if (!$ss) {
460  $ss = [];
461  }
462 
463  $normalized = [];
464  foreach ($ss as $s) {
465  $normalized[] = $this->buildStruct($this->contributorStruct, $s);
466  }
467 
468  return $normalized;
469  }
470 
476  public function getProvides() {
477  // normalize for 1.7
478  if ($this->getApiVersion() < 1.8) {
479  $provides = [];
480  } else {
481  $provides = $this->parser->getAttribute('provides');
482  }
483 
484  if (!$provides) {
485  $provides = [];
486  }
487 
488  // always provide ourself if we can
489  if ($this->pluginID) {
490  $provides[] = [
491  'type' => 'plugin',
492  'name' => $this->getPluginID(),
493  'version' => $this->getVersion()
494  ];
495  }
496 
497  $normalized = [];
498  foreach ($provides as $provide) {
499  $normalized[] = $this->buildStruct($this->depsProvidesStruct, $provide);
500  }
501 
502  return $normalized;
503  }
504 
510  public function getRequires() {
511  $reqs = $this->parser->getAttribute('requires');
512 
513  if (!$reqs) {
514  $reqs = [];
515  }
516 
517  $normalized = [];
518  foreach ($reqs as $req) {
519  $normalized[] = $this->normalizeDep($req);
520  }
521 
522  return $normalized;
523  }
524 
530  public function getSuggests() {
531  $suggests = $this->parser->getAttribute('suggests');
532 
533  if (!$suggests) {
534  $suggests = [];
535  }
536 
537  $normalized = [];
538  foreach ($suggests as $suggest) {
539  $normalized[] = $this->normalizeDep($suggest);
540  }
541 
542  return $normalized;
543  }
544 
552  private function normalizeDep($dep) {
553 
554  $struct = [];
555 
556  switch ($dep['type']) {
557  case 'elgg_release':
558  $struct = $this->depsStructElgg;
559  break;
560 
561  case 'plugin':
562  $struct = $this->depsStructPlugin;
563  break;
564 
565  case 'priority':
566  $struct = $this->depsStructPriority;
567  break;
568 
569  case 'php_version':
570  $struct = $this->depsStructPhpVersion;
571  break;
572 
573  case 'php_extension':
574  $struct = $this->depsStructPhpExtension;
575  break;
576 
577  case 'php_ini':
578  $struct = $this->depsStructPhpIni;
579 
580  // also normalize boolean values
581  if (isset($dep['value'])) {
582  switch (strtolower($dep['value'])) {
583  case 'yes':
584  case 'true':
585  case 'on':
586  case 1:
587  $dep['value'] = 1;
588  break;
589 
590  case 'no':
591  case 'false':
592  case 'off':
593  case 0:
594  case '':
595  $dep['value'] = 0;
596  break;
597  }
598  }
599  break;
600  default:
601  // unrecognized so we just return the raw dependency
602  return $dep;
603  }
604 
605  $normalized_dep = $this->buildStruct($struct, $dep);
606 
607  // normalize comparison operators
608  if (isset($normalized_dep['comparison'])) {
609  switch ($normalized_dep['comparison']) {
610  case '<':
611  $normalized_dep['comparison'] = 'lt';
612  break;
613 
614  case '<=':
615  $normalized_dep['comparison'] = 'le';
616  break;
617 
618  case '>':
619  $normalized_dep['comparison'] = 'gt';
620  break;
621 
622  case '>=':
623  $normalized_dep['comparison'] = 'ge';
624  break;
625 
626  case '==':
627  case 'eq':
628  $normalized_dep['comparison'] = '=';
629  break;
630 
631  case '<>':
632  case 'ne':
633  $normalized_dep['comparison'] = '!=';
634  break;
635  }
636  }
637 
638  return $normalized_dep;
639  }
640 
646  public function getConflicts() {
647  // normalize for 1.7
648  if ($this->getApiVersion() < 1.8) {
649  $conflicts = [];
650  } else {
651  $conflicts = $this->parser->getAttribute('conflicts');
652  }
653 
654  if (!$conflicts) {
655  $conflicts = [];
656  }
657 
658  $normalized = [];
659 
660  foreach ($conflicts as $conflict) {
661  $normalized[] = $this->buildStruct($this->depsConflictsStruct, $conflict);
662  }
663 
664  return $normalized;
665  }
666 
672  public function getActivateOnInstall() {
673  $activate = $this->parser->getAttribute('activate_on_install');
674  if ($activate === false) {
675  return false;
676  }
677 
678  // these are the truthy supported values, everything else will result in false
679  switch (strtolower($activate)) {
680  case 'yes':
681  case 'true':
682  case 'on':
683  case 1:
684  return true;
685  }
686 
687  return false;
688  }
689 
698  protected function buildStruct(array $struct, array $array) {
699  $return = [];
700 
701  foreach ($struct as $index => $default) {
702  $return[$index] = elgg_extract($index, $array, $default);
703  }
704 
705  return $return;
706  }
707 
717  public static function getFriendlyCategory($category) {
718  $cat_raw_string = "admin:plugins:category:$category";
719  if (_elgg_services()->translator->languageKeyExists($cat_raw_string)) {
720  return elgg_echo($cat_raw_string);
721  }
722 
723  $category = str_replace(['-', '_'], ' ', $category);
724  return ucwords($category);
725  }
726 }
getCopyright()
Return the copyright.
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
getLicense()
Returns the license.
getName()
Returns the plugin name.
getRepositoryURL()
Returns the repository url.
getApiVersion()
Returns the API version in use.
getScreenshots()
Return the screenshots listed.
elgg_echo($message_key, array $args=[], $language="")
Given a message key, returns an appropriately translated full-text string.
Definition: languages.php:21
getDescription()
Return the description.
getID()
Return the plugin ID required by the author.
getPluginID()
Returns the plugin ID.
getSuggests()
Returns the suggests elements.
getBlurb()
Return the short description.
getAuthor()
Returns the plugin author.
static factory($reason, ElggPlugin $plugin=null, $message=null, Throwable $previous=null)
Create a new plugin exception.
getManifest()
Returns the manifest array.
getContributors()
Return the contributors listed.
$namespace_root
The root for plugin manifest namespaces.
getVersion()
Returns the version of the plugin.
getActivateOnInstall()
Should this plugin be activated when Elgg is installed.
$plugin_id
Definition: save.php:15
getDonationsPageURL()
Returns the donations page.
getCategories()
Return the categories listed for this plugin.
static getFriendlyCategory($category)
Returns a category&#39;s friendly name.
if($item instanceof\ElggEntity) elseif($item instanceof\ElggRiverItem) elseif(is_callable([$item, 'getType']))
Definition: item.php:39
$default
Definition: checkbox.php:35
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1131
getBugTrackerURL()
Returns the bug tracker page.
getProvides()
Return the list of provides by this plugin.
elgg_get_excerpt($text, $num_chars=250)
Returns an excerpt.
Definition: output.php:74
buildStruct(array $struct, array $array)
Normalizes an array into the structure specified.
_elgg_services()
Get the global service provider.
Definition: elgglib.php:1292
$index
Definition: gallery.php:47
getRequires()
Returns the dependencies listed.
__construct($manifest, $plugin_id=null)
Load a manifest file, XmlElement or path to manifest.xml file.
getWebsite()
Return the website.
$version
Definition: version.php:14
getConflicts()
Returns the conflicts listed.