Exemplo n.º 1
0
		/**
		 * If it is proven to be a valid SQL Statement worthy of logging, the persistQuery() function will
		 * write the statement to file and log it
		 * @param string $query The SQL Statement that will be saved to file and CDI log
		 */
		public static function persistQuery($query) {
			try {
				$ts = time();
		
				if(self::$lastEntryTS != $ts) {
					self::$lastEntryTS = $ts;
					self::$lastEntryOrder = 0;
				} else {
					self::$lastEntryOrder++;
				}
				
				$id = $ts . '-' . self::$lastEntryOrder;
				$hash = md5($id . $query);
				$date = date('Y-m-d H:i:s', $ts);
				
				try{
					//We are only logging this to file because we do not execute CDI queries on the MASTER instance
					//The database table `tbl_cdi_log` is removed from the database on the MASTER instance.
					//It is the repsonsibility of the user to ensure that they only have a single MASTER instance 
					//and that they protect the integrity of the Symphony database
					$entries = CdiLogQuery::getCdiLogEntries();
					$entries[$id] = array(0 => $ts, 1 => self::$lastEntryOrder, 2 => $hash, 3 => $query);
					file_put_contents(CDI_FILE, json_encode($entries));
					return true;
				} catch(Exception $e) {
					//TODO: think of some smart way of dealing with errors, perhaps through the preference screen or a CDI Status content page?
					CdiLogQuery::rollback($hash,$ts,$order);
					return false;
				}
			} catch(Exception $e) {
				//TODO: think of some smart way of dealing with errors, perhaps through the preference screen or a CDI Status content page?
				return false;
			}
		}
Exemplo n.º 2
0
		/**
		 * The CdiQueryLog::log() function is called from the Database implementation responsible for executing Symphony SQL queries
		 * If in MASTER mode, CDI will save the query to disk allowing it to be committed to the VCS. From there it will be available
		 * for automatic query exection by CDI slave instances (see also CdiLogQuery::executeQueries()).
		 * @param String $query
		 */
		public static function log($query) {
			// Prevent execution on the frontend and check configuration conditions
			// Do not log the query when CDI is disabled, in SLAVE mode or busy executing queries.
			// Additionally if the logger is not installed, you should not be able to call this function
			if((!class_exists('Administration')) || !CdiUtil::isEnabled() || self::$isUpdating) {
				return true;
			}
			
			$query = trim($query);
			$tbl_prefix = Symphony::Configuration()->get('tbl_prefix', 'database');
	
			/* FILTERS */
			// do not register changes to tbl_cdi_log
			if (preg_match("/{$tbl_prefix}cdi_log/i", $query)) return true;
			// only structural changes, no SELECT statements
			if (!preg_match('/^(insert|update|delete|create|drop|alter|rename)/i', $query)) return true;
			// un-tracked tables (sessions, cache, authors)
			if (preg_match("/{$tbl_prefix}(authors|cache|forgotpass|sessions)/i", $query)) return true;
			// content updates in tbl_entries (includes tbl_entries_fields_*)
			if (preg_match('/^(insert|delete|update)/i', $query) && preg_match("/({$config->tbl_prefix}entries)/i", $query)) return true;
			// append query delimeter if it doesn't exist
			if (!preg_match('/;$/', $query)) $query .= ";";

			// Replace the table prefix in the query
			// This allows query execution on slave instances with different table prefix.
			$query = str_replace($tbl_prefix,'tbl_',$query);
			
			// We've come far enough... let's try to save it to disk!
			if(CdiUtil::isCdiMaster()) {
				return CdiMaster::persistQuery($query);
			} else if(CdiUtil::isCdiDBSyncMaster()) {
				return CdiDBSync::persistQuery($query);
			} else {
				//TODO: error handling for the unusual event that we are dealing with here.
				return true;
			}
		}
Exemplo n.º 3
0
	require_once(EXTENSIONS . '/cdi/lib/class.cdilogquery.php');
	require_once(EXTENSIONS . '/cdi/lib/class.cdipreferences.php');
	
	// We should not be processing any queries when the extension is disabled or when we are the Master instance
	if((!class_exists('Administration')) || !CdiUtil::isEnabled()) {
	   	$result["status"] = "error";
	   	$result["message"] = "You can only execute actions from within Symphony and when the CDI extension is enabled";
		Symphony::Log()->pushToLog('[CDI] You can only execute actions from within Symphony and when the CDI extension is enabled', E_NOTICE, true);
	} 
	
	// Clean the database and log files when the cdi_clear action is called
	if(isset($_POST["action"]["cdi_clear"])) {
		try {
			if(CdiUtil::isCdiMaster()) {
				CdiMaster::uninstall();
				CdiMaster::install();
			} else if (CdiUtil::isCdiSlave()) {
				CdiSlave::uninstall();
				CdiSlave::install();
			} else if(CdiUtil::isCdiDBSync()) {
				CdiDBSync::uninstall();
				CdiDBSync::install();
			}
			$result["status"] = 'success';
		} catch(Exception $e) {
			$result["status"] = "error";
			$result["message"] = $e->getMessage();
			Symphony::Log()->pushToLog('[CDI] ' . $e->getMessage(), E_ERROR, true);
		}
	}
Exemplo n.º 4
0
		public function savePreferences($context){
			if(CdiPreferences::save()) {
				// apply config changes
				if(CdiUtil::isCdiSlave()) { CdiSlave::install(); } 
				else if (CdiUtil::isCdiMaster()) { CdiMaster::install(); }
				else { CdiDBSync::install(); }
			} else {
				Administration::instance()->Page->pageAlert(_('An unknown error occurred while saving preferences for CDI. Your changes have not been saved.'));
				return false;
			}
		}