1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: 19: 20: 21: 22: 23:
24: class cApiModuleCollection extends ItemCollection {
25:
26: 27: 28:
29: public function __construct() {
30: global $cfg;
31: parent::__construct($cfg['tab']['mod'], 'idmod');
32: $this->_setItemClass('cApiModule');
33: }
34:
35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
58: public function create($name, $idclient = NULL, $alias = '', $type = '', $error = 'none', $description = '', $deletable = 0, $template = '', $static = 0, $package_guid = '', $package_data = '', $author = '', $created = '', $lastmodified = '') {
59: global $client, $auth;
60:
61: if (NULL === $idclient) {
62: $idclient = $client;
63: }
64:
65: if (empty($author)) {
66: $author = $auth->auth['uname'];
67: }
68: if (empty($created)) {
69: $created = date('Y-m-d H:i:s');
70: }
71: if (empty($lastmodified)) {
72: $lastmodified = date('Y-m-d H:i:s');
73: }
74:
75: $item = parent::createNewItem();
76:
77: $item->set('idclient', $idclient);
78: $item->set('name', $name);
79: $item->set('alias', $alias);
80: $item->set('type', $type);
81: $item->set('error', $error);
82: $item->set('description', $description);
83: $item->set('deletable', $deletable);
84: $item->set('template', $template);
85: $item->set('static', $static);
86: $item->set('package_guid', $package_guid);
87: $item->set('package_data', $package_data);
88: $item->set('author', $author);
89: $item->set('created', $created);
90: $item->set('lastmodified', $lastmodified);
91: $item->store();
92:
93: return $item;
94: }
95:
96: 97: 98: 99: 100: 101: 102:
103: public function getAllTypesByIdclient($idclient) {
104: $types = array();
105:
106: $sql = "SELECT type FROM `%s` WHERE idclient = %d GROUP BY type";
107: $sql = $this->db->prepare($sql, $this->table, $idclient);
108: $this->db->query($sql);
109: while ($this->db->nextRecord()) {
110: $types[] = $this->db->f('type');
111: }
112:
113: return $types;
114: }
115:
116: 117: 118: 119: 120:
121: public function getModulesInUse() {
122: global $cfg;
123:
124: $db = cRegistry::getDb();
125:
126: $sql = 'SELECT
127: c.idmod, c.idtpl, t.name
128: FROM
129: ' . $cfg['tab']['container'] . ' as c,
130: ' . $cfg['tab']['tpl'] . " as t
131: WHERE
132: t.idtpl = c.idtpl
133: GROUP BY c.idmod
134: ORDER BY t.name";
135: $db->query($sql);
136:
137: $aUsedTemplates = array();
138: if ($db->numRows() != 0) {
139: while ($db->nextRecord()) {
140: $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_name'] = $db->f('name');
141: $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_id'] = (int) $db->f('idtpl');
142: }
143: }
144:
145: return $aUsedTemplates;
146: }
147: }
148:
149: 150: 151: 152: 153: 154:
155: class cApiModule extends Item {
156:
157: 158: 159: 160: 161:
162: private $_translationPatternText = '/mi18n([\s]*)\("((\\\\"|[^"])*)"(([\s]*),([\s]*)[^\),]+)*\)/';
163:
164: 165: 166: 167: 168:
169: private $_translationPatternBase = '/mi18n([\s]*)\(([\s]*)"/';
170:
171: 172: 173: 174: 175:
176: private $_translationReplacement = 'mi18n("';
177:
178: 179: 180: 181:
182: protected $_error;
183:
184: 185: 186: 187: 188:
189: protected $_packageStructure;
190:
191: 192: 193: 194:
195: private $aUsedTemplates = array();
196:
197: 198: 199: 200: 201:
202: public function __construct($mId = false) {
203: global $cfg, $cfgClient, $client;
204: parent::__construct($cfg['tab']['mod'], 'idmod');
205:
206:
207:
208:
209:
210: $this->setFilters(array(), array());
211:
212: if ($mId !== false) {
213: $this->loadByPrimaryKey($mId);
214: }
215:
216: if (isset($client) && $client != 0) {
217: $this->_packageStructure = array(
218: 'jsfiles' => $cfgClient[$client]['js']['path'],
219: 'tplfiles' => $cfgClient[$client]['tpl']['path'],
220: 'cssfiles' => $cfgClient[$client]['css']['path']
221: );
222: }
223: }
224:
225: 226: 227: 228: 229:
230: public function getTranslatedName() {
231: global $lang;
232:
233:
234: if (!$this->isLoaded()) {
235: return false;
236: }
237:
238: $modname = $this->getProperty('translated-name', $lang);
239:
240: if ($modname === false) {
241: return $this->get('name');
242: } else {
243: return $modname;
244: }
245: }
246:
247: 248: 249: 250: 251:
252: public function setTranslatedName($name) {
253: global $lang;
254: $this->setProperty('translated-name', $lang, $name);
255: }
256:
257: 258: 259: 260: 261: 262: 263: 264: 265:
266: function parseModuleForStringsLoadFromFile($cfg, $client, $lang) {
267: global $client;
268:
269:
270: if (!$this->isLoaded()) {
271: return false;
272: }
273:
274:
275: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
276: $code = $contenidoModuleHandler->readOutput() . ' ';
277: $code .= $contenidoModuleHandler->readInput();
278:
279:
280: $strings = array();
281:
282:
283: $varr = preg_split($this->_translationPatternBase, $code, -1);
284: array_shift($varr);
285:
286: if (count($varr) > 0) {
287: foreach ($varr as $key => $value) {
288:
289: $closing = strpos($value, '")');
290:
291: if ($closing === false) {
292: $closing = strpos($value, '" )');
293: }
294:
295: if ($closing !== false) {
296: $value = substr($value, 0, $closing) . '")';
297: }
298:
299:
300: $varr[$key] = $this->_translationReplacement . $value;
301:
302:
303: preg_match_all($this->_translationPatternText, $varr[$key], $results);
304:
305:
306: if (is_array($results[1]) && count($results[2]) > 0) {
307: $strings = array_merge($strings, $results[2]);
308: }
309:
310:
311: unset($results);
312: }
313: }
314:
315:
316:
317:
318:
319: if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
320:
321: foreach ($cfg['translatable_content_types'] as $sContentType) {
322:
323: if (file_exists($cfg['contenido']['path'] . 'classes/class.' . strtolower($sContentType) . '.php')) {
324: cInclude('classes', 'class.' . strtolower($sContentType) . '.php');
325:
326:
327:
328:
329: if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . strtoupper($sContentType) . '\[\d+\]/', $code)) {
330:
331: $strings = call_user_func(array(
332: $sContentType,
333: 'addModuleTranslations'
334: ), $strings);
335: }
336: }
337: }
338: }
339:
340:
341: return array_unique($strings);
342: }
343:
344: 345: 346: 347: 348:
349: public function parseModuleForStrings() {
350: if (!$this->isLoaded()) {
351: return false;
352: }
353:
354:
355:
356:
357:
358: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
359: $code = $contenidoModuleHandler->readOutput() . ' ';
360: $code .= $contenidoModuleHandler->readInput();
361:
362:
363: $strings = array();
364:
365:
366: $varr = preg_split($this->_translationPatternBase, $code, -1);
367:
368: if (count($varr) > 1) {
369: foreach ($varr as $key => $value) {
370:
371: $closing = strpos($value, '")');
372:
373: if ($closing === false) {
374: $closing = strpos($value, '" )');
375: }
376:
377: if ($closing !== false) {
378: $value = substr($value, 0, $closing) . '")';
379: }
380:
381:
382: $varr[$key] = $this->_translationReplacement . $value;
383:
384:
385: preg_match_all($this->_translationPatternText, $varr[$key], $results);
386:
387:
388: if (is_array($results[1]) && count($results[2]) > 0) {
389: $strings = array_merge($strings, $results[2]);
390: }
391:
392:
393: unset($results);
394: }
395: }
396:
397: global $cfg;
398:
399:
400:
401:
402:
403: if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
404:
405: foreach ($cfg['translatable_content_types'] as $sContentType) {
406:
407: if (cFileHandler::exists($cfg['contenido']['path'] . 'classes/class.' . strtolower($sContentType) . '.php')) {
408: cInclude('classes', 'class.' . strtolower($sContentType) . '.php');
409:
410:
411:
412:
413: if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . strtoupper($sContentType) . '\[\d+\]/', $code)) {
414:
415: $strings = call_user_func(array(
416: $sContentType,
417: 'addModuleTranslations'
418: ), $strings);
419: }
420: }
421: }
422: }
423:
424:
425: return array_unique($strings);
426: }
427:
428: 429: 430: 431: 432: 433: 434:
435: public function moduleInUse($module, $bSetData = false) {
436: global $cfg;
437:
438: $db = cRegistry::getDb();
439:
440: $sql = 'SELECT
441: c.idmod, c.idtpl, t.name
442: FROM
443: ' . $cfg['tab']['container'] . ' as c,
444: ' . $cfg['tab']['tpl'] . " as t
445: WHERE
446: c.idmod = '" . cSecurity::toInteger($module) . "' AND
447: t.idtpl=c.idtpl
448: GROUP BY c.idtpl
449: ORDER BY t.name";
450: $db->query($sql);
451:
452: if ($db->numRows() == 0) {
453: return false;
454: } else {
455: $i = 0;
456:
457: if ($bSetData === true) {
458: while ($db->nextRecord()) {
459: $this->aUsedTemplates[$i]['tpl_name'] = $db->f('name');
460: $this->aUsedTemplates[$i]['tpl_id'] = (int) $db->f('idmod');
461: $i++;
462: }
463: }
464:
465: return true;
466: }
467: }
468:
469: 470: 471: 472: 473:
474: public function getUsedTemplates() {
475: return $this->aUsedTemplates;
476: }
477:
478: 479: 480: 481: 482:
483: public function isOldModule() {
484:
485: $scanKeywords = array(
486: '$cfgTab',
487: 'idside',
488: 'idsidelang'
489: );
490:
491: $input = $this->get('input');
492: $output = $this->get('output');
493:
494: foreach ($scanKeywords as $keyword) {
495: if (strstr($input, $keyword)) {
496: return true;
497: }
498: if (strstr($output, $keyword)) {
499: return true;
500: }
501: }
502: }
503:
504: 505: 506: 507:
508: public function getField($field) {
509: $value = parent::getField($field);
510:
511: switch ($field) {
512: case 'name':
513: if ($value == '') {
514: $value = i18n('- Unnamed module -');
515: }
516: }
517:
518: return ($value);
519: }
520:
521: 522: 523: 524: 525:
526: public function store($bJustStore = false) {
527: if ($bJustStore) {
528:
529: $success = parent::store();
530: } else {
531: cInclude('includes', 'functions.con.php');
532:
533: $success = parent::store();
534:
535: conGenerateCodeForAllArtsUsingMod($this->get('idmod'));
536: }
537:
538: return $success;
539: }
540:
541: 542: 543: 544: 545: 546: 547:
548: private function _parseImportFile($sFile) {
549: $oXmlReader = new cXmlReader();
550: $oXmlReader->load($sFile);
551:
552: $aData = array();
553: $aInformation = array(
554: 'name',
555: 'description',
556: 'type',
557: 'input',
558: 'output',
559: 'alias'
560: );
561:
562: foreach ($aInformation as $sInfoName) {
563: $sPath = '/module/' . $sInfoName;
564:
565: $value = $oXmlReader->getXpathValue($sPath);
566: $aData[$sInfoName] = $value;
567: }
568:
569: return $aData;
570: }
571:
572: 573: 574: 575: 576: 577:
578: private function _getModuleProperties($sFile) {
579: $ret = array();
580:
581: $aModuleData = $this->_parseImportFile($sFile);
582: if (count($aModuleData) > 0) {
583: foreach ($aModuleData as $key => $value) {
584:
585: if ($key != 'output' && $key != 'input') {
586: $ret[$key] = addslashes($value);
587: }
588: }
589: }
590:
591: return $ret;
592: }
593:
594: 595: 596: 597: 598: 599: 600: 601: 602:
603: function import($sFile, $tempName, $show_notification = true) {
604: global $cfgClient, $db, $client, $cfg, $encoding, $lang;
605: $zip = new ZipArchive();
606: $notification = new cGuiNotification();
607:
608:
609:
610: $modulName = substr($sFile, 0, -4);
611:
612: $sModulePath = $cfgClient[$client]['module']['path'] . $modulName;
613: $sTempPath = $cfg['path']['temp'] . 'module_import_' . $modulName;
614:
615:
616: if (is_dir($sModulePath)) {
617: if ($show_notification == true) {
618: $notification->displayNotification('error', i18n('Module exist!'));
619: }
620:
621: return false;
622: }
623:
624: if ($zip->open($tempName)) {
625: if ($zip->extractTo($sTempPath)) {
626: $zip->close();
627:
628:
629: if (cFileHandler::exists($sTempPath . '/info.xml')) {
630:
631:
632: $modules = new cApiModuleCollection();
633:
634: $module = $modules->create($modulName);
635: $moduleProperties = $this->_getModuleProperties($sTempPath . '/info.xml');
636:
637:
638: foreach ($moduleProperties as $key => $value) {
639: $module->set($key, $value);
640: }
641:
642: $module->store();
643: } else {
644: if ($show_notification == true) {
645: $notification->displayNotification('error', i18n('Import failed, could load module information!'));
646: }
647: return false;
648: }
649: } else {
650: if ($show_notification == true) {
651: $notification->displayNotification('error', i18n('Import failed, could not extract zip file!'));
652: }
653:
654: return false;
655: }
656: } else {
657: if ($show_notification == true) {
658: $notification->displayNotification('error', i18n('Could not open the zip file!'));
659: }
660:
661: return false;
662: }
663:
664:
665: cDirHandler::rename($sTempPath, $sModulePath);
666:
667: return true;
668: }
669:
670: 671: 672: 673: 674: 675:
676: function importModuleFromXML($sFile) {
677: global $db, $cfgClient, $client, $cfg, $encoding, $lang;
678:
679: $inputOutput = array();
680: $notification = new cGuiNotification();
681:
682: $aModuleData = $this->_parseImportFile($sFile);
683: if (count($aModuleData) > 0) {
684: foreach ($aModuleData as $key => $value) {
685: if ($this->get($key) != $value) {
686:
687: if ($key == 'output' || $key == 'input') {
688: $inputOutput[$key] = $value;
689: } else {
690: $this->set($key, addslashes($value));
691: }
692: }
693: }
694:
695: $moduleName = cApiStrCleanURLCharacters($this->get('name'));
696: $moduleAlias = cApiStrCleanURLCharacters($this->get('alias'));
697:
698:
699: if ($this->get('alias') == '') {
700: $this->set('alias', $moduleName);
701: }
702:
703: if (is_dir($cfgClient[$client]['module']['path'] . $moduleAlias)) {
704: $notification->displayNotification('error', i18n('Module exist!'));
705: return false;
706: } else {
707:
708: $this->store();
709: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
710: if (!$contenidoModuleHandler->createModule($inputOutput['input'], $inputOutput['output'])) {
711: $notification->displayNotification('error', i18n('Could not make a module!'));
712: return false;
713: } else {
714:
715: $contenidoModuleHandler->saveInfoXML();
716: }
717: }
718: } else {
719: $notification->displayNotification('error', i18n('Could not parse xml file!'));
720:
721: return false;
722: }
723:
724: return true;
725: }
726:
727: 728: 729: 730: 731: 732: 733:
734: private function _addFolderToZip($dir, $zipArchive, $zipdir = '') {
735: if (is_dir($dir)) {
736: if ($dh = opendir($dir)) {
737:
738: if (!empty($zipdir)) {
739: $zipArchive->addEmptyDir($zipdir);
740: }
741:
742:
743: while (($file = readdir($dh)) !== false) {
744:
745: if (!is_file($dir . $file)) {
746:
747: if (($file !== '.') && ($file !== '..')) {
748: $this->_addFolderToZip($dir . $file . '/', $zipArchive, $zipdir . $file . '/');
749: }
750: } else {
751:
752: if ($zipArchive->addFile($dir . $file, $zipdir . $file) === false) {
753: $notification = new cGuiNotification();
754: $notification->displayNotification('error', sprintf(i18n('Could not add file %s to zip!'), $file));
755: }
756: }
757: }
758: }
759: }
760: }
761:
762: 763: 764:
765: public function export() {
766: $notification = new cGuiNotification();
767: $moduleHandler = new cModuleHandler($this->get('idmod'));
768:
769:
770: if ($moduleHandler->modulePathExists()) {
771: $zip = new ZipArchive();
772: $zipName = $this->get('alias') . '.zip';
773: if ($zip->open($zipName, ZipArchive::CREATE)) {
774: $this->_addFolderToZip($moduleHandler->getModulePath(), $zip);
775:
776: $zip->close();
777:
778: header('Content-Type: application/zip');
779: header('Content-Length: ' . filesize($zipName));
780: header("Content-Disposition: attachment; filename=\"$zipName\"");
781: readfile($zipName);
782:
783:
784: unlink($zipName);
785: } else {
786: $notification->displayNotification('error', i18n('Could not open the zip file!'));
787: }
788: } else {
789: $notification->displayNotification('error', i18n("Module don't exist on file system!"));
790: }
791: }
792:
793: 794: 795: 796: 797: 798: 799: 800:
801: public function setField($name, $value, $bSafe = true) {
802: switch ($name) {
803: case 'deletable':
804: case 'static':
805: $value = ($value == 1) ? 1 : 0;
806: break;
807: case 'idclient':
808: $value = (int) $value;
809: break;
810: }
811:
812: parent::setField($name, $value, $bSafe);
813: }
814: }
815:
816: ?>