diff --git a/plugin/Cache/Objects/CacheDB.php b/plugin/Cache/Objects/CacheDB.php new file mode 100644 index 000000000000..f877ba23c68a --- /dev/null +++ b/plugin/Cache/Objects/CacheDB.php @@ -0,0 +1,84 @@ +id = intval($id); + } + + function setName($name) { + $this->name = $name; + } + + + function getId() { + return intval($this->id); + } + + function getName() { + return $this->name; + } + + public static function insert($name) { + $sql = "INSERT IGNORE INTO cache_schedule_delete (name) VALUES (?)"; + $res = sqlDAL::writeSql($sql, "s", [$name]); + if ($res) { + return true; + } else { + error_log("ObjectYPT::insert::Error on save: " . $sql . " Error : " . json_encode($res)); + return false; + } + } + +} diff --git a/plugin/Cache/Objects/CachesInDB.php b/plugin/Cache/Objects/CachesInDB.php new file mode 100644 index 000000000000..17b3d6943097 --- /dev/null +++ b/plugin/Cache/Objects/CachesInDB.php @@ -0,0 +1,434 @@ +id = intval($id); + } + + public function setContent($content) + { + $content = self::encodeContent($content); + $this->content = $content; + } + + public function setDomain($domain) + { + $this->domain = $domain; + } + + public function setIshttps($ishttps) + { + $this->ishttps = $ishttps; + } + + public function setLoggedType($loggedType) + { + $this->loggedType = $loggedType; + } + + public function setUser_location($user_location) + { + $this->user_location = $user_location; + } + + public function setExpires($expires) + { + $this->expires = $expires; + } + + public function setTimezone($timezone) + { + $this->timezone = $timezone; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getId() + { + return intval($this->id); + } + + public function getContent() + { + $this->content = self::decodeContent($this->content); + return $this->content; + } + + public function getDomain() + { + return $this->domain; + } + + public function getIshttps() + { + return $this->ishttps; + } + + public function getLoggedType() + { + return $this->loggedType; + } + + public function getUser_location() + { + return $this->user_location; + } + + public function getExpires() + { + return $this->expires; + } + + public function getTimezone() + { + return $this->timezone; + } + + public function getName() + { + return $this->name; + } + + static function hashName($name){ + if(preg_match('/^hashName_/', $name)){ + return $name; + } + return 'hashName_'.preg_replace('/[^0-9a-z]/i', '_', $name); + } + + public static function _getCache($name, $domain, $ishttps, $user_location, $loggedType, $ignoreMetadata=false) + { + global $global; + $name = self::hashName($name); + $sql = "SELECT * FROM " . static::getTableName() . " WHERE name = ? "; + $formats = 's'; + $values = [$name]; + $sql .= " AND ishttps = ? AND domain = ? AND user_location = ? "; + $formats = 'siss'; + $values = [$name, $ishttps, $domain, $user_location]; + if(empty($ignoreMetadata)){ + $sql .= " AND loggedType = ? "; + $formats .= 's'; + $values[] = $loggedType; + } + $sql .= " ORDER BY id DESC LIMIT 1"; + + //var_dump($sql, $formats, $values ); + //_error_log(json_encode(array($sql, $values ))); + // I had to add this because the about from customize plugin was not loading on the about page http://127.0.0.1/AVideo/about + $res = sqlDAL::readSql($sql, $formats, $values); + $data = sqlDAL::fetchAssoc($res); + //var_dump( $data); + sqlDAL::close($res); + if ($res) { + if (!empty($data) && !empty($data['content'])) { + $originalContent = $data['content']; + $data['content'] = self::decodeContent($data['content']); + //var_dump($originalContent ); + //var_dump($data['content']); + if($data['content'] === null){ + _error_log("Fail decode content [{$name}]".$originalContent); + //_error_log(json_encode(debug_backtrace()));exit; + //var_dump(debug_backtrace());exit; + //var_dump("Fail decode content [{$name}]", $originalContent);exit; + } + } + $row = $data; + } else { + if (empty($global['mysqli'])) { + $global['mysqli'] = new stdClass(); + } + if($global['mysqli']->errno == 1146){ + $error = array($global['mysqli']->error); + $file = $global['systemRootPath'] . 'plugin/Cache/install/install.sql'; + sqlDal::executeFile($file); + if (!static::isTableInstalled()) { + $error[] = $global['mysqli']->error; + die("We could not create table ".static::getTableName().'
'.implode('
', $error)); + } + } + $row = false; + } + //var_dump($row); + return $row; + } + + public static function _setCache($name, $value, $domain, $ishttps, $user_location, $loggedType) + { + if (!is_string($value)) { + $value = _json_encode($value); + } + if (empty($value)) { + return false; + } + + $row = self::_getCache($name, $domain, $ishttps, $user_location, $loggedType); + if (!empty($row)) { + $c = new CachesInDB($row['id']); + } else { + $c = new CachesInDB(0); + } + + $name = self::hashName($name); + $c->setContent($value); + $c->setName($name); + $c->setDomain($domain); + $c->setIshttps($ishttps); + $c->setUser_location($user_location); + $c->setLoggedType($loggedType); + $c->setExpires(date('Y-m-d H:i:s', strtotime('+ 1 month'))); + return $c->save(); + } + private static function prepareCacheItem($name, $cache, $metadata, $tz, $time) { + $formattedCacheItem = []; + + $name = self::hashName($name); + $content = !is_string($cache) ? json_encode($cache) : $cache; + if (empty($content)) { + return null; + } + + $expires = date('Y-m-d H:i:s', strtotime('+1 month')); + + // Format for the prepared statement + $formattedCacheItem['format'] = "ssssssssi"; + $formattedCacheItem['values'] = [ + $name, + $content, + $metadata['domain'], + $metadata['ishttps'], + $metadata['user_location'], + $metadata['loggedType'], + $expires, + $tz, + $time + ]; + + return $formattedCacheItem; + } + + public static function setBulkCache($cacheArray, $metadata, $batchSize = 50) { + if(isBot()){ + return false; + } + if (empty($cacheArray)) { + return false; + } + + global $global; + $cacheBatches = array_chunk($cacheArray, $batchSize, true); + $tz = date_default_timezone_get(); + $time = time(); + $result = true; + + foreach ($cacheBatches as $batch) {$placeholders = []; + $formats = []; + $values = []; + + foreach ($batch as $name => $cache) { + $cacheItem = self::prepareCacheItem($name, $cache, $metadata, $tz, $time); + if ($cacheItem === null) continue; + + $placeholders[] = "(?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())"; + $formats[] = $cacheItem['format']; + $values = array_merge($values, $cacheItem['values']); + } + + $sql = "INSERT INTO " . static::getTableName() . " (name, content, domain, ishttps, user_location, loggedType, expires, timezone, created_php_time, created, modified) + VALUES " . implode(", ", $placeholders) . " + ON DUPLICATE KEY UPDATE + content = VALUES(content), + expires = VALUES(expires), + created_php_time = VALUES(created_php_time), + modified = NOW()"; + + // Start transaction + mysqlBeginTransaction(); + + try { + $res = sqlDAL::writeSql($sql, implode('', $formats), $values); + $result &= $res; + mysqlCommit(); + } catch (\Throwable $th) { + mysqlRollback(); + _error_log($th->getMessage() . " name={$name} ".$sql, AVideoLog::$ERROR); + //return false; + } + } + + return $result; + } + + public static function readUncomited($uncomited=true) + { + if($uncomited){ + $sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"; + }else{ + $sql = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;"; + } + return sqlDAL::writeSql($sql); + } + + public static function _deleteCache($name) + { + if(isBot()){ + return false; + } + global $global; + if (empty($name)) { + return false; + } + + if (!static::isTableInstalled()) { + return false; + } + $name = self::hashName($name); + self::set_innodb_lock_wait_timeout(); + $sql = "DELETE FROM " . static::getTableName() . " "; + $sql .= " WHERE name = ?"; + $global['lastQuery'] = $sql; + //_error_log("Delete Query: ".$sql); + self::readUncomited(); + $return = sqlDAL::writeSql($sql, "s", [$name]); + self::readUncomited(false); + return $return; + } + public static function set_innodb_lock_wait_timeout($timeout = 10) + { + global $global; + $sql = "SET SESSION innodb_lock_wait_timeout = {$timeout};"; + /** + * + * @var array $global + * @var object $global['mysqli'] + */ + return $global['mysqli']->query($sql); + } + + public static function _deleteCacheStartingWith($name) + { + if(isBot() && !preg_match('/plugin\/Live\/on_/', $_SERVER['SCRIPT_NAME'])){ + _error_log("CachesInDB::_deleteCacheStartingWith($name) error line=".__LINE__); + return false; + } + global $global; + if (empty($name)) { + _error_log("CachesInDB::_deleteCacheStartingWith($name) error line=".__LINE__); + return false; + } + if (!static::isTableInstalled()) { + _error_log("CachesInDB::_deleteCacheStartingWith($name) error line=".__LINE__); + return false; + } + $name = self::hashName($name); + self::set_innodb_lock_wait_timeout(); + //$sql = "DELETE FROM " . static::getTableName() . " WHERE name LIKE '{$name}%'"; + $sql = "DELETE FROM " . static::getTableName() . " WHERE MATCH(name) AGAINST('{$name}*' IN BOOLEAN MODE) OR name like '{$name}%';"; + + _error_log("CachesInDB::_deleteCacheStartingWith($name) $sql"); + $global['lastQuery'] = $sql; + //_error_log("Delete Query: ".$sql); + self::readUncomited(); + $return = sqlDAL::writeSql($sql); + self::readUncomited(false); + return $return; + } + + + public static function _deleteCacheWith($name) + { + if(isBot()){ + return false; + } + global $global; + if (empty($name)) { + return false; + } + if (!static::isTableInstalled()) { + return false; + } + $name = self::hashName($name); + $name = str_replace('hashName_', '', $name); + self::set_innodb_lock_wait_timeout(); + $sql = "DELETE FROM " . static::getTableName() . " "; + $sql .= " WHERE name LIKE '%{$name}%'"; + $global['lastQuery'] = $sql; + //_error_log("Delete Query: ".$sql); + self::readUncomited(); + $return = sqlDAL::writeSql($sql); + self::readUncomited(false); + return $return; + } + + public static function _deleteAllCache() + { + if(isBot()){ + return false; + } + global $global; + if (!static::isTableInstalled()) { + return false; + } + /* + $sql = "TRUNCATE TABLE " . static::getTableName() . " "; + $global['lastQuery'] = $sql; + //_error_log("Delete Query: ".$sql); + return sqlDAL::writeSql($sql); + */ + $sql = 'DROP TABLE IF EXISTS `CachesInDB`'; + sqlDal::writeSql($sql); + $file = $global['systemRootPath'] . 'plugin/Cache/install/install.sql'; + return sqlDal::executeFile($file); + } + + public static function encodeContent($content) + { + $original = $content; + if (!is_string($content)) { + $content = _json_encode($content); + } + $prefix = substr($content, 0, 10); + if ($prefix!== CacheDB::$prefix) { + //$content = base64_encode($content); + $content = CacheDB::$prefix.$content; + } + return $content; + } + + public static function decodeContent($content) + { + $prefix = substr($content, 0, strlen(CacheDB::$prefix)); + if ($prefix === CacheDB::$prefix) { + $content = str_replace(CacheDB::$prefix, '', $content); + //$content = base64_decode($content); + } + return $content; + } +} diff --git a/plugin/Cache/Objects/CachesInDBMem.php b/plugin/Cache/Objects/CachesInDBMem.php new file mode 100644 index 000000000000..92064a968fda --- /dev/null +++ b/plugin/Cache/Objects/CachesInDBMem.php @@ -0,0 +1,223 @@ +errno == 1146) { + self::tryToCreateTables(); + } + } + return false; + } + public static function setBulkCache($cacheArray, $metadata, $batchSize = 50) + { + if (empty($cacheArray)) { + return false; + } + $start = microtime(true); + foreach ($cacheArray as $name => $cache) { + self::_setCache($name, $cache, $metadata['domain'], $metadata['ishttps'], $metadata['user_location'], $metadata['loggedType']); + } + + $end = number_format(microtime(true) - $start, 5); + //_error_log("Memory setBulkCache took {$end} seconds"); + return true; + } + + + public static function _setCache($name, $content, $domain, $ishttps, $user_location, $loggedType) + { + if (!is_string($content)) { + $content = _json_encode($content); + } + + if (empty($content)){ + return false; + } + + global $global; + $time = time(); + $timezone = date_default_timezone_get();; + + // Preparing SQL for Metadata Insertion + $metadataSql = "INSERT INTO " . self::$metadataTable . " (name, domain, ishttps, user_location, loggedType, created, modified, expires, timezone, created_php_time) + VALUES (?, ?, ?, ?, ?, NOW(), NOW(), ?, ?, ?) + ON DUPLICATE KEY UPDATE + expires = VALUES(expires), + created_php_time = VALUES(created_php_time), + modified = NOW()"; + + $contentSqlBase = "INSERT INTO " . self::$contentTable . " (id, content) + VALUES (?, ?) + ON DUPLICATE KEY UPDATE + content = VALUES(content)"; + + $name = self::hashName($name); + + $expires = date('Y-m-d H:i:s', strtotime('+1 month')); + + $metadataSqlValues = [$name, $domain, $ishttps, $user_location, $loggedType, $expires, $timezone, $time]; + /** + * + * @var array $global + * @var object $global['mysqli'] + */ + + // Insert metadata + $metadataResult = sqlDAL::writeSql($metadataSql, 'sssssssi', $metadataSqlValues); + if ($metadataResult) { + $insertedId = @$global['mysqli']->insert_id; // Get the last inserted ID + // Insert content + if ($insertedId > 0) { + return sqlDAL::writeSql($contentSqlBase, 'is', [$insertedId, $content]); + } else { + return false; + } + } else { + return false; + } + } + + + public static function _deleteCache($name) + { + global $global; + if (empty($name)) { + return false; + } + + if (!static::isTableInstalled(self::$metadataTable)) { + return false; + } + $name = self::hashName($name); + + // Delete from content table + $sqlContent = "DELETE FROM " . self::$contentTable . " WHERE id IN (SELECT id FROM " . self::$metadataTable . " WHERE name = ?)"; + sqlDAL::writeSql($sqlContent, "s", [$name]); + + // Delete from metadata table + $sqlMetadata = "DELETE FROM " . self::$metadataTable . " WHERE name = ?"; + return sqlDAL::writeSql($sqlMetadata, "s", [$name]); + } + public static function _deleteCacheStartingWith($name) + { + global $global; + if (empty($name)) { + return false; + } + + if (!static::isTableInstalled(self::$metadataTable)) { + return false; + } + $name = self::hashName($name); + + // Delete from content table + $sqlContent = "DELETE FROM " . self::$contentTable . " WHERE id IN (SELECT id FROM " . self::$metadataTable . " WHERE name LIKE '{$name}%')"; + sqlDAL::writeSql($sqlContent); + + // Delete from metadata table + $sqlMetadata = "DELETE FROM " . self::$metadataTable . " WHERE name LIKE '{$name}%'"; + return sqlDAL::writeSql($sqlMetadata); + } + public static function _deleteCacheWith($name) + { + global $global; + if (empty($name)) { + return false; + } + + if (!static::isTableInstalled(self::$metadataTable)) { + return false; + } + $name = self::hashName($name); + + // Delete from content table + $sqlContent = "DELETE FROM " . self::$contentTable . " WHERE id IN (SELECT id FROM " . self::$metadataTable . " WHERE name LIKE '%{$name}%')"; + sqlDAL::writeSql($sqlContent); + + // Delete from metadata table + $sqlMetadata = "DELETE FROM " . self::$metadataTable . " WHERE name LIKE '%{$name}%'"; + return sqlDAL::writeSql($sqlMetadata); + } + public static function _deleteAllCache() + { + global $global; + + if (!static::isTableInstalled(self::$metadataTable)) { + return false; + } + + // Truncate content table + $sqlContent = "TRUNCATE TABLE " . self::$contentTable . ""; + sqlDAL::writeSql($sqlContent); + + // Truncate metadata table + $sqlMetadata = "TRUNCATE TABLE " . self::$metadataTable . ""; + return sqlDAL::writeSql($sqlMetadata); + } +}