1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16:
17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
18:
19: cInclude('includes', 'functions.api.string.php');
20: cInclude('includes', 'functions.con.php');
21:
22: 23: 24: 25: 26: 27: 28: 29:
30: class cModuleSynchronizer extends cModuleHandler {
31:
32: 33: 34: 35: 36:
37: private $_lastIdMod = 0;
38:
39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
51: private function _syncModule($dir, $oldModulName, $newModulName) {
52: global $client;
53:
54: if ($this->_isExistInTable($oldModulName, $client) == false) {
55:
56: $this->_addModule($newModulName);
57: } else {
58:
59: if ($oldModulName != $newModulName) {
60: $this->_updateModulnameInDb($oldModulName, $newModulName, $client);
61: }
62: }
63: }
64:
65: 66: 67: 68: 69: 70: 71:
72: private function _renameFiles($dir, $oldModulName, $newModulName) {
73: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php') == true) {
74: rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_input.php');
75: }
76:
77: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php') == true) {
78: rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_output.php');
79: }
80:
81: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css') == true) {
82: rename($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css', $dir . $newModulName . '/' . $this->_directories['css'] . $newModulName . '.css');
83: }
84:
85: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js') == true) {
86: rename($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js', $dir . $newModulName . '/' . $this->_directories['js'] . $newModulName . '.js');
87: }
88: }
89:
90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103:
104: private function _renameFileAndDir($dir, $dirNameOld, $dirNameNew, $client) {
105: if (rename($dir . $dirNameOld, $dir . $dirNameNew) == FALSE) {
106: return false;
107: } else {
108: $this->_renameFiles($dir, $dirNameOld, $dirNameNew);
109: }
110: return true;
111: }
112:
113: 114: 115: 116: 117: 118: 119: 120: 121: 122:
123: public function compareFileAndModuleTimestamp() {
124: global $cfgClient;
125:
126: $db = cRegistry::getDb();
127: $db->query('
128: SELECT lastmodified, idclient, description, type, `name`, alias, idmod
129: FROM ' . $this->_cfg['tab']['mod'] . '
130: WHERE idclient = ' . cSecurity::toInteger($this->_client));
131:
132: $synchLock = 0;
133: $retIdMod = 0;
134:
135:
136: $idmods = [];
137:
138: while ($db->nextRecord()) {
139: $showMessage = false;
140:
141: $modulePath = $cfgClient[$db->f('idclient')]['module']['path'] . $db->f('alias') . '/';
142: $modulePHP = $modulePath . $this->_directories['php'] . $db->f('alias');
143:
144: $lastmodified = $db->f('lastmodified');
145: $lastmodified = DateTime::createFromFormat('Y-m-d H:i:s', $lastmodified);
146: $lastmodified = $lastmodified->getTimestamp();
147:
148: $lastmodInput = $lastmodOutput = 0;
149:
150: if (cFileHandler::exists($modulePHP . '_input.php')) {
151: $lastmodInput = filemtime($modulePHP . '_input.php');
152: }
153:
154: if (cFileHandler::exists($modulePHP . '_output.php')) {
155: $lastmodOutput = filemtime($modulePHP . '_output.php');
156: }
157:
158: if (cFileHandler::exists($modulePath . "info.xml")) {
159: $lastModInfo = filemtime($modulePath . "info.xml");
160: if ($lastModInfo > $lastmodified) {
161: try {
162: $xml = cFileHandler::read($modulePath . 'info.xml');
163: } catch (cInvalidArgumentException $e) {
164: $xml = '';
165: }
166: $modInfo = cXmlBase::xmlStringToArray($xml);
167: $mod = new cApiModule($db->f("idmod"));
168: if ($modInfo["description"] != $mod->get("description")) {
169: $mod->set("description", $modInfo["description"]);
170: $this->setLastModified($lastModInfo, $db->f('idmod'));
171: }
172: if ($modInfo["type"] != $mod->get("type")) {
173: $mod->set("type", $modInfo["type"]);
174: $this->setLastModified($lastModInfo, $db->f('idmod'));
175: }
176:
177: if ($modInfo["name"] != $mod->get("name")) {
178: $mod->set("name", $modInfo["name"]);
179: $this->setLastModified($lastModInfo, $db->f('idmod'));
180: }
181:
182: if ($modInfo["alias"] != $mod->get("alias")) {
183: $mod->set("alias", $modInfo["alias"]);
184: $this->setLastModified($lastModInfo, $db->f('idmod'));
185: }
186: $mod->store(true);
187: $synchLock = 1;
188: $showMessage = true;
189: }
190: }
191:
192: $lastmodabsolute = max($lastmodInput, $lastmodOutput);
193: if ($lastmodified < $lastmodabsolute) {
194: $synchLock = 1;
195: $this->setLastModified($lastmodabsolute, $db->f('idmod'));
196: $idmods[] = (int) $db->f('idmod');
197: $showMessage = true;
198: }
199:
200: if (($idmod = $this->_synchronizeFilesystemAndDb($db)) != 0) {
201: $retIdMod = $idmod;
202: }
203:
204: if ($showMessage) {
205: cRegistry::appendLastOkMessage(sprintf(i18n('Module %s successfully synchronized'), $db->f('name')));
206: }
207: }
208:
209: if (count($idmods)) {
210: conGenerateCodeForAllartsUsingMod($idmods);
211: }
212:
213: if ($synchLock == 0) {
214: cRegistry::addInfoMessage(i18n('All modules are already synchronized'));
215: }
216:
217:
218: return $retIdMod;
219: }
220:
221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236:
237: private function _synchronizeFilesystemAndDb($db) {
238: $returnIdMod = 0;
239: $this->initWithDatabaseRow($db);
240:
241: if ($this->modulePathExists() == false) {
242: $modul = new cApiModule($db->f('idmod'));
243: $returnIdMod = $db->f('idmod');
244: if ($modul->moduleInUse($db->f('idmod')) == true) {
245:
246: if ($this->createModule() == false) {
247: $notification = new cGuiNotification();
248: $notification->displayNotification('error', i18n("Can not create module") . " " . $db->f('name'));
249: }
250: } else {
251:
252: $sql = sprintf('DELETE FROM %s WHERE idmod = %s AND idclient = %s', $this->_cfg['tab']['mod'], $db->f('idmod'), $this->_client);
253: $myDb = cRegistry::getDb();
254: $myDb->query($sql);
255: }
256: }
257: return $returnIdMod;
258: }
259:
260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271:
272: public function synchronize() {
273: global $cfgClient;
274:
275:
276: $dir = $cfgClient[$this->_client]['module']['path'];
277:
278: if (is_dir($dir)) {
279: if (false !== ($handle = cDirHandler::read($dir))) {
280: foreach ($handle as $file) {
281: if (false === cFileHandler::fileNameBeginsWithDot($file) && is_dir($dir . $file . '/')) {
282: $newFile = cString::cleanURLCharacters($file);
283:
284: if ($newFile == $file) {
285: $this->_syncModule($dir, $file, $newFile);
286: } else {
287: if (is_dir($dir . $newFile)) {
288:
289:
290: $newDirName = $newFile . cString::getPartOfString(md5(time() . rand(0, time())), 0, 4);
291:
292:
293: if ($this->_renameFileAndDir($dir, $file, $newDirName, $this->_client) != false) {
294: $this->_syncModule($dir, $file, $newDirName);
295: }
296: } else {
297:
298: if ($this->_renameFileAndDir($dir, $file, $newFile, $this->_client) != false) {
299: $this->_syncModule($dir, $file, $newFile);
300: }
301: }
302: }
303: }
304: }
305: }
306: }
307:
308:
309: return $this->_lastIdMod;
310: }
311:
312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324:
325: private function _isExistInTable($alias, $idclient) {
326: $db = cRegistry::getDb();
327:
328:
329: $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $alias, $idclient);
330:
331: $db->query($sql);
332:
333:
334: if ($db->nextRecord()) {
335: return true;
336: } else {
337: return false;
338: }
339: }
340:
341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351:
352: private function _updateModulnameInDb($oldName, $newName, $idclient) {
353: $db = cRegistry::getDb();
354:
355:
356: $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $oldName, $idclient);
357:
358: $db->query($sql);
359:
360:
361: if ($db->nextRecord()) {
362: $sqlUpdateName = sprintf("UPDATE %s SET alias='%s' WHERE idmod=%s", $this->_cfg['tab']['mod'], $newName, $db->f('idmod'));
363: $db->query($sqlUpdateName);
364: return;
365: }
366: }
367:
368: 369: 370: 371: 372: 373: 374: 375: 376: 377:
378: private function _addModule($name) {
379:
380:
381: $client = cRegistry::getClientId();
382: $alias = $name;
383: $type = '';
384: $error = 'none';
385: $description = '';
386: $deletable = 0;
387: $template = '';
388: $static = 0;
389: $package_guid = '';
390: $package_data = '';
391: $author = '';
392: $created = '';
393: $lastmodified = '1970-01-01 00:00:00';
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405: $oModColl = new cApiModuleCollection();
406: $mod = $oModColl->create(
407: $name,
408: $client,
409: $alias,
410: $type,
411: $error,
412: $description,
413: $deletable,
414: $template,
415: $static,
416: $package_guid,
417: $package_data,
418: $author,
419: $created,
420: $lastmodified
421: );
422:
423:
424: if (is_object($mod)) {
425: $this->_lastIdMod = $mod->get('idmod');
426: }
427: }
428:
429: 430: 431: 432: 433: 434: 435: 436: 437: 438:
439: public function setLastModified($timestamp, $idmod) {
440: $oMod = new cApiModule((int) $idmod);
441: if ($oMod->isLoaded()) {
442: $oMod->set('lastmodified', date('Y-m-d H:i:s', $timestamp));
443: $oMod->store(true);
444: }
445: }
446:
447: }
448: