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: private function _syncModule($dir, $oldModulName, $newModulName) {
48: global $client;
49:
50: if ($this->_isExistInTable($oldModulName, $client) == false) {
51:
52: $this->_addModule($newModulName);
53: cRegistry::appendLastOkMessage(sprintf(i18n('Module %s successfully synchronized'), $newModulName));
54: } else {
55:
56: if ($oldModulName != $newModulName) {
57: $this->_updateModulnameInDb($oldModulName, $newModulName, $client);
58: }
59: }
60: }
61:
62: 63: 64: 65: 66: 67: 68:
69: private function _renameFiles($dir, $oldModulName, $newModulName) {
70: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php') == true) {
71: rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_input.php');
72: }
73:
74: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php') == true) {
75: rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_output.php');
76: }
77:
78: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css') == true) {
79: rename($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css', $dir . $newModulName . '/' . $this->_directories['css'] . $newModulName . '.css');
80: }
81:
82: if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js') == true) {
83: rename($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js', $dir . $newModulName . '/' . $this->_directories['js'] . $newModulName . '.js');
84: }
85: }
86:
87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100:
101: private function _renameFileAndDir($dir, $dirNameOld, $dirNameNew, $client) {
102: if (rename($dir . $dirNameOld, $dir . $dirNameNew) == FALSE) {
103: return false;
104: } else {
105: $this->_renameFiles($dir, $dirNameOld, $dirNameNew);
106: }
107: return true;
108: }
109:
110: 111: 112: 113: 114: 115: 116:
117: public function compareFileAndModuleTimestamp() {
118: global $cfgClient;
119:
120: $synchLock = 0;
121:
122: $sql = sprintf('SELECT UNIX_TIMESTAMP(mod1.lastmodified) AS lastmodified,mod1.idclient,description,type, mod1.name, mod1.alias, mod1.idmod FROM %s AS mod1 WHERE mod1.idclient = %s', $this->_cfg['tab']['mod'], $this->_client);
123:
124: $db = cRegistry::getDb();
125: $db->query($sql);
126: $retIdMod = 0;
127:
128: while ($db->nextRecord()) {
129: $showMessage = false;
130:
131: $modulePath = $cfgClient[$db->f('idclient')]['module']['path'] . $db->f('alias') . '/';
132: $modulePHP = $modulePath . $this->_directories['php'] . $db->f('alias');
133:
134: $lastmodified = $db->f('lastmodified');
135:
136: $lastmodInput = $lastmodOutput = 0;
137:
138: if (cFileHandler::exists($modulePHP . '_input.php')) {
139: $lastmodInput = filemtime($modulePHP . '_input.php');
140: }
141:
142: if (cFileHandler::exists($modulePHP . '_output.php')) {
143: $lastmodOutput = filemtime($modulePHP . '_output.php');
144: }
145:
146: if (cFileHandler::exists($modulePath . "info.xml")) {
147: $lastModInfo = filemtime($modulePath . "info.xml");
148: if ($lastModInfo > $lastmodified) {
149: $modInfo = cXmlBase::xmlStringToArray(cFileHandler::read($modulePath . "info.xml"));
150: $mod = new cApiModule($db->f("idmod"));
151: if ($modInfo["description"] != $mod->get("description")) {
152: $mod->set("description", $modInfo["description"]);
153: $this->setLastModified($lastModInfo, $db->f('idmod'));
154: }
155: if ($modInfo["type"] != $mod->get("type")) {
156: $mod->set("type", $modInfo["type"]);
157: $this->setLastModified($lastModInfo, $db->f('idmod'));
158: }
159:
160: if ($modInfo["name"] != $mod->get("name")) {
161: $mod->set("name", $modInfo["name"]);
162: $this->setLastModified($lastModInfo, $db->f('idmod'));
163: }
164:
165: if ($modInfo["alias"] != $mod->get("alias")) {
166: $mod->set("alias", $modInfo["alias"]);
167: $this->setLastModified($lastModInfo, $db->f('idmod'));
168: }
169: $mod->store();
170: $synchLock = 1;
171: $showMessage = true;
172: }
173: }
174:
175: $lastmodabsolute = max($lastmodInput, $lastmodOutput);
176: if ($lastmodified < $lastmodabsolute) {
177:
178: $synchLock = 1;
179: $this->setLastModified($lastmodabsolute, $db->f('idmod'));
180: conGenerateCodeForAllartsUsingMod($db->f('idmod'));
181: $showMessage = true;
182: }
183:
184: if (($idmod = $this->_synchronizeFilesystemAndDb($db)) != 0) {
185: $retIdMod = $idmod;
186: }
187:
188: if ($showMessage) {
189: cRegistry::appendLastOkMessage(sprintf(i18n('Module %s successfully synchronized'), $db->f('name')));
190: }
191: }
192:
193: if ($synchLock == 0) {
194: cRegistry::addInfoMessage(i18n('All modules are already synchronized'));
195: }
196:
197:
198: return $retIdMod;
199: }
200:
201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211:
212: private function _synchronizeFilesystemAndDb($db) {
213: $returnIdMod = 0;
214: $this->initWithDatabaseRow($db);
215:
216: if ($this->modulePathExists() == false) {
217: $modul = new cApiModule($db->f('idmod'));
218: $returnIdMod = $db->f('idmod');
219: if ($modul->moduleInUse($db->f('idmod')) == true) {
220:
221: if ($this->createModule() == false) {
222: $notification = new cGuiNotification();
223: $notification->displayNotification('error', i18n("Can not create module") . " " . $db->f('name'));
224: }
225: } else {
226:
227: $sql = sprintf('DELETE FROM %s WHERE idmod = %s AND idclient = %s', $this->_cfg['tab']['mod'], $db->f('idmod'), $this->_client);
228: $myDb = cRegistry::getDb();
229: $myDb->query($sql);
230: }
231: }
232: return $returnIdMod;
233: }
234:
235: 236: 237: 238: 239: 240: 241: 242: 243:
244: public function synchronize() {
245: global $cfgClient;
246:
247:
248: $dir = $cfgClient[$this->_client]['module']['path'];
249:
250: if (is_dir($dir)) {
251: if (false !== ($handle = cDirHandler::read($dir))) {
252: foreach ($handle as $file) {
253: if (false === cFileHandler::fileNameBeginsWithDot($file) && is_dir($dir . $file . '/')) {
254: $newFile = cString::cleanURLCharacters($file);
255:
256: if ($newFile == $file) {
257: $this->_syncModule($dir, $file, $newFile);
258: } else {
259: if (is_dir($dir . $newFile)) {
260:
261:
262: $newDirName = $newFile . substr(md5(time() . rand(0, time())), 0, 4);
263:
264:
265: if ($this->_renameFileAndDir($dir, $file, $newDirName, $this->_client) != false) {
266: $this->_syncModule($dir, $file, $newDirName);
267: }
268: } else {
269:
270: if ($this->_renameFileAndDir($dir, $file, $newFile, $this->_client) != false) {
271: $this->_syncModule($dir, $file, $newFile);
272: }
273: }
274: }
275: }
276: }
277: }
278: }
279:
280:
281: return $this->_lastIdMod;
282: }
283:
284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295:
296: private function _isExistInTable($alias, $idclient) {
297: $db = cRegistry::getDb();
298:
299:
300: $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $alias, $idclient);
301:
302: $db->query($sql);
303:
304:
305: if ($db->nextRecord()) {
306: return true;
307: } else {
308: return false;
309: }
310: }
311:
312: 313: 314: 315: 316: 317: 318: 319: 320: 321:
322: private function _updateModulnameInDb($oldName, $newName, $idclient) {
323: $db = cRegistry::getDb();
324:
325:
326: $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $oldName, $idclient);
327:
328: $db->query($sql);
329:
330:
331: if ($db->nextRecord()) {
332: $sqlUpdateName = sprintf("UPDATE %s SET alias='%s' WHERE idmod=%s", $this->_cfg['tab']['mod'], $newName, $db->f('idmod'));
333: $db->query($sqlUpdateName);
334: return;
335: }
336: }
337:
338: 339: 340: 341: 342: 343:
344: private function _addModule($name) {
345:
346:
347: $client = cRegistry::getClientId();
348: $cfgClient = cRegistry::getClientConfig($client);
349:
350:
351: $oModColl = new cApiModuleCollection();
352:
353:
354: $modulePath = $cfgClient['module']['path'] . $name . '/';
355:
356:
357: $modInfo = cXmlBase::xmlStringToArray(cFileHandler::read($modulePath . 'info.xml'));
358:
359:
360: $mod = $oModColl->create($modInfo['name'], $client, $modInfo['alias'], $modInfo['type']);
361:
362: if (is_object($mod)) {
363:
364: $this->_lastIdMod = $mod->get('idmod');
365: }
366: }
367:
368: 369: 370: 371: 372: 373: 374: 375:
376: public function setLastModified($timestamp, $idmod) {
377: $oMod = new cApiModule((int) $idmod);
378: if ($oMod->isLoaded()) {
379: $oMod->set('lastmodified', date('Y-m-d H:i:s', $timestamp));
380: $oMod->store();
381: }
382: }
383:
384: }
385: