1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
16:
17: 18: 19: 20: 21: 22:
23: class cApiModuleCollection extends ItemCollection {
24: 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: 59:
60: public function create($name, $idclient = NULL, $alias = '', $type = '',
61: $error = 'none', $description = '', $deletable = 0, $template = '',
62: $static = 0, $package_guid = '', $package_data = '', $author = '',
63: $created = '', $lastmodified = '') {
64: global $client, $auth;
65:
66: if (NULL === $idclient) {
67: $idclient = $client;
68: }
69:
70: if (empty($author)) {
71: $author = $auth->auth['uname'];
72: }
73: if (empty($created)) {
74: $created = date('Y-m-d H:i:s');
75: }
76: if (empty($lastmodified)) {
77: $lastmodified = date('Y-m-d H:i:s');
78: }
79:
80:
81: $item = $this->createNewItem();
82:
83: $item->set('idclient', $idclient);
84: $item->set('name', $name);
85: $item->set('alias', $alias);
86: $item->set('type', $type);
87: $item->set('error', $error);
88: $item->set('description', $description);
89: $item->set('deletable', $deletable);
90: $item->set('template', $template);
91: $item->set('static', $static);
92: $item->set('package_guid', $package_guid);
93: $item->set('package_data', $package_data);
94: $item->set('author', $author);
95: $item->set('created', $created);
96: $item->set('lastmodified', $lastmodified);
97: $item->store();
98:
99: return $item;
100: }
101:
102: 103: 104: 105: 106: 107: 108: 109:
110: public function getAllTypesByIdclient($idclient) {
111: $types = array();
112:
113: $sql = "SELECT type FROM `%s` WHERE idclient = %d GROUP BY type";
114: $sql = $this->db->prepare($sql, $this->table, $idclient);
115: $this->db->query($sql);
116: while ($this->db->nextRecord()) {
117: $types[] = $this->db->f('type');
118: }
119:
120: return $types;
121: }
122:
123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133:
134: public function getAllByIdclient($idclient, $oderBy = 'name') {
135: $records = array();
136:
137: if (!empty($oderBy)) {
138: $oderBy = ' ORDER BY ' . $this->db->escape($oderBy);
139: }
140: $sql = "SELECT * FROM `%s` WHERE idclient = %d{$oderBy}";
141: $sql = $this->db->prepare($sql, $this->table, $idclient);
142: $this->db->query($sql);
143: while ($this->db->nextRecord()) {
144: $records[$this->db->f('idmod')] = $this->db->toArray();
145: }
146:
147: return $records;
148: }
149:
150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161:
162: public function getAllByIdclientAndType($idclient, $type, $oderBy = 'name') {
163: $records = array();
164:
165: if (!empty($oderBy)) {
166: $oderBy = ' ORDER BY ' . $this->db->escape($oderBy);
167: }
168: $sql = "SELECT * FROM `%s` WHERE idclient = %d AND type LIKE '%s' {$oderBy}";
169: $sql = $this->db->prepare($sql, $this->table, $idclient, '%' . $type . '%');
170:
171: $this->db->query($sql);
172: while ($this->db->nextRecord()) {
173: $records[$this->db->f('idmod')] = $this->db->toArray();
174: }
175:
176: return $records;
177: }
178:
179: 180: 181: 182: 183: 184: 185:
186: public function getModulesInUse() {
187: global $cfg;
188:
189: $db = cRegistry::getDb();
190:
191: $sql = 'SELECT
192: c.idmod, c.idtpl, t.name
193: FROM
194: ' . $cfg['tab']['container'] . ' as c,
195: ' . $cfg['tab']['tpl'] . " as t
196: WHERE
197: t.idtpl = c.idtpl
198: GROUP BY c.idmod, c.idtpl, t.name
199: ORDER BY t.name";
200: $db->query($sql);
201:
202: $aUsedTemplates = array();
203: if ($db->numRows() != 0) {
204: while ($db->nextRecord()) {
205: $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_name'] = $db->f('name');
206: $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_id'] = (int) $db->f('idtpl');
207: }
208: }
209:
210: return $aUsedTemplates;
211: }
212: }
213:
214: 215: 216: 217: 218: 219:
220: class cApiModule extends Item {
221:
222: 223: 224: 225: 226:
227: private $_translationPatternText = '/mi18n([\s]*)\("((\\\\"|[^"])*)"(([\s]*),([\s]*)[^\),]+)*\)/';
228:
229: 230: 231: 232: 233:
234: private $_translationPatternBase = '/mi18n([\s]*)\(([\s]*)"/';
235:
236: 237: 238: 239: 240:
241: private $_translationReplacement = 'mi18n("';
242:
243: 244: 245: 246: 247:
248: private $_translationPatternTemplate = '/\{\s*"([^"]+)"\s*\|\s*mi18n\s*\}/';
249:
250: 251: 252: 253:
254: protected $_error;
255:
256: 257: 258: 259: 260:
261: protected $_packageStructure;
262:
263: 264: 265: 266:
267: private $aUsedTemplates = array();
268:
269: 270: 271: 272: 273: 274: 275: 276:
277: public function __construct($mId = false) {
278: global $cfg, $cfgClient, $client;
279: parent::__construct($cfg['tab']['mod'], 'idmod');
280:
281:
282:
283:
284:
285: $this->setFilters(array(), array());
286:
287: if ($mId !== false) {
288: $this->loadByPrimaryKey($mId);
289: }
290:
291: if (isset($client) && $client != 0) {
292: $this->_packageStructure = array(
293: 'jsfiles' => $cfgClient[$client]['js']['path'],
294: 'tplfiles' => $cfgClient[$client]['tpl']['path'],
295: 'cssfiles' => $cfgClient[$client]['css']['path']
296: );
297: }
298: }
299:
300: 301: 302: 303: 304: 305: 306: 307:
308: public function getTranslatedName() {
309: global $lang;
310:
311:
312: if (!$this->isLoaded()) {
313: return false;
314: }
315:
316: $modname = $this->getProperty('translated-name', $lang);
317:
318: if ($modname === false) {
319: return $this->get('name');
320: } else {
321: return $modname;
322: }
323: }
324:
325: 326: 327: 328: 329: 330: 331: 332: 333: 334:
335: public function setTranslatedName($name) {
336: global $lang;
337: $this->setProperty('translated-name', $lang, $name);
338: }
339:
340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350:
351: function parseModuleForStringsLoadFromFile($cfg, $client, $lang) {
352: global $client;
353:
354:
355: if (!$this->isLoaded()) {
356: return false;
357: }
358:
359:
360: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
361: $code = $contenidoModuleHandler->readOutput() . ' ';
362: $code .= $contenidoModuleHandler->readInput();
363:
364:
365: $strings = array();
366:
367:
368: $varr = preg_split($this->_translationPatternBase, $code, -1);
369: array_shift($varr);
370:
371: if (count($varr) > 0) {
372: foreach ($varr as $key => $value) {
373:
374: $closing = cString::findFirstPos($value, '")');
375:
376: if ($closing === false) {
377: $closing = cString::findFirstPos($value, '" )');
378: }
379:
380: if ($closing !== false) {
381: $value = cString::getPartOfString($value, 0, $closing) . '")';
382: }
383:
384:
385: $varr[$key] = $this->_translationReplacement . $value;
386:
387:
388: preg_match_all($this->_translationPatternText, $varr[$key], $results);
389:
390:
391: if (is_array($results[1]) && count($results[2]) > 0) {
392: $strings = array_merge($strings, $results[2]);
393: }
394:
395:
396: unset($results);
397: }
398: }
399:
400:
401: $contenidoModulTemplateHandler = new cModuleTemplateHandler($this->get('idmod'), null);
402: $filesArray = $contenidoModulTemplateHandler->getAllFilesFromDirectory('template');
403:
404: if (is_array($filesArray)) {
405: $code = '';
406: foreach ($filesArray as $file) {
407: $code .= $contenidoModulTemplateHandler->getFilesContent('template', '', $file);
408: }
409:
410:
411: preg_match_all($this->_translationPatternTemplate, $code, $results);
412:
413: if (is_array($results) && is_array($results[1]) && count($results[1]) > 0) {
414: $strings = array_merge($strings, $results[1]);
415: }
416: }
417:
418:
419:
420:
421:
422: if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
423:
424: foreach ($cfg['translatable_content_types'] as $sContentType) {
425:
426: if (file_exists($cfg['path']['contenido'] . 'classes/class.' . cString::toLowerCase($sContentType) . '.php')) {
427: cInclude('classes', 'class.' . cString::toLowerCase($sContentType) . '.php');
428:
429:
430:
431:
432: if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . cString::toUpperCase($sContentType) . '\[\d+\]/', $code)) {
433:
434: $strings = call_user_func(array(
435: $sContentType,
436: 'addModuleTranslations'
437: ), $strings);
438: }
439: }
440: }
441: }
442:
443:
444: return array_unique($strings);
445: }
446:
447: 448: 449: 450: 451: 452: 453:
454: public function parseModuleForStrings() {
455: if (!$this->isLoaded()) {
456: return false;
457: }
458:
459:
460:
461:
462:
463: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
464: $code = $contenidoModuleHandler->readOutput() . ' ';
465: $code .= $contenidoModuleHandler->readInput();
466:
467:
468: $strings = array();
469:
470:
471: $varr = preg_split($this->_translationPatternBase, $code, -1);
472:
473: if (count($varr) > 1) {
474: foreach ($varr as $key => $value) {
475:
476: $closing = cString::findFirstPos($value, '")');
477:
478: if ($closing === false) {
479: $closing = cString::findFirstPos($value, '" )');
480: }
481:
482: if ($closing !== false) {
483: $value = cString::getPartOfString($value, 0, $closing) . '")';
484: }
485:
486:
487: $varr[$key] = $this->_translationReplacement . $value;
488:
489:
490: preg_match_all($this->_translationPatternText, $varr[$key], $results);
491:
492:
493: if (is_array($results[1]) && count($results[2]) > 0) {
494: $strings = array_merge($strings, $results[2]);
495: }
496:
497:
498: unset($results);
499: }
500: }
501:
502: global $cfg;
503:
504:
505:
506:
507:
508: if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
509:
510: foreach ($cfg['translatable_content_types'] as $sContentType) {
511:
512: if (cFileHandler::exists($cfg['path']['contenido'] . 'classes/class.' . cString::toLowerCase($sContentType) . '.php')) {
513: cInclude('classes', 'class.' . cString::toLowerCase($sContentType) . '.php');
514:
515:
516:
517:
518: if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . cString::toUpperCase($sContentType) . '\[\d+\]/', $code)) {
519:
520: $strings = call_user_func(array(
521: $sContentType,
522: 'addModuleTranslations'
523: ), $strings);
524: }
525: }
526: }
527: }
528:
529:
530: return array_unique($strings);
531: }
532:
533: 534: 535: 536: 537: 538: 539: 540: 541:
542: public function moduleInUse($module, $bSetData = false) {
543: global $cfg;
544:
545: $db = cRegistry::getDb();
546:
547: $sql = 'SELECT
548: c.idmod, c.idtpl, t.name
549: FROM
550: ' . $cfg['tab']['container'] . ' as c,
551: ' . $cfg['tab']['tpl'] . " as t
552: WHERE
553: c.idmod = '" . cSecurity::toInteger($module) . "' AND
554: t.idtpl=c.idtpl
555: GROUP BY c.idtpl, c.idmod, t.name
556: ORDER BY t.name";
557: $db->query($sql);
558:
559: if ($db->numRows() == 0) {
560: return false;
561: } else {
562: $i = 0;
563:
564: if ($bSetData === true) {
565: while ($db->nextRecord()) {
566: $this->aUsedTemplates[$i]['tpl_name'] = $db->f('name');
567: $this->aUsedTemplates[$i]['tpl_id'] = (int) $db->f('idmod');
568: $i++;
569: }
570: }
571:
572: return true;
573: }
574: }
575:
576: 577: 578: 579: 580: 581:
582: public function getUsedTemplates() {
583: return $this->aUsedTemplates;
584: }
585:
586: 587: 588: 589: 590: 591:
592: public function isOldModule() {
593:
594: $scanKeywords = array(
595: '$cfgTab',
596: 'idside',
597: 'idsidelang'
598: );
599:
600: $input = $this->get('input');
601: $output = $this->get('output');
602:
603: foreach ($scanKeywords as $keyword) {
604: if (strstr($input, $keyword)) {
605: return true;
606: }
607: if (strstr($output, $keyword)) {
608: return true;
609: }
610: }
611: }
612:
613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623:
624: public function getField($field, $bSafe = true) {
625: $value = parent::getField($field, $bSafe);
626:
627: switch ($field) {
628: case 'name':
629: if ($value == '') {
630: $value = i18n('- Unnamed module -');
631: }
632: }
633:
634: return $value;
635: }
636:
637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648:
649: public function store($bJustStore = false) {
650: if ($bJustStore) {
651:
652: $success = parent::store();
653: } else {
654: cInclude('includes', 'functions.con.php');
655:
656: $success = parent::store();
657:
658: conGenerateCodeForAllartsUsingMod($this->get('idmod'));
659: }
660:
661: return $success;
662: }
663:
664: 665: 666: 667: 668: 669: 670: 671: 672:
673: private function _parseImportFile($sFile) {
674: $oXmlReader = new cXmlReader();
675: $oXmlReader->load($sFile);
676:
677: $aData = array();
678: $aInformation = array(
679: 'name',
680: 'description',
681: 'type',
682: 'input',
683: 'output',
684: 'alias'
685: );
686:
687: foreach ($aInformation as $sInfoName) {
688: $sPath = '/module/' . $sInfoName;
689:
690: $value = $oXmlReader->getXpathValue($sPath);
691: $aData[$sInfoName] = $value;
692: }
693:
694: return $aData;
695: }
696:
697: 698: 699: 700: 701: 702: 703: 704:
705: private function _getModuleProperties($sFile) {
706: $ret = array();
707:
708: $aModuleData = $this->_parseImportFile($sFile);
709: if (count($aModuleData) > 0) {
710: foreach ($aModuleData as $key => $value) {
711:
712: if ($key != 'output' && $key != 'input') {
713: $ret[$key] = addslashes($value);
714: }
715: }
716: }
717:
718: return $ret;
719: }
720:
721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734:
735: function import($sFile, $tempName, $show_notification = true) {
736: global $cfgClient, $db, $client, $cfg, $encoding, $lang;
737: $zip = new ZipArchive();
738: $notification = new cGuiNotification();
739:
740:
741:
742: $modulName = cString::getPartOfString($sFile, 0, -4);
743:
744: $sModulePath = $cfgClient[$client]['module']['path'] . $modulName;
745: $sTempPath = $cfg['path']['contenido_temp'] . 'module_import_' . $modulName;
746:
747:
748: if (is_dir($sModulePath)) {
749: if ($show_notification == true) {
750: $notification->displayNotification('error', i18n('Module already exists!'));
751: }
752:
753: return false;
754: }
755:
756: if ($zip->open($tempName)) {
757: if ($zip->extractTo($sTempPath)) {
758: $zip->close();
759:
760:
761: if (cFileHandler::exists($sTempPath . '/info.xml')) {
762:
763:
764: $modules = new cApiModuleCollection();
765:
766: $module = $modules->create($modulName);
767: $moduleProperties = $this->_getModuleProperties($sTempPath . '/info.xml');
768:
769:
770: foreach ($moduleProperties as $key => $value) {
771: $module->set($key, $value);
772: }
773:
774: $module->store();
775: } else {
776: if ($show_notification == true) {
777: $notification->displayNotification('error', i18n('Import failed, could load module information!'));
778: }
779: return false;
780: }
781: } else {
782: if ($show_notification == true) {
783: $notification->displayNotification('error', i18n('Import failed, could not extract zip file!'));
784: }
785:
786: return false;
787: }
788: } else {
789: if ($show_notification == true) {
790: $notification->displayNotification('error', i18n('Could not open the zip file!'));
791: }
792:
793: return false;
794: }
795:
796:
797: cDirHandler::rename($sTempPath, $sModulePath);
798:
799: return true;
800: }
801:
802: 803: 804: 805: 806: 807: 808: 809: 810:
811: function importModuleFromXML($sFile) {
812: global $db, $cfgClient, $client, $cfg, $encoding, $lang;
813:
814: $inputOutput = array();
815: $notification = new cGuiNotification();
816:
817: $aModuleData = $this->_parseImportFile($sFile);
818: if (count($aModuleData) > 0) {
819: foreach ($aModuleData as $key => $value) {
820: if ($this->get($key) != $value) {
821:
822: if ($key == 'output' || $key == 'input') {
823: $inputOutput[$key] = $value;
824: } else {
825: $this->set($key, addslashes($value));
826: }
827: }
828: }
829:
830: $moduleName = cString::cleanURLCharacters($this->get('name'));
831: $moduleAlias = cString::cleanURLCharacters($this->get('alias'));
832:
833:
834: if ($this->get('alias') == '') {
835: $this->set('alias', $moduleName);
836: }
837:
838: if (is_dir($cfgClient[$client]['module']['path'] . $moduleAlias)) {
839: $notification->displayNotification('error', i18n('Module exist!'));
840: return false;
841: } else {
842:
843: $this->store();
844: $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
845: if (!$contenidoModuleHandler->createModule($inputOutput['input'], $inputOutput['output'])) {
846: $notification->displayNotification('error', i18n('Could not create a module!'));
847: return false;
848: } else {
849:
850: $contenidoModuleHandler->saveInfoXML();
851: }
852: }
853: } else {
854: $notification->displayNotification('error', i18n('Could not parse xml file!'));
855:
856: return false;
857: }
858:
859: return true;
860: }
861:
862: 863: 864: 865: 866: 867: 868: 869: 870:
871: private function _addFolderToZip($dir, $zipArchive, $zipdir = '') {
872: if (is_dir($dir)) {
873: if (false !== $handle = cDirHandler::read($dir)) {
874: if (!empty($zipdir)) {
875: $zipArchive->addEmptyDir($zipdir);
876: }
877:
878: foreach ($handle as $file) {
879:
880: if (!is_file($dir . $file)) {
881:
882: if (false === cFileHandler::fileNameIsDot($file)) {
883: $this->_addFolderToZip($dir . $file . '/', $zipArchive, $zipdir . $file . '/');
884: }
885: } else {
886:
887: if ($zipArchive->addFile($dir . $file, $zipdir . $file) === false) {
888: $notification = new cGuiNotification();
889: $notification->displayNotification('error', sprintf(i18n('Could not add file %s to zip!'), $file));
890: }
891: }
892: }
893: }
894: }
895: }
896:
897: 898: 899:
900: public function export() {
901: $notification = new cGuiNotification();
902: $moduleHandler = new cModuleHandler($this->get('idmod'));
903:
904:
905: if ($moduleHandler->modulePathExists()) {
906: $zip = new ZipArchive();
907: $zipName = $this->get('alias') . '.zip';
908: $cfg = cRegistry::getConfig();
909: $path = $cfg['path']['contenido_temp'];
910: if ($zip->open($path . $zipName, ZipArchive::CREATE)) {
911: $this->_addFolderToZip($moduleHandler->getModulePath(), $zip);
912:
913: $zip->close();
914:
915: header('Content-Type: application/zip');
916: header('Content-Length: ' . filesize($path . $zipName));
917: header("Content-Disposition: attachment; filename=\"$zipName\"");
918: readfile($path . $zipName);
919:
920:
921: unlink($path . $zipName);
922: } else {
923: $notification->displayNotification('error', i18n('Could not open the zip file!'));
924: }
925: } else {
926: $notification->displayNotification('error', i18n("Module don't exist on file system!"));
927: }
928: }
929:
930: 931: 932: 933: 934: 935: 936: 937: 938: 939:
940: public function setField($name, $value, $bSafe = true) {
941: switch ($name) {
942: case 'deletable':
943: case 'static':
944: $value = ($value == 1) ? 1 : 0;
945: break;
946: case 'idclient':
947: $value = (int) $value;
948: break;
949: }
950:
951: return parent::setField($name, $value, $bSafe);
952: }
953:
954: 955: 956: 957: 958: 959: 960: 961: 962: 963: 964:
965: public static function processContainerInputCode($containerNr, $containerCfg, $moduleInputCode) {
966: $containerConfigurations = array();
967: if (!empty($containerCfg)) {
968: $containerConfigurations = cApiContainerConfiguration::parseContainerValue($containerCfg);
969: }
970:
971: $CiCMS_Var = '$C' . $containerNr . 'CMS_VALUE';
972: $CiCMS_Values = array();
973:
974: foreach ($containerConfigurations as $key3 => $value3) {
975:
976: $tmp = conHtmlSpecialChars($value3);
977: $tmp = str_replace('\\', '\\\\', $tmp);
978:
979: $CiCMS_Values[] = $CiCMS_Var . '[' . $key3 . '] = "' . $tmp . '";';
980: $moduleInputCode = str_replace("\$CMS_VALUE[$key3]", $tmp, $moduleInputCode);
981: $moduleInputCode = str_replace("CMS_VALUE[$key3]", $tmp, $moduleInputCode);
982: }
983:
984: $moduleInputCode = str_replace('CMS_VALUE', $CiCMS_Var, $moduleInputCode);
985: $moduleInputCode = str_replace("\$" . $CiCMS_Var, $CiCMS_Var, $moduleInputCode);
986: $moduleInputCode = str_replace('CMS_VAR', 'C' . $containerNr . 'CMS_VAR', $moduleInputCode);
987:
988: $CiCMS_Values = implode("\n", $CiCMS_Values);
989:
990: return $CiCMS_Values . "\n" . $moduleInputCode;
991: }
992: }
993: