public function testAdd() { global $testHelpers, $mockPosts; $testHelpers->writeAppsettings(['keepDefaultContent' => true], 'yaml'); $yaml = new Yaml(); \WP_Mock::wpFunction('get_post', ['times' => '1', 'return' => (object) $mockPosts['testpost1']]); \WP_Mock::wpFunction('get_posts', ['times' => '1', 'return' => [(object) $mockPosts['testpost1']]]); $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $cli = $app['cli']; $p = new Commands\Posts(); $p->add(array(10), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['posts']['post'])); $this->assertEquals(1, count($settings['content']['posts']['post'])); $this->assertEquals('testpost1', $settings['content']['posts']['post'][0]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $p->add(array('testpost1'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['posts']['post'])); $this->assertEquals(1, count($settings['content']['posts']['post'])); $this->assertEquals('testpost1', $settings['content']['posts']['post'][0]); \WP_Mock::wpFunction('get_posts', ['times' => '1', 'return' => false]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $p->add(array('testpost1'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertFalse(isset($settings['content']['posts']['post'])); }
/** * Import settings via WP-CFM */ public function import() { $app = Bootstrap::getApplication(); $helpers = $app['helpers']; $baseUrl = get_option('siteurl'); $src = WPBOOT_BASEPATH . '/bootstrap/config/wpbootstrap.json'; $trg = $app['path'] . '/wp-content/config/wpbootstrap.json'; if (file_exists($src)) { @mkdir(dirname($trg), 0777, true); copy($src, $trg); // deneutralize $settings = json_decode(file_get_contents($trg)); $helpers->fieldSearchReplace($settings, Bootstrap::NEUTRALURL, $baseUrl); file_put_contents($trg, $helpers->prettyPrint(json_encode($settings))); if (function_exists('WPCFM')) { WPCFM()->readwrite->pull_bundle('wpbootstrap'); } else { $cli = $app['cli']; $cli->warning('Plugin WP-CFM does not seem to be installed. No options imported.'); $cli->warning('Add the WP-CFM plugin directly to this install using:'); $cli->warning('$ wp plugin install wp-cfm --activate'); $cli->warning(''); $cli->warning('...or to your appsettings using:'); $cli->warning('$ wp bootstrap add plugin wp-cfm'); $cli->warning('$ wp bootstrap setup'); return; } // Flush options to make sure no other code overwrites based // on old settings stored in cache wp_cache_flush(); } }
public function testAdd() { global $testHelpers, $mockTerms; $testHelpers->writeAppsettings(['keepDefaultContent' => true], 'yaml'); $yaml = new Yaml(); \WP_Mock::wpFunction('get_term_by', ['times' => '2', 'return' => (object) $mockTerms['catTerm1']]); $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $t = new Commands\Taxonomies(); $t->add(array('category', 21), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['taxonomies']['category'])); $this->assertEquals(1, count($settings['content']['taxonomies']['category'])); $this->assertEquals('catTerm1', $settings['content']['taxonomies']['category'][0]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $t->add(array('category', 'catTerm1'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['taxonomies']['category'])); $this->assertEquals(1, count($settings['content']['taxonomies']['category'])); $this->assertEquals('catTerm1', $settings['content']['taxonomies']['category'][0]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $t->add(array('category', '*'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['taxonomies']['category'])); $this->assertEquals(1, count($settings['content']['taxonomies']['category'])); $this->assertEquals('*', $settings['content']['taxonomies']['category'][0]); \WP_Mock::wpFunction('get_term_by', ['times' => '1', 'return' => false]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $t->add(array('category', 'yadayada'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertFalse(isset($settings['content']['taxonomies']['category'])); }
/** * Add a post to be managed by WP Bootstrap * * <taxonomy> * :The name of the taxonomy * * <term_identifier>... * :One or more term slugs or term id's to be added * * [--post_type=<post-type>] * :When adding a posts by post name, limit the post search * to single post-type. * * @param $args * @param $assocArgs */ public function add($args, $assocArgs) { $this->args = $args; $this->assocArgs = $assocArgs; $app = Bootstrap::getApplication(); $cli = $app['cli']; $taxonomy = array_shift($args); foreach ($args as $termIdentifier) { $slug = false; if ($termIdentifier != '*') { if (is_numeric($termIdentifier)) { $term = get_term_by('id', $termIdentifier, $taxonomy); } else { $term = get_term_by('slug', $termIdentifier, $taxonomy); } if ($term) { $slug = $term->slug; } } else { $slug = $termIdentifier; } if ($slug) { $this->updateSettings(array('content', 'taxonomies', $taxonomy, $slug)); } else { $cli->warning("Term {$termIdentifier} not found"); return; } } $this->writeAppsettings(); }
/** * Identifies links to images/attachments on WordPress installation * * @param \stdClass $obj * @return array */ private function findMediaFromObj($obj) { $ret = array(); $app = Bootstrap::getApplication(); $helpers = $app['helpers']; $b64 = $helpers->isBase64($obj); if ($b64) { $obj = base64_decode($obj); } $ser = $helpers->isSerialized($obj); if ($ser) { $obj = unserialize($obj); } if (is_object($obj) || is_array($obj)) { foreach ($obj as $key => &$member) { $arr = $this->findMediaFromObj($member); $ret = array_merge($ret, $arr); } } else { if (is_string($obj)) { $base = rtrim($this->uploadDir['baseurl'], '/') . '/'; $pattern = '~(' . preg_quote($base, '~') . '[^.]+.\\w\\w\\w\\w?)~i'; preg_match_all($pattern, $obj, $matches); if (isset($matches[0]) && is_array($matches[0])) { $ret = array_merge($ret, $matches[0]); } } } return array_unique($ret); }
public function testAdd() { global $testHelpers, $mockTerms; $testHelpers->writeAppsettings(['keepDefaultContent' => true], 'yaml'); $yaml = new Yaml(); $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $m = new Commands\Menus(); $cli = $app['cli']; $cli->launch_self_return = (object) ['return_code' => 0, 'stdout' => json_encode([(object) ['term_id' => 1, 'name' => 'Main menu', 'slug' => 'main', 'locations' => ['primary', 'footer'], 'count' => 2]])]; $m->add(array('main'), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['menus'])); $this->assertEquals(1, count($settings['content']['menus'])); $this->assertEquals('main', $settings['content']['menus'][0]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $m->add(array(1), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertTrue(isset($settings['content']['menus'])); $this->assertEquals(1, count($settings['content']['menus'])); $this->assertEquals('main', $settings['content']['menus'][0]); file_put_contents(WPBOOT_BASEPATH . '/appsettings.yml', "foobar: true\n"); $m->add(array(999), array()); $settings = $yaml->parse(WPBOOT_BASEPATH . '/appsettings.yml'); $this->assertFalse(isset($settings['content']['menus'])); }
/** * The main import process */ private function process() { $app = Bootstrap::getApplication(); $helpers = $app['helpers']; $baseUrl = get_option('siteurl'); $currentSidebars = get_option('sidebars_widgets', array()); foreach ($this->sidebars as $sidebar) { $current = array(); $new = array(); if (isset($currentSidebars[$sidebar->slug])) { $current = $currentSidebars[$sidebar->slug]; } foreach ($current as $key => $widgetRef) { $this->unsetWidget($widgetRef); } foreach ($sidebar->items as $widget) { $currentWidgetDef = get_option('widget_' . $widget->type, array()); $ord = $this->findFirstFree($currentWidgetDef); $helpers->fieldSearchReplace($widget->meta, Bootstrap::NEUTRALURL, $baseUrl); $currentWidgetDef[$ord] = $widget->meta; update_option('widget_' . $widget->type, $currentWidgetDef); $newKey = $widget->type . '-' . $ord; $new[] = $newKey; } $currentSidebars[$sidebar->slug] = $new; update_option('sidebars_widgets', $currentSidebars); } }
public function run($args, $assocArgs) { $app = \Wpbootstrap\Bootstrap::getApplication(); $cli = $app['cli']; $cli->log('Running Bootstrap::reset'); $resp = "y\n"; if (!isset($assocArgs['yes'])) { $cli->line("*************************************************************************************"); $cli->line("**"); $cli->line("** WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! **"); $cli->line("**"); $cli->line("*************************************************************************************"); $cli->line("The WordPress installation located in {$app['path']} will be removed"); $resp = $cli->confirm("Are you sure? Hit Y to go ahead, anything else to cancel"); } if (strtolower($resp) != "y\n") { $cli->line("Aborted"); return; } // Reset the DB $cli->run_command(array('db', 'reset'), array('yes' => 1)); // Remove all files $cmd = 'rm -rf ' . $app['path'] . '/*'; $cli->launch($cmd); }
/** * Add mediaId to the internal array * @param int|array $mediaId */ public function addMedia($mediaId) { $app = Bootstrap::getApplication(); $cli = $app['cli']; if (is_array($mediaId)) { $cli->debug('Including thumbnail media', $mediaId); $this->mediaIds = array_merge($this->mediaIds, $mediaId); } else { $cli->debug('Including thumbnail media', array($mediaId)); $this->mediaIds[] = $mediaId; } }
/** * Export Menus */ public function export() { $app = Bootstrap::getApplication(); $settings = $app['settings']; if (!isset($settings['content']['menus'])) { return; } $this->readMenus(); $dumper = new Dumper(); remove_all_filters('wp_get_nav_menu_items'); $helpers = $app['helpers']; $exportTaxonomies = $app['exporttaxonomies']; $exportPosts = $app['exportposts']; $baseUrl = get_option('siteurl'); foreach ($settings['content']['menus'] as $menu) { $dir = WPBOOT_BASEPATH . '/bootstrap/menus/' . $menu; array_map('unlink', glob("{$dir}/*")); @mkdir($dir, 0777, true); $menuMeta = array(); $menuMeta['locations'] = array(); if (isset($this->navMenus[$menu])) { $menuMeta['locations'] = $this->navMenus[$menu]->locations; } $file = WPBOOT_BASEPATH . "/bootstrap/menus/{$menu}_manifest"; file_put_contents($file, $dumper->dump($menuMeta, 4)); $menuItems = wp_get_nav_menu_items($menu); foreach ($menuItems as $menuItem) { $obj = get_post($menuItem->ID, ARRAY_A); $obj['post_meta'] = get_post_meta($obj['ID']); switch ($obj['post_meta']['_menu_item_type'][0]) { case 'post_type': $postType = $obj['post_meta']['_menu_item_object'][0]; $postId = $obj['post_meta']['_menu_item_object_id'][0]; $objPost = get_post($postId); $exportPosts->addPost($postType, $objPost->post_name); break; case 'taxonomy': $id = $obj['post_meta']['_menu_item_object_id'][0]; $taxonomy = $obj['post_meta']['_menu_item_object'][0]; $objTerm = get_term($id, $taxonomy); if (!is_wp_error($objTerm)) { $exportTaxonomies->addTerm($taxonomy, $objTerm->slug); } break; } $helpers->fieldSearchReplace($obj, $baseUrl, Bootstrap::NEUTRALURL); $file = $dir . '/' . $menuItem->post_name; file_put_contents($file, $dumper->dump($obj, 4)); } } }
/** * Create and saves manifest file with details about the export */ private function createManifest() { $app = Bootstrap::getApplication(); $settings = $app['settings']; $helpers = $app['helpers']; $manifest = new \stdClass(); $dumper = new Dumper(); $manifest->created = date('Y-m-d H:i:s'); $manifest->boostrapVersion = Bootstrap::VERSION; $manifest->appSettings = $dumper->dump($settings, 2); $manifestFile = WPBOOT_BASEPATH . '/bootstrap/manifest.json'; if (file_exists(dirname($manifestFile))) { file_put_contents($manifestFile, $helpers->prettyPrint(json_encode($manifest))); } }
protected function requireEnv($parameters) { $app = \Wpbootstrap\Bootstrap::getApplication(); $cli = $app['cli']; $dotEnv = new Dotenv(WPBOOT_BASEPATH); try { foreach ($parameters as $parameter) { $dotEnv->required($parameter); } } catch (\Exception $e) { $cli->warning($e->getMessage()); return false; } return true; }
/** * Unless specified otherwise, remove default content from a fresh * WordPress installation */ private function deleteDefaultContent() { $app = \Wpbootstrap\Bootstrap::getApplication(); $cli = $app['cli']; $cli->log('Deleting default posts, comments, themes and plugins'); $app = \Wpbootstrap\Bootstrap::getApplication(); if (!isset($app['settings']['keepDefaultContent']) || $app['settings']['keepDefaultContent'] == false) { $cmd = sprintf('db query "%s %s %s %s"', 'delete from wp_posts;', 'delete from wp_postmeta;', 'delete from wp_comments;', 'delete from wp_commentmeta;'); $ret = $cli->launch_self($cmd, array(), array(), false, true); $cmd = sprintf("rm -rf %s/wp-content/plugins/*", $app['path']); $ret = $cli->launch($cmd); $cmd = sprintf("rm -rf %s/wp-content/themes/*", $app['path']); $ret = $cli->launch($cmd); } }
/** * Add a menu to be managed by WP Bootstrap * * <menu_identifier>... * :One or more menus, identified by their (slug) or term id, to be added * * @param $args * @param $assocArgs */ public function add($args, $assocArgs) { $app = Bootstrap::getApplication(); $cli = $app['cli']; $menus = $this->getJsonList('menu list --format=json', array(), $assocArgs); foreach ($args as $menuIdentifier) { $menu = $this->getMenuSlug($menuIdentifier, $menus); if ($menu) { $this->updateSettings(array('content', 'menus', $menu->slug)); $this->writeAppsettings(); } else { $cli->warning("Menu {$menuIdentifier} not found\n"); } } }
public function run($args, $assocArgs) { $this->app = Bootstrap::getApplication(); $this->cli = $this->app['cli']; $this->cli->log('Running Bootstrap::setup'); $this->checkAlreadyInstalled(); $this->parseInstallables('plugin', 'standard'); $this->parseInstallables('plugin', 'local'); $this->parseInstallables('plugin', 'localcopy'); $this->parseInstallables('theme', 'standard'); $this->parseInstallables('theme', 'local'); $this->parseInstallables('theme', 'localcopy'); $this->resolveInstallOrder(); $this->installAll(); $this->applySettings(); $this->wpContentSymlinks(); }
/** * Process individual menu * * @param $menu */ private function processMenu(&$menu) { $app = Bootstrap::getApplication(); $import = $app['import']; $objMenu = wp_get_nav_menu_object($menu->slug); if (!$objMenu) { wp_create_nav_menu($menu->slug); $objMenu = wp_get_nav_menu_object($menu->slug); } $menuId = $objMenu->term_id; $menu->id = $menuId; $existingMenuItems = wp_get_nav_menu_items($menu->slug); foreach ($existingMenuItems as $existingMenuItem) { wp_delete_post($existingMenuItem->ID, true); } foreach ($menu->items as &$objMenuItem) { $menuItemType = $objMenuItem->menu['post_meta']['_menu_item_type'][0]; $newTarget = 0; switch ($menuItemType) { case 'post_type': $newTarget = $import->findTargetObjectId($objMenuItem->menu['post_meta']['_menu_item_object_id'][0], 'post'); break; case 'taxonomy': $newTarget = $import->findTargetObjectId($objMenuItem->menu['post_meta']['_menu_item_object_id'][0], 'term'); break; } $parentItem = $this->findMenuItem($objMenuItem->menu['post_meta']['_menu_item_menu_item_parent'][0]); $args = array('menu-item-title' => $objMenuItem->menu['post_title'], 'menu-item-position' => $objMenuItem->menu['menu_order'], 'menu-item-description' => $objMenuItem->menu['post_content'], 'menu-item-attr-title' => $objMenuItem->menu['post_title'], 'menu-item-status' => $objMenuItem->menu['post_status'], 'menu-item-type' => $menuItemType, 'menu-item-object' => $objMenuItem->menu['post_meta']['_menu_item_object'][0], 'menu-item-object-id' => $newTarget, 'menu-item-url' => $objMenuItem->menu['post_meta']['_menu_item_url'][0], 'menu-item-parent-id' => $parentItem); $ret = wp_update_nav_menu_item($menuId, 0, $args); $objMenuItem->id = $ret; foreach ($objMenuItem->menu['post_meta'] as $key => $meta) { if (in_array($key, $this->skipped_meta_fields) || substr($key, 0, 1) == '_') { continue; } $val = $meta[0]; update_post_meta($ret, $key, $val); } } }
/** * Add a post to be managed by WP Bootstrap * * <post_identifier>... * :One or more post_name (slug) or post id's to be added * * [--post_type=<post-type>] * :When adding a posts by post name, limit the post search * to single post-type. * * @param $args * @param $assocArgs */ public function add($args, $assocArgs) { $app = Bootstrap::getApplication(); $cli = $app['cli']; foreach ($args as $postIdentifier) { if (is_numeric($postIdentifier)) { $post = get_post($postIdentifier); } else { $post = false; $args = array('name' => $postIdentifier, 'post_type' => 'any'); $posts = get_posts($args); if (is_array($posts)) { $post = reset($posts); } } if ($post) { $this->updateSettings(array('content', 'posts', $post->post_type, $post->post_name)); $this->writeAppsettings(); } else { $cli->warning("Post {$postIdentifier} not found\n"); } } }
/** * Export sidebars */ public function export() { $app = Bootstrap::getApplication(); $settings = $app['settings']; if (!isset($settings['content']['sidebars'])) { return; } $extractMedia = $app['extractmedia']; $exportMedia = $app['exportmedia']; $helpers = $app['helpers']; $baseUrl = get_option('siteurl'); $dumper = new Dumper(); $storedSidebars = get_option('sidebars_widgets', array()); foreach ($settings['content']['sidebars'] as $sidebar) { $dir = WPBOOT_BASEPATH . '/bootstrap/sidebars/' . $sidebar; array_map('unlink', glob("{$dir}/*")); @mkdir($dir, 0777, true); $sidebarDef = array(); if (isset($storedSidebars[$sidebar])) { $sidebarDef = $storedSidebars[$sidebar]; } foreach ($sidebarDef as $key => $widgetRef) { $parts = explode('-', $widgetRef); $ord = end($parts); $name = substr($widgetRef, 0, -1 * strlen('-' . $ord)); $widgetTypeSettings = get_option('widget_' . $name); $widgetSettings = $widgetTypeSettings[$ord]; $ret = $extractMedia->getReferencedMedia($widgetSettings); $exportMedia->addMedia($ret); $file = $dir . '/' . $widgetRef; $helpers->fieldSearchReplace($widgetSettings, $baseUrl, Bootstrap::NEUTRALURL); file_put_contents($file, $dumper->dump($widgetSettings, 4)); } $file = WPBOOT_BASEPATH . "/bootstrap/sidebars/{$sidebar}_manifest"; file_put_contents($file, $dumper->dump($sidebarDef, 4)); } }
/** * @depends testCreate */ public function testCommands() { global $testHelpers; \WP_Mock::wpFunction('get_option', ['args' => ['siteurl'], 'times' => '2+', 'return' => 'http://www.example.com']); \WP_Mock::wpFunction('get_taxonomies', ['times' => '1+', 'return' => ['category' => 'category']]); \WP_Mock::wpFunction('get_option', ['args' => ['sidebars_widgets', []], 'times' => '1+', 'return' => []]); \WP_Mock::wpFunction('get_option', ['args' => ['page_on_front', 0], 'times' => '1+', 'return' => []]); \WP_Mock::wpFunction('wp_upload_dir', ['times' => '1+', 'return' => ['basedir' => '/tmp/import']]); \WP_Mock::wpFunction('wp_cache_flush', ['times' => '1+']); //\WP_Mock::wpFunction('remove_all_actions', ['times' => 1,]); $app = $testHelpers->getAppWithMockCli(); $helpers = $app['helpers']; $helpers->recursiveRemoveDirectory(WPBOOT_BASEPATH . '/bootstrap'); $bootstrap = new Bootstrap(); $bootstrap->install(array(), array()); $bootstrap->reset(array(), array()); $bootstrap->setup(array(), array()); $bootstrap->import(array(), array()); $bootstrap->export(array(), array()); }
/** * Finds all new, modified and removed options between two snapshots * * @param \stdClass $oldState * @param \stdClass $newState * @return array */ private function internalDiff($oldState, $newState) { $added = array(); $modified = array(); $removed = array(); $oldName = $oldState->name; $newName = $newState->name; $app = Bootstrap::getApplication(); $helpers = $app['helpers']; $wpCfmSettings = $helpers->getWPCFMSettings(); foreach ($oldState->options as $name => $value) { if (in_array($name, $this->excludedOptions)) { continue; } if (isset($newState->options[$name])) { if (md5(serialize($value)) != md5(serialize($newState->options[$name]))) { $modified[] = array('state' => 'MOD', 'name' => $name, $oldName => $this->valueToString($value), $newName => $this->valueToString($newState->options[$name]), 'managed' => isset($wpCfmSettings->{$name}) ? 'Yes' : 'No'); } } else { $removed[] = array('state' => 'DEL', 'name' => $name, $oldName => $this->valueToString($value), $newName => null, 'managed' => isset($wpCfmSettings->{$name}) ? 'Yes' : 'No'); } } foreach ($newState->options as $name => $value) { if (in_array($name, $this->excludedOptions)) { continue; } if (!isset($oldState->options[$name])) { $added[] = array('state' => 'NEW', 'name' => $name, $oldName => null, $newName => $this->valueToString($value), 'managed' => isset($wpCfmSettings->{$name}) ? 'Yes' : 'No'); } } return array_merge($added, $modified, $removed); }
public function testFindTargetObjectId() { global $testHelpers; $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $app = Bootstrap::getApplication(); $import = $app['import']; $testHelpers->makePublic($import, 'posts'); $testHelpers->makePublic($import, 'taxonomies'); $import->taxonomies = ['category' => (object) ['terms' => [(object) ['id' => 20, 'term' => ['term_id' => 98]]]]]; $this->assertEquals(20, $import->findTargetObjectId(98, 'term')); $this->assertEquals(0, $import->findTargetObjectId(999, 'term')); $import->posts = [(object) ['id' => 10, 'post' => ['ID' => 12]]]; $this->assertEquals(10, $import->findTargetObjectId(12, 'post')); $this->assertEquals(0, $import->findTargetObjectId(999, 'post')); }
/** * Export the posts */ public function doExport() { global $wpdb; $app = Bootstrap::getApplication(); $cli = $app['cli']; $extractMedia = $app['extractmedia']; $exportMedia = $app['exportmedia']; $exportTaxonomies = $app['exporttaxonomies']; $helpers = $app['helpers']; $baseUrl = get_option('siteurl'); $dumper = new Dumper(); $count = 1; while ($count > 0) { $count = 0; foreach ($this->posts as $postType => &$posts) { foreach ($posts as &$post) { if ($post->done == true) { continue; } $postId = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s", $postType, $post->slug)); $arrPost = get_post($postId, ARRAY_A); if (!$arrPost) { $cli->debug("Post {$postId} not found"); continue; } $cli->debug("Exporting post {$post->slug} ({$postId})"); $meta = get_post_meta($arrPost['ID']); $arrPost['taxonomies'] = array(); // extract media ids // 1. from attached media: $media = get_attached_media('', $postId); foreach ($media as $item) { $exportMedia->addMedia($item->ID); } // 2. from featured image: if (has_post_thumbnail($postId)) { $mediaId = get_post_thumbnail_id($postId); $exportMedia->addMedia($mediaId); } // 3. Is this post actually an attachment? if ($arrPost['post_type'] == 'attachment') { $exportMedia->addMedia($arrPost['ID']); } // 4. referenced in the content $ret = $extractMedia->getReferencedMedia($arrPost); if (count($ret) > 0) { $exportMedia->addMedia($ret); } // 5. referenced in meta data $ret = $extractMedia->getReferencedMedia($meta); if (count($ret) > 0) { $exportMedia->addMedia($ret); } // terms foreach (get_taxonomies() as $taxonomy) { if (in_array($taxonomy, $this->excludedTaxonomies)) { continue; } $terms = wp_get_object_terms($postId, $taxonomy); if (count($terms)) { $cli->debug('Adding ' . count($terms) . " terms from {$taxonomy}"); } foreach ($terms as $objTerm) { // add it to the exported terms $exportTaxonomies->addTerm($taxonomy, $objTerm->slug); if (!isset($arrPost['taxonomies'][$taxonomy])) { $arrPost['taxonomies'][$taxonomy] = array(); } $arrPost['taxonomies'][$taxonomy][] = $objTerm->slug; } } $arrPost['post_meta'] = $meta; $helpers->fieldSearchReplace($arrPost, $baseUrl, Bootstrap::NEUTRALURL); $file = WPBOOT_BASEPATH . "/bootstrap/posts/{$arrPost['post_type']}/{$arrPost['post_name']}"; $cli->debug("Storing {$file}"); @mkdir(dirname($file), 0777, true); file_put_contents($file, $dumper->dump($arrPost, 4)); $post->done = true; ++$count; } } } }
protected function output($output) { $app = Bootstrap::getApplication(); $cliutils = $app['cliutils']; if (count($output) > 0) { $cliutils->format_items($this->getAssocArg('format', 'table'), $output, array_keys($output[0])); } }
/** * Process individual taxonomy * * @param \stdClass $taxonomy */ private function processTaxonomy(&$taxonomy) { $app = Bootstrap::getApplication(); $cli = $app['cli']; $currentTerms = get_terms($taxonomy->slug, array('hide_empty' => false)); $done = false; while (!$done) { $deferred = 0; foreach ($taxonomy->terms as &$term) { if (!$term->done) { $parentId = $this->parentId($term->term['parent'], $taxonomy); $cli->debug("Importing term {$term->term['name']}/{$term->term['slug']} parent: {$parentId}"); if ($parentId || $term->term['parent'] == 0) { $args = array('description' => $term->term['description'], 'parent' => $parentId, 'slug' => $term->term['slug'], 'term_group' => $term->term['term_group'], 'name' => $term->term['name']); switch ($taxonomy->type) { case 'postid': $this->adjustTypePostId($term->term, $args); break; } $existingTermId = $this->findExistingTerm($term, $currentTerms); if ($existingTermId > 0) { wp_update_term($existingTermId, $taxonomy->slug, $args); $term->id = $existingTermId; } else { $id = wp_insert_term($term->term['name'], $taxonomy->slug, $args); $term->id = $id['term_id']; } $term->done = true; } else { ++$deferred; } } if ($deferred == 0) { $done = true; } } } }
private function runExport() { global $testHelpers; $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $helpers = $app['helpers']; $helpers->recursiveRemoveDirectory(WPBOOT_BASEPATH . '/bootstrap'); require_once WPBOOT_BASEPATH . '/www/wordpress-test/wp-load.php'; $export = $app['export']; $export->run([], []); }
/** * Add the term identified by taxonomyName/slug to the internal array * * @param string $taxonomyName * @param string $slug */ public function addTerm($taxonomyName, $slug) { $app = Bootstrap::getApplication(); $cli = $app['cli']; $cli->debug("Adding term {$slug} to Taxonomy {$taxonomyName}"); if (!isset($this->taxonomies->{$taxonomyName})) { $this->taxonomies->{$taxonomyName} = new \stdClass(); $this->taxonomies->{$taxonomyName}->type = 'standard'; $this->taxonomies->{$taxonomyName}->termsDescriptor = 'indirect'; $this->taxonomies->{$taxonomyName}->terms = array(); } foreach ($this->taxonomies->{$taxonomyName}->terms as $term) { if ($term->slug == $slug) { return; } } $newTerm = new \stdClass(); $newTerm->slug = $slug; $newTerm->done = false; array_push($this->taxonomies->{$taxonomyName}->terms, $newTerm); }
/** * Import media file and meta data */ private function importMedia() { $app = Bootstrap::getApplication(); $cli = $app['cli']; $uploadDir = wp_upload_dir(); $yaml = new Yaml(); // check all the media. foreach (glob(WPBOOT_BASEPATH . '/bootstrap/media/*') as $dir) { $item = $yaml->parse(file_get_contents("{$dir}/meta")); // does this image have an imported post as it's parent? $parentId = $this->parentId($item['post_parent'], $this->posts); if ($parentId != 0) { $cli->debug("Media is attached to post {$item['ID']} {$parentId}"); } // does an imported post have this image as thumbnail? $isAThumbnail = $this->isAThumbnail($item['ID']); if ($isAThumbnail) { $cli->debug('Media is thumbnail to (at least) one post ' . $item['ID']); } $args = array('name' => $item['post_name'], 'post_type' => $item['post_type']); $file = $item['post_meta']['_wp_attached_file'][0]; $existing = new \WP_Query($args); if (!$existing->have_posts()) { $args = array('post_title' => $item['post_title'], 'post_name' => $item['post_name'], 'post_type' => $item['post_type'], 'post_parent' => $parentId, 'post_status' => $item['post_status'], 'post_mime_type' => $item['post_mime_type'], 'guid' => $uploadDir['basedir'] . '/' . $file); $id = wp_insert_post($args); } else { $id = $existing->post->ID; } update_post_meta($id, '_wp_attached_file', $file); // move the file $src = $dir . '/' . basename($file); $trg = $uploadDir['basedir'] . '/' . $file; @mkdir($uploadDir['basedir'] . '/' . dirname($file), 0777, true); if (file_exists($src) && file_exists($trg)) { if (filesize($src) == filesize($trg)) { // set this image as a thumbnail and then exit if ($isAThumbnail) { $this->setAsThumbnail($item->ID, $id); } continue; } } if (file_exists($src)) { copy($src, $trg); // create metadata and other sizes $attachData = wp_generate_attachment_metadata($id, $trg); wp_update_attachment_metadata($id, $attachData); } // set this image as a thumbnail if needed if ($isAThumbnail) { $this->setAsThumbnail($item['ID'], $id); } } }
public function testShow() { global $testHelpers; $app = $testHelpers->getAppWithMockCli(); Bootstrap::setApplication($app); $snapper = new OptionSnap(); $snapper->show(['snapWrong'], []); $cli = $app['cli']; $this->assertTrue(count($cli->error) == 1); $snapper->show(['snap1'], []); $utils = $app['cliutils']; $this->assertTrue(count($utils->output) == 2); $this->assertTrue($utils->output[0]['name'] == 'opta'); $snapper->show(['snap1', 'optb'], []); $snapper->show(['snap1', 'optb'], []); $cli = $app['cli']; $this->assertTrue(count($cli->line) == 2); }
/** * Runs after all import is done. Resolves options fields that * are references to posts or terms */ private function resolveOptionReferences() { $app = Bootstrap::getApplication(); $resolver = $app['resolver']; $settings = $app['settings']; $options = []; if (isset($settings['references']['posts']['options'])) { $options = $settings['references']['posts']['options']; } // Ask any extensions to add option references via filter $options = apply_filters('wp-bootstrap_option_post_references', $options); if (is_array($options)) { foreach ($options as $value) { if (is_string($value)) { $this->optionPostReferenceNames[] = $value; } elseif (is_object($value)) { $arr = (array) $value; $key = key($arr); $this->optionPostReferenceNames[$key] = $arr[$key]; } elseif (is_array($value)) { $key = key($value); $this->optionPostReferenceNames[$key] = $value[$key]; } } } $resolver->resolveOptionReferences($this->optionPostReferenceNames, 'post'); $options = []; if (isset($settings['references']['terms']['options'])) { $options = $settings['references']['terms']['options']; } // Ask any extensions to add option references via filter $options = apply_filters('wp-bootstrap_option_term_references', $options); if (is_array($options)) { foreach ($options as $value) { if (is_string($value)) { $this->optionTermReferenceNames[] = $value; } elseif (is_object($value)) { $arr = (array) $value; $key = key($arr); $this->optionTermReferenceNames[$key] = $arr[$key]; } elseif (is_array($value)) { $key = key($value); $this->optionTermReferenceNames[$key] = $value[$key]; } } } $resolver->resolveOptionReferences($this->optionTermReferenceNames, 'term'); }