To explain the motivation a little bit, when VersionPress is installed, it rewrites the wpdb class
and adds its own logic into DB-manipulating methods. That is good for WordPress and all the 3rd party
plugins but not for VersionPress itself - it needs the raw query() functionality not to trigger
itself recursively. Now, the developers could call $wpdb->__wp_query() but that's ugly,
fragile and easy to forget. This proxy improves that.
(The PhpDoc API description below can be regenerated by ./wpdb-api-to-phpdoc.php.)
public function saveSchema($table) { $schemaFile = $this->getSchemaFile($table); $tableDDL = $this->database->get_var("show create table `{$table}`", 1); if (!$tableDDL) { return; } $tableDDL = str_replace("CREATE TABLE `{$this->database->prefix}", 'CREATE TABLE IF NOT EXISTS `' . Storage::PREFIX_PLACEHOLDER, $tableDDL); $tableDDL = preg_replace('/( AUTO_INCREMENT=[0-9]+)/', '', $tableDDL); FileSystem::mkdir($this->directory); file_put_contents($schemaFile, $tableDDL); }
public function prepare_deleteOrphanedMenuItems() { $dbHost = self::$testConfig->testSite->dbHost; $dbUser = self::$testConfig->testSite->dbUser; $dbPassword = self::$testConfig->testSite->dbPassword; $dbName = self::$testConfig->testSite->dbName; $wpdb = new \wpdb($dbUser, $dbPassword, $dbName, $dbHost); $wpdb->set_prefix(self::$testConfig->testSite->dbTablePrefix); $deleteOrphanedFilesSeconds = Reverter::DELETE_ORPHANED_POSTS_SECONDS; $database = new Database($wpdb); $database->query($wpdb->prepare("UPDATE {$database->postmeta} SET meta_value = meta_value - {$deleteOrphanedFilesSeconds} " . "WHERE meta_key='_menu_item_orphaned' ORDER BY meta_id DESC LIMIT 1", [])); $pluginsDir = self::$wpAutomation->getPluginsDir(); $updateConfigArgs = ['VERSIONPRESS_GUI', 'html', 'require' => $pluginsDir . '/versionpress/src/Cli/vp-internal.php']; self::$wpAutomation->runWpCliCommand('vp-internal', 'update-config', $updateConfigArgs); }
/** * @param $entityName * @return mixed */ private function getEntitiesFromDatabase($entityName) { if ($this->dbSchema->isChildEntity($entityName)) { $entityInfo = $this->dbSchema->getEntityInfo($entityName); $parentReference = $entityInfo->parentReference; return $this->database->get_results("SELECT * FROM {$this->dbSchema->getPrefixedTableName($entityName)} ORDER BY {$parentReference}", ARRAY_A); } return $this->database->get_results("SELECT * FROM {$this->dbSchema->getPrefixedTableName($entityName)}", ARRAY_A); }
/** * Deletes orphaned files older than 1 minute (due to postponed commits, that has not been used) */ private function clearOrphanedPosts() { $deleteTimestamp = time() - self::DELETE_ORPHANED_POSTS_SECONDS; // Older than 1 minute $orphanedMenuItems = $this->database->get_col($this->database->prepare("SELECT ID FROM {$this->database->posts} AS p\n LEFT JOIN {$this->database->postmeta} AS m ON p.ID = m.post_id\n WHERE post_type = 'nav_menu_item'\n AND post_status = 'draft' AND meta_key = '_menu_item_orphaned' AND meta_value < '%d'", $deleteTimestamp)); foreach ((array) $orphanedMenuItems as $menuItemId) { wp_delete_post($menuItemId, true); $this->committer->discardPostponedCommit('menu-item-' . $menuItemId); } }
private function countEntities() { $entities = $this->schema->getAllEntityNames(); $totalEntitiesCount = 0; foreach ($entities as $entity) { $table = $this->schema->getPrefixedTableName($entity); $totalEntitiesCount += $this->database->get_var("SELECT COUNT(*) FROM {$table}"); } return $totalEntitiesCount; }
private function getIdsForVpIds($referencesToUpdate) { if (count($referencesToUpdate) === 0) { return [[0, 0]]; } $vpIds = array_map(function ($vpId) { return 'UNHEX("' . $vpId . '")'; }, $referencesToUpdate); $vpIdsRestriction = join(', ', $vpIds); $result = $this->database->get_results("SELECT HEX(vp_id), id FROM {$this->database->vp_id} WHERE vp_id IN ({$vpIdsRestriction})", ARRAY_N); $result[] = [0, 0]; return array_combine(array_column($result, 0), array_column($result, 1)); }
/** * Parses UPDATE query * * @param Parser $parser * @param DbSchemaInfo $schema * @param string $query * @param Database $database * @return ParsedQueryData */ private function parseUpdateQuery($parser, $query, $schema, $database) { /** @var UpdateStatement $sqlStatement */ $sqlStatement = $parser->statements[0]; $table = $sqlStatement->tables[0]->table; $idColumns = $this->resolveIdColumns($schema, $table); if ($idColumns == null) { return null; } $parsedQueryData = new ParsedQueryData(ParsedQueryData::UPDATE_QUERY); $parsedQueryData->table = $table; $parsedQueryData->idColumnsNames = $idColumns; $parsedQueryData->entityName = $this->resolveEntityName($schema, $table); $selectSql = $this->getSelectQuery($parser, $idColumns); $where = $this->getWhereFragments($parser, $query, $sqlStatement); if (isset($where)) { $selectSql .= " WHERE " . join(' ', $where); } $parsedQueryData->sqlQuery = $selectSql; $parsedQueryData->ids = $database->get_results($selectSql, ARRAY_N); $parsedQueryData->data = $this->getColumnDataToSet($sqlStatement); return $parsedQueryData; }
/** * Saves all already existing meta and M:N references for an entity that wasn't tracked yet * * @param array $data * @param string $entityName */ private function storeRelatedEntities($data, $entityName) { $id = $data[$this->dbSchemaInfo->getEntityInfo($entityName)->idColumnName]; foreach ($this->dbSchemaInfo->getAllEntityNames() as $referencedEntityName) { $entityInfo = $this->dbSchemaInfo->getEntityInfo($referencedEntityName); if ($this->dbSchemaInfo->isChildEntity($referencedEntityName) && $entityInfo->references[$entityInfo->parentReference] === $entityName) { $childEntities = $this->database->get_results("SELECT * FROM {$this->dbSchemaInfo->getPrefixedTableName($referencedEntityName)} WHERE `{$entityInfo->parentReference}` = '{$id}'", ARRAY_A); foreach ($childEntities as $childEntity) { $childEntity = $this->vpidRepository->replaceForeignKeysWithReferences($referencedEntityName, $childEntity); if (!$this->mirror->shouldBeSaved($referencedEntityName, $childEntity)) { continue; } $id = $childEntity[$entityInfo->idColumnName]; $vpid = $this->vpidRepository->getVpidForEntity($referencedEntityName, $id); if ($vpid) { $childEntity[$entityInfo->vpidColumnName] = $vpid; } else { $childEntity = $this->vpidRepository->identifyEntity($referencedEntityName, $childEntity, $childEntity[$entityInfo->idColumnName]); } $childEntity = $this->shortcodesReplacer->replaceShortcodesInEntity($referencedEntityName, $childEntity); $this->mirror->save($referencedEntityName, $childEntity); } } } foreach ($this->dbSchemaInfo->getAllMnReferences() as $mnReferenceDetails) { if ($mnReferenceDetails['source-entity'] === $entityName) { $junctionTable = $mnReferenceDetails['junction-table']; $prefixedJunctionTable = $this->dbSchemaInfo->getPrefixedTableName($junctionTable); $sourceColumn = $mnReferenceDetails['source-column']; $references = $this->database->get_results("SELECT * FROM `{$prefixedJunctionTable}` WHERE `{$sourceColumn}` = '{$id}'", ARRAY_A); foreach ($references as $reference) { $reference = $this->vpidRepository->replaceForeignKeysWithReferences($junctionTable, $reference); $this->mirror->save($junctionTable, $reference); } } } }
private function saveId($entityName, $id, $vpId) { $tableName = $this->schemaInfo->getTableName($entityName); $query = "INSERT INTO {$this->database->vp_id} (`vp_id`, `table`, `id`)\n VALUES (UNHEX('{$vpId}'), \"{$tableName}\", {$id})"; $this->database->query($query); }
/** * Function used by Synchronizer - see `schema.yml`. It restores the `wp_term_taxonomy.count` column after sync. * * @param Database $database */ function vp_fix_posts_count($database) { $sql = "update {$database->term_taxonomy} tt set tt.count =\n (select count(*) from {$database->term_relationships} tr where tr.term_taxonomy_id = tt.term_taxonomy_id);"; $database->query($sql); }
/** * @param $vpids * @param Database $database * @return mixed */ private static function getIdsForVpids($vpids, $database) { $vpidsForRestriction = self::joinVpidsForRestriction($vpids); return $database->get_col("SELECT id FROM {$database->vp_id} WHERE vp_id IN ({$vpidsForRestriction})"); }