1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
18: class ElggPluginManifest {
19:
20: 21: 22:
23: protected $parser;
24:
25: 26: 27: 28:
29: protected $namespace_root = 'http://www.elgg.org/plugin_manifest/';
30:
31: 32: 33:
34: private $depsStructPlugin = array(
35: 'type' => '',
36: 'name' => '',
37: 'version' => '',
38: 'comparison' => 'ge'
39: );
40:
41: 42: 43:
44: private $depsStructPriority = array(
45: 'type' => '',
46: 'priority' => '',
47: 'plugin' => ''
48: );
49:
50: 51: 52:
53: private $depsStructElgg = array(
54: 'type' => '',
55: 'version' => '',
56: 'comparison' => 'ge'
57: );
58:
59: 60: 61:
62: private $depsStructPhpIni = array(
63: 'type' => '',
64: 'name' => '',
65: 'value' => '',
66: 'comparison' => '='
67: );
68:
69: 70: 71:
72: private $depsStructPhpExtension = array(
73: 'type' => '',
74: 'name' => '',
75: 'version' => '',
76: 'comparison' => '='
77: );
78:
79: 80: 81:
82: private $depsConflictsStruct = array(
83: 'type' => '',
84: 'name' => '',
85: 'version' => '',
86: 'comparison' => '='
87: );
88:
89: 90: 91:
92: private $depsProvidesStruct = array(
93: 'type' => '',
94: 'name' => '',
95: 'version' => ''
96: );
97:
98: 99: 100:
101: private $screenshotStruct = array(
102: 'description' => '',
103: 'path' => ''
104: );
105:
106: 107: 108: 109: 110:
111: protected $apiVersion;
112:
113: 114: 115: 116: 117:
118: protected $pluginID;
119:
120: 121: 122: 123: 124: 125: 126:
127: public function __construct($manifest, $plugin_id = null) {
128: if ($plugin_id) {
129: $this->pluginID = $plugin_id;
130: }
131:
132:
133: if ($manifest instanceof ElggXMLElement) {
134: $manifest_obj = $manifest;
135: } else {
136: if (substr(trim($manifest), 0, 1) == '<') {
137:
138: $raw_xml = $manifest;
139: } elseif (is_file($manifest)) {
140:
141: $raw_xml = file_get_contents($manifest);
142: }
143:
144: $manifest_obj = xml_to_object($raw_xml);
145: }
146:
147: if (!$manifest_obj) {
148: throw new PluginException(elgg_echo('PluginException:InvalidManifest',
149: array($this->getPluginID())));
150: }
151:
152:
153: if (isset($manifest_obj->attributes['xmlns'])) {
154: $namespace = $manifest_obj->attributes['xmlns'];
155: $version = str_replace($this->namespace_root, '', $namespace);
156: } else {
157: $version = 1.7;
158: }
159:
160: $this->apiVersion = $version;
161:
162: $parser_class_name = 'ElggPluginManifestParser' . str_replace('.', '', $this->apiVersion);
163:
164:
165: try {
166: $class_exists = class_exists($parser_class_name);
167: } catch (Exception $e) {
168: $class_exists = false;
169: }
170:
171: if ($class_exists) {
172: $this->parser = new $parser_class_name($manifest_obj, $this);
173: } else {
174: throw new PluginException(elgg_echo('PluginException:NoAvailableParser',
175: array($this->apiVersion, $this->getPluginID())));
176: }
177:
178: if (!$this->parser->parse()) {
179: throw new PluginException(elgg_echo('PluginException:ParserError',
180: array($this->apiVersion, $this->getPluginID())));
181: }
182:
183: return true;
184: }
185:
186: 187: 188: 189: 190:
191: public function getApiVersion() {
192: return $this->apiVersion;
193: }
194:
195: 196: 197: 198: 199:
200: public function getPluginID() {
201: if ($this->pluginID) {
202: return $this->pluginID;
203: } else {
204: return elgg_echo('unknown');
205: }
206: }
207:
208: 209: 210: 211: 212: 213: 214: 215:
216: public function getManifest() {
217: return $this->parser->getManifest();
218: }
219:
220: 221: 222:
223:
224: 225: 226: 227: 228:
229: public function getName() {
230: $name = $this->parser->getAttribute('name');
231:
232: if (!$name && $this->pluginID) {
233: $name = ucwords(str_replace('_', ' ', $this->pluginID));
234: }
235:
236: return $name;
237: }
238:
239:
240: 241: 242: 243: 244:
245: public function getDescription() {
246: return $this->parser->getAttribute('description');
247: }
248:
249: 250: 251: 252: 253:
254: public function getBlurb() {
255: $blurb = $this->parser->getAttribute('blurb');
256:
257: if (!$blurb) {
258: $blurb = elgg_get_excerpt($this->getDescription());
259: }
260:
261: return $blurb;
262: }
263:
264: 265: 266: 267: 268:
269: public function getLicense() {
270:
271: $en_us = $this->parser->getAttribute('license');
272: if ($en_us) {
273: return $en_us;
274: } else {
275: return $this->parser->getAttribute('licence');
276: }
277: }
278:
279: 280: 281: 282: 283:
284: public function getRepositoryURL() {
285: return $this->parser->getAttribute('repository');
286: }
287:
288: 289: 290: 291: 292:
293: public function getBugTrackerURL() {
294: return $this->parser->getAttribute('bugtracker');
295: }
296:
297: 298: 299: 300: 301:
302: public function getDonationsPageURL() {
303: return $this->parser->getAttribute('donations');
304: }
305:
306: 307: 308: 309: 310:
311: public function getVersion() {
312: return $this->parser->getAttribute('version');
313: }
314:
315: 316: 317: 318: 319:
320: public function getAuthor() {
321: return $this->parser->getAttribute('author');
322: }
323:
324: 325: 326: 327: 328:
329: public function getCopyright() {
330: return $this->parser->getAttribute('copyright');
331: }
332:
333: 334: 335: 336: 337:
338: public function getWebsite() {
339: return $this->parser->getAttribute('website');
340: }
341:
342: 343: 344: 345: 346:
347: public function getCategories() {
348: $bundled_plugins = array('blog', 'bookmarks', 'categories',
349: 'custom_index', 'dashboard', 'developers', 'diagnostics',
350: 'embed', 'externalpages', 'file', 'garbagecollector',
351: 'groups', 'htmlawed', 'invitefriends', 'likes',
352: 'logbrowser', 'logrotate', 'members', 'messageboard',
353: 'messages', 'notifications', 'oauth_api', 'pages', 'profile',
354: 'reportedcontent', 'search', 'tagcloud', 'thewire', 'tinymce',
355: 'twitter', 'twitter_api', 'uservalidationbyemail', 'zaudio',
356: );
357:
358: $cats = $this->parser->getAttribute('category');
359:
360: if (!$cats) {
361: $cats = array();
362: }
363:
364: if (in_array('bundled', $cats) && !in_array($this->getPluginID(), $bundled_plugins)) {
365: unset($cats[array_search('bundled', $cats)]);
366: }
367:
368: return $cats;
369: }
370:
371: 372: 373: 374: 375:
376: public function getScreenshots() {
377: $ss = $this->parser->getAttribute('screenshot');
378:
379: if (!$ss) {
380: $ss = array();
381: }
382:
383: $normalized = array();
384: foreach ($ss as $s) {
385: $normalized[] = $this->buildStruct($this->screenshotStruct, $s);
386: }
387:
388: return $normalized;
389: }
390:
391: 392: 393: 394: 395:
396: public function getProvides() {
397:
398: if ($this->getApiVersion() < 1.8) {
399: $provides = array();
400: } else {
401: $provides = $this->parser->getAttribute('provides');
402: }
403:
404: if (!$provides) {
405: $provides = array();
406: }
407:
408:
409: if ($this->pluginID) {
410: $provides[] = array(
411: 'type' => 'plugin',
412: 'name' => $this->getPluginID(),
413: 'version' => $this->getVersion()
414: );
415: }
416:
417: $normalized = array();
418: foreach ($provides as $provide) {
419: $normalized[] = $this->buildStruct($this->depsProvidesStruct, $provide);
420: }
421:
422: return $normalized;
423: }
424:
425: 426: 427: 428: 429:
430: public function getRequires() {
431:
432: if ($this->apiVersion < 1.8) {
433: $elgg_version = $this->parser->getAttribute('elgg_version');
434: if ($elgg_version) {
435: $reqs = array(
436: array(
437: 'type' => 'elgg_version',
438: 'version' => $elgg_version,
439: 'comparison' => 'ge'
440: )
441: );
442: } else {
443: $reqs = array();
444: }
445: } else {
446: $reqs = $this->parser->getAttribute('requires');
447: }
448:
449: if (!$reqs) {
450: $reqs = array();
451: }
452:
453: $normalized = array();
454: foreach ($reqs as $req) {
455: $normalized[] = $this->normalizeDep($req);
456: }
457:
458: return $normalized;
459: }
460:
461: 462: 463: 464: 465:
466: public function getSuggests() {
467: $suggests = $this->parser->getAttribute('suggests');
468:
469: if (!$suggests) {
470: $suggests = array();
471: }
472:
473: $normalized = array();
474: foreach ($suggests as $suggest) {
475: $normalized[] = $this->normalizeDep($suggest);
476: }
477:
478: return $normalized;
479: }
480:
481: 482: 483: 484: 485: 486: 487:
488: private function normalizeDep($dep) {
489: switch ($dep['type']) {
490: case 'elgg_version':
491: case 'elgg_release':
492: $struct = $this->depsStructElgg;
493: break;
494:
495: case 'plugin':
496: $struct = $this->depsStructPlugin;
497: break;
498:
499: case 'priority':
500: $struct = $this->depsStructPriority;
501: break;
502:
503: case 'php_extension':
504: $struct = $this->depsStructPhpExtension;
505: break;
506:
507: case 'php_ini':
508: $struct = $this->depsStructPhpIni;
509:
510:
511: if (isset($dep['value'])) {
512: switch (strtolower($dep['value'])) {
513: case 'yes':
514: case 'true':
515: case 'on':
516: case 1:
517: $dep['value'] = 1;
518: break;
519:
520: case 'no':
521: case 'false':
522: case 'off':
523: case 0:
524: case '':
525: $dep['value'] = 0;
526: break;
527: }
528: }
529: break;
530: default:
531:
532: return $dep;
533: }
534:
535: $normalized_dep = $this->buildStruct($struct, $dep);
536:
537:
538: if (isset($normalized_dep['comparison'])) {
539: switch ($normalized_dep['comparison']) {
540: case '<':
541: $normalized_dep['comparison'] = 'lt';
542: break;
543:
544: case '<=':
545: $normalized_dep['comparison'] = 'le';
546: break;
547:
548: case '>':
549: $normalized_dep['comparison'] = 'gt';
550: break;
551:
552: case '>=':
553: $normalized_dep['comparison'] = 'ge';
554: break;
555:
556: case '==':
557: case 'eq':
558: $normalized_dep['comparison'] = '=';
559: break;
560:
561: case '<>':
562: case 'ne':
563: $normalized_dep['comparison'] = '!=';
564: break;
565: }
566: }
567:
568: return $normalized_dep;
569: }
570:
571: 572: 573: 574: 575:
576: public function getConflicts() {
577:
578: if ($this->getApiVersion() < 1.8) {
579: $conflicts = array();
580: } else {
581: $conflicts = $this->parser->getAttribute('conflicts');
582: }
583:
584: if (!$conflicts) {
585: $conflicts = array();
586: }
587:
588: $normalized = array();
589:
590: foreach ($conflicts as $conflict) {
591: $normalized[] = $this->buildStruct($this->depsConflictsStruct, $conflict);
592: }
593:
594: return $normalized;
595: }
596:
597: 598: 599: 600: 601:
602: public function getActivateOnInstall() {
603: $activate = $this->parser->getAttribute('activate_on_install');
604: switch (strtolower($activate)) {
605: case 'yes':
606: case 'true':
607: case 'on':
608: case 1:
609: return true;
610:
611: case 'no':
612: case 'false':
613: case 'off':
614: case 0:
615: case '':
616: return false;
617: }
618: }
619:
620: 621: 622: 623: 624: 625: 626: 627:
628: protected function buildStruct(array $struct, array $array) {
629: $return = array();
630:
631: foreach ($struct as $index => $default) {
632: $return[$index] = elgg_extract($index, $array, $default);
633: }
634:
635: return $return;
636: }
637:
638: 639: 640: 641: 642: 643: 644: 645: 646:
647: static public function getFriendlyCategory($category) {
648: $cat_raw_string = "admin:plugins:category:$category";
649: $cat_display_string = elgg_echo($cat_raw_string);
650: if ($cat_display_string == $cat_raw_string) {
651: $category = str_replace(array('-', '_'), ' ', $category);
652: $cat_display_string = ucwords($category);
653: }
654: return $cat_display_string;
655: }
656: }
657: