/** * Hook for add_filter('locale ', ...), change the user interface language * * @param string $lang * * @return string */ function set_locale($lang) { // Cheap cache static $loc = '__UNSET__'; if (is_admin()) { // go with the user setting // get_current_user_id uses wp_get_current_user which may not be available the first time(s) get_locale is called if ('__UNSET__' == $loc && function_exists('wp_get_current_user')) { $loc = get_user_option('user_interface_lang'); } } elseif ($GLOBALS['pagenow'] == 'wp-signup.php') { // use global setting $loc = get_site_option('WPLANG'); } else { // go with the book info setting $metadata = \PressBooks\Book::getBookInformation(); if ('__UNSET__' == $loc && !empty($metadata['pb_language'])) { $locations = \PressBooks\L10n\wplang_codes(); $loc = $locations[$metadata['pb_language']]; } } // Return if ('__UNSET__' == $loc) { return $lang; } else { return $loc ? $loc : $lang; } }
/** * Imports user selected chapters from an instance of PB * * @param array $chapters * Array( [5] => Array( [222] => chapter ) [14] => Array( [164] => front-matter ) ) * @return type */ function import(array $chapters) { $this->chapters = $chapters; $chapters_to_import = $this->getChapters(); libxml_use_internal_errors(true); foreach ($chapters_to_import as $new_post) { // Load HTMl snippet into DOMDocument using UTF-8 hack $utf8_hack = '<?xml version="1.0" encoding="UTF-8"?>'; $doc = new \DOMDocument(); $doc->loadHTML($utf8_hack . $new_post['post_content']); // Download images, change image paths $doc = $this->scrapeAndKneadImages($doc); $html = $doc->saveXML($doc->documentElement); // Remove auto-created <html> <body> and <!DOCTYPE> tags. $html = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace(array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $html)); $import_post = array('post_title' => $new_post['post_title'], 'post_content' => $html, 'post_type' => $new_post['post_type'], 'post_status' => $new_post['post_status']); // set post parent if ('chapter' == $new_post['post_type']) { $post_parent = $this->getChapterParent(); $import_post['post_parent'] = $post_parent; } // woot, woot! $pid = wp_insert_post($import_post); // check for errors, redirect and record if (is_wp_error($pid)) { error_log('\\PBT\\Import\\PBImport()->import error at `wp_insert_post()`: ' . $pid->get_error_message()); \PBT\Search\ApiSearch::revokeCurrentImport(); \Pressbooks\Redirect\location(get_bloginfo('url') . '/wp-admin/admin.php?page=api_search_import'); } // set post metadata $this->setPostMeta($pid, $new_post); \Pressbooks\Book::consolidatePost($pid, get_post($pid)); } return \PBT\Search\ApiSearch::revokeCurrentImport(); }
function thincc_ajax() { $sitename = sanitize_key(get_bloginfo('name')); if (!empty($sitename)) { $sitename .= '.'; } $filename = $sitename . 'wordpress.' . date('Y-m-d'); $options = process_thincc_options($_POST); if (isset($_POST['download']) && $_POST['download'] == '0') { $options['version'] = 'thin'; $options['inline'] = true; $manifest = new \CC\Manifest(\PressBooks\Book::getBookStructure('', true), $options); $manifest->build_manifest(); header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename=' . $filename . '.xml'); header('Content-Type: text/plain; charset=' . get_option('blog_charset'), true); echo '<pre>', htmlentities($manifest), '</pre>'; } else { if (!isset($options['version'])) { $options['version'] = '1.2'; } $manifest = new \CC\Manifest(\PressBooks\Book::getBookStructure('', true), $options); $manifest->build_manifest(); $file = $manifest->build_zip(); header('Content-Type: application/vnd.ims.imsccv1p2+application/zip'); header('Content-Length: ' . filesize($file)); header('Content-Disposition: attachment; filename="' . $filename . '.zip"'); readfile($file); } }
function pbt_get_microdata_meta_elements() { // map items that are already captured $html = ''; $micro_mapping = array('about' => 'pb_bisac_subject', 'alternativeHeadline' => 'pb_subtitle', 'author' => 'pb_author', 'contributor' => 'pb_contributing_authors', 'copyrightHolder' => 'pb_copyright_holder', 'copyrightYear' => 'pb_copyright_year', 'datePublished' => 'pb_publication_date', 'description' => 'pb_about_50', 'editor' => 'pb_editor', 'image' => 'pb_cover_image', 'inLanguage' => 'pb_language', 'keywords' => 'pb_keywords_tags', 'publisher' => 'pb_publisher'); $metadata = \PressBooks\Book::getBookInformation(); // create microdata elements foreach ($micro_mapping as $itemprop => $content) { if (array_key_exists($content, $metadata)) { if ('pb_publication_date' == $content) { $content = date('Y-m-d', $metadata[$content]); } else { $content = $metadata[$content]; } $html .= "<meta itemprop='" . $itemprop . "' content='" . $content . "' id='" . $itemprop . "'>\n"; } } // add elements that aren't captured, and don't need user input $pb_bisac_subject = ''; // Pressbooks Metadata: fixes the undefined index pb_bisac_subject notice if (isset($metadata['pb_bisac_subject'])) { $pb_bisac_subject = $metadata['pb_bisac_subject']; } $lrmi_meta = array('educationalAlignment' => $pb_bisac_subject, 'educationalUse' => 'Open textbook study', 'audience' => 'student', 'interactivityType' => 'mixed', 'learningResourceType' => 'textbook', 'typicalAgeRange' => '17-'); foreach ($lrmi_meta as $itemprop => $content) { // @todo parse educationalAlignment items into alignmentOjects $html .= "<meta itemprop='" . $itemprop . "' content='" . $content . "' id='" . $itemprop . "'>\n"; } return $html; }
/** * Displays a Book widget */ function display_book_widget() { $book_structure = \PressBooks\Book::getBookStructure(); // front-matter echo "<ul><li><h4>" . __('Front Matter', 'pressbooks') . "</h4></li><ul>"; foreach ($book_structure['front-matter'] as $fm) { $title = !empty($fm['post_title']) ? $fm['post_title'] : '…'; echo "<li class='front-matter'><a href='post.php?post=" . $fm['ID'] . "&action=edit'>" . $title . "</a></li>\n"; } echo "</ul>"; // parts foreach ($book_structure['part'] as $part) { $title = !empty($part['post_title']) ? $part['post_title'] : '…'; echo "<ul><li><h4><a href='post.php?post=" . $part['ID'] . "&action=edit'>" . $title . "</a></h4></li><ul>\n"; // chapters foreach ($part['chapters'] as $chapter) { $title = !empty($chapter['post_title']) ? $chapter['post_title'] : '…'; echo "<li class='chapter'><a href='post.php?post=" . $chapter['ID'] . "&action=edit'>" . $title . "</a></li>\n"; } echo "</ul>\n"; } // back-matter echo "<li><h4>" . __('Back Matter', 'pressbooks') . "</h4></li><ul>"; foreach ($book_structure['back-matter'] as $bm) { $title = !empty($bm['post_title']) ? $bm['post_title'] : '…'; echo "<li class='back-matter'><a href='post.php?post=" . $bm['ID'] . "&action=edit'>" . $title . "</a></li>\n"; } echo "</ul>"; // add, organize echo "</ul>\n"; echo '<div class="part-buttons"><a href="post-new.php?post_type=chapter">' . __('Add', 'pressbooks') . '</a> | <a class="remove" href="admin.php?page=pressbooks">' . __('Organize', 'pressbooks') . '</a></div>'; }
/** * Delete 'pressbooks_current_import' option, delete the file too. * * @return bool */ function revokeCurrentImport() { $current_import = get_option('pressbooks_current_import'); if (is_array($current_import) && isset($current_import['file']) && is_file($current_import['file'])) { unlink($current_import['file']); } \Pressbooks\Book::deleteBookObjectCache(); delete_transient('dirsize_cache'); /** @see get_dirsize() */ return delete_option('pressbooks_current_import'); }
/** * @param array $current_import */ function import(array $current_import) { try { $imscc = new IMSCCParser($current_import['file']); } catch (\Exception $e) { return FALSE; } $items = $imscc->manifestGetItems(); $match_ids = array_flip(array_keys($current_import['chapters'])); $total = 0; if (!empty($items)) { $current_post_parent = -1; foreach ($items as $id => $item) { // Skip if (!$this->flaggedForImport($id)) { continue; } if (!isset($match_ids[$id])) { continue; } $post_type = $this->determinePostType($id); $new_post = array('post_title' => wp_strip_all_tags($item['title']), 'post_type' => $post_type, 'post_status' => 'part' == $post_type ? 'publish' : 'draft'); if ('part' != $post_type) { $new_post['post_content'] = $imscc->getContent($id); } if ('chapter' == $post_type) { if ($current_post_parent == -1) { $new_post['post_parent'] = $this->getChapterParent(); } else { $new_post['post_parent'] = $current_post_parent; } } $pid = wp_insert_post(add_magic_quotes($new_post)); //store part post ID to use as parent for subsequent chapters if ('part' == $post_type) { $current_post_parent = $pid; } // @todo postmeta like author update_post_meta($pid, 'pb_show_title', 'on'); update_post_meta($pid, 'pb_export', 'on'); if ('part' == $post_type && $imscc->getContent($id)) { update_post_meta($pid, 'pb_part_content', $imscc->getContent($id)); } Book::consolidatePost($pid, get_post($pid)); ++$total; } } // Done $_SESSION['pb_notices'][] = sprintf(__('Imported %d chapters.', 'pressbooks'), $total); $imscc->cleanUp(); return $this->revokeCurrentImport(); }
/** * Adds and Removes some admin buttons * * @since 1.0.1 */ function adminMenuAdjuster() { if ( \Pressbooks\Book::isBook() ) { add_menu_page( __( 'Import', $this->plugin_slug ), __( 'Import', $this->plugin_slug ), 'edit_posts', 'pb_import', '\PressBooks\Admin\Laf\display_import', '', 15 ); add_options_page( __( 'PressBooks Textbook Settings', $this->plugin_slug ), __( 'PB Textbook', $this->plugin_slug ), 'manage_options', $this->plugin_slug . '-settings', array( $this, 'displayPluginAdminPage' ) ); add_menu_page( __( 'PressBooks Textbook', $this->plugin_slug ), __( 'PB Textbook', $this->plugin_slug ), 'edit_posts', $this->plugin_slug , array( $this, 'displayPBTPage' ), '', 64 ); // check if the functionality we need is available if ( class_exists('\PressBooks\Api_v1\Api') ){ add_submenu_page( $this->plugin_slug, __('Search and Import', $this->plugin_slug), __('Search and Import', $this->plugin_slug), 'edit_posts', 'api_search_import',array( $this, 'displayApiSearchPage' ), '', 65 ); } add_submenu_page( $this->plugin_slug, __('Download Textbooks', $this->plugin_slug), __('Download Textbooks', $this->plugin_slug), 'edit_posts', 'download_textbooks',array( $this, 'displayDownloadTextbooks' ), '', 66 ); add_menu_page( 'Plugins', 'Plugins', 'manage_network_plugins', 'plugins.php', '', 'dashicons-admin-plugins', 67 ); remove_menu_page( 'pb_sell' ); } }
/** * Register theme directories, set a filter that hides themes under certain conditions */ function registerThemeDirectories() { // No trailing slash, otherwise we get a double slash bug // @see \PressBooks\Metadata::fixDoubleSlashBug register_theme_directory(PB_PLUGIN_DIR . 'themes-root'); register_theme_directory(PB_PLUGIN_DIR . 'themes-book'); if (is_admin()) { if (Book::isBook()) { add_filter('allowed_themes', array($this, 'allowedBookThemes')); } else { add_filter('allowed_themes', array($this, 'allowedRootThemes')); } } }
function add_theme($themes) { $merge_themes = array(); if (\Pressbooks\Book::isBook()) { $registered_themes = search_theme_directories(); foreach ($registered_themes as $key => $val) { if ($val['theme_root'] == __DIR__ . '/themes') { $merge_themes[$key] = 1; } } // add our theme $themes = array_merge($themes, $merge_themes); } return $themes; }
/** * Add the plugin's specific themes to the PressBooks theme filter. * Inspirated from Textbook's one. * * @since 0.1 * @param array $themes The currently allowed themes in PressBooks * @return array The array from the input, with the plugin's themes */ public function add_themes_to_filter($themes) { $pbt_themes = array(); if (\Pressbooks\Book::isBook()) { $registered_themes = search_theme_directories(); foreach ($registered_themes as $key => $val) { if ($val['theme_root'] == plugin_dir_path(dirname(__FILE__)) . 'themes') { $pbt_themes[$key] = 1; } } // add our theme to the whitelist $themes = array_merge($themes, $pbt_themes); return $themes; } else { return $themes; } }
function hide_menus() { global $wpdb; $user = wp_get_current_user(); $restricted = $wpdb->get_results('SELECT * FROM wp_sitemeta WHERE meta_key = "pressbooks_network_managers"'); if ($restricted) { $restricted = maybe_unserialize($restricted[0]->meta_value); } else { $restricted = array(); } if (in_array($user->ID, $restricted) && !\PressBooks\Book::isBook()) { remove_menu_page("themes.php"); remove_menu_page("plugins.php"); remove_menu_page("settings.php"); remove_menu_page("update-core.php"); remove_menu_page("admin.php?page=pb_stats"); } }
/** * Adds and Removes some admin buttons * * @since 1.0.1 */ function adminMenuAdjuster() { if (\Pressbooks\Book::isBook()) { add_menu_page(__('Import', $this->plugin_slug), __('Import', $this->plugin_slug), 'edit_posts', 'pb_import', '\\Pressbooks\\Admin\\Laf\\display_import', 'dashicons-upload', 15); add_options_page(__('Pressbooks Textbook Settings', $this->plugin_slug), __('PB Textbook', $this->plugin_slug), 'manage_options', $this->plugin_slug . '-settings', array($this, 'displayPluginAdminPage')); add_menu_page(__('Pressbooks Textbook', $this->plugin_slug), __('PB Textbook', $this->plugin_slug), 'edit_posts', $this->plugin_slug, array($this, 'displayPBTPage'), 'dashicons-tablet', 64); // check if the functionality we need is available if (class_exists('\\Pressbooks\\Modules\\Api_v1\\Api')) { add_submenu_page($this->plugin_slug, __('Search and Import', $this->plugin_slug), __('Search and Import', $this->plugin_slug), 'edit_posts', 'api_search_import', array($this, 'displayApiSearchPage'), '', 65); } add_submenu_page($this->plugin_slug, __('Download Textbooks', $this->plugin_slug), __('Download Textbooks', $this->plugin_slug), 'edit_posts', 'download_textbooks', array($this, 'displayDownloadTextbooks'), '', 66); if (version_compare(PB_PLUGIN_VERSION, '2.7') >= 0) { remove_menu_page('pb_publish'); } else { remove_menu_page('pb_sell'); } } }
function pbt_get_microdata_meta_elements() { // map items that are already captured $html = ''; $micro_mapping = array('about' => 'pb_bisac_subject', 'alternativeHeadline' => 'pb_subtitle', 'author' => 'pb_author', 'contributor' => 'pb_contributing_authors', 'copyrightHolder' => 'pb_copyright_holder', 'copyrightYear' => 'pb_copyright_year', 'datePublished' => 'pb_publication_date', 'description' => 'pb_about_50', 'editor' => 'pb_editor', 'image' => 'pb_cover_image', 'inLanguage' => 'pb_language', 'keywords' => 'pb_keywords_tags', 'publisher' => 'pb_publisher'); $metadata = \PressBooks\Book::getBookInformation(); // create microdata elements foreach ($micro_mapping as $itemprop => $content) { if (array_key_exists($content, $metadata)) { if ('pb_publication_date' == $content) { $content = date('Y-m-d', $metadata[$content]); } else { $content = $metadata[$content]; } $html .= "<meta itemprop='" . $itemprop . "' content='" . $content . "' id='" . $itemprop . "'>\n"; } } return $html; }
/** * Create $this->outputPath * * @return bool */ function convert() { // Create ICML $vars = array('meta' => \PressBooks\Book::getBookInformation(), 'book_contents' => $this->preProcessBookContents(\PressBooks\Book::getBookContents())); $cc_copyright = strip_tags($this->doCopyrightLicense($vars['meta'])); $vars['do_copyright_license'] = $cc_copyright; $book_html = $this->loadTemplate(__DIR__ . '/templates/xhtml.php', $vars); $content = $this->transformXML($book_html, PB_PLUGIN_DIR . 'symbionts/icml/tkbr2icml-v044.xsl'); // Save ICML as file in exports folder $filename = $this->timestampedFileName('.icml'); file_put_contents($filename, $content); $this->outputPath = $filename; if (!filesize($this->outputPath)) { $this->logError($this->bookHtmlError($book_html)); unlink($this->outputPath); return false; } return true; }
/** * Pummel then insert HTML into our database * * @param string $href * @param string $post_type * @param int $chapter_parent * @param string $domain domain name of the webpage */ function kneadandInsert($html, $post_type, $chapter_parent, $domain) { $matches = array(); $meta = $this->getLicenseAttribution($html); $author = isset($meta['authors']) ? $meta['authors'] : $this->getAuthors($html); $license = isset($meta['license']) ? $this->extractCCLicense($meta['license']) : ''; // get the title, preference to title set by PB preg_match('/<h2 class="entry-title">(.*)<\\/h2>/', $html, $matches); if (!empty($matches[1])) { $title = wp_strip_all_tags($matches[1]); } else { preg_match('/<title>(.+)<\\/title>/', $html, $matches); $title = !empty($matches[1]) ? wp_strip_all_tags($matches[1]) : '__UNKNOWN__'; } // just get the body preg_match('/(?:<body[^>]*>)(.*)<\\/body>/isU', $html, $matches); // get rid of stuff we don't need $body = $this->regexSearchReplace($matches[1]); // clean it up $xhtml = $this->tidy($body); $body = $this->kneadHtml($xhtml, $post_type, $domain); $new_post = array('post_title' => $title, 'post_content' => $body, 'post_type' => $post_type, 'post_status' => 'draft'); if ('chapter' == $post_type) { $new_post['post_parent'] = $chapter_parent; } $pid = wp_insert_post(add_magic_quotes($new_post)); if (!empty($author)) { update_post_meta($pid, 'pb_section_author', $author); } if (!empty($license)) { update_post_meta($pid, 'pb_section_license', $license); } update_post_meta($pid, 'pb_show_title', 'on'); update_post_meta($pid, 'pb_export', 'on'); Book::consolidatePost($pid, get_post($pid)); // Reorder }
/** * Fetch next or previous Pressbooks post ID * This is taken from PB's inner code to find the next page * * @param string $what prev, next * * @return ID of requested post */ function get_pb_page_id($what = 'next') { global $blog_id; global $post; $current_post_id = $post->ID; $book_structure = \PressBooks\Book::getBookStructure(); $order = $book_structure['__order']; $pos = array_keys($order); $what = $what == 'next' ? 'next' : 'prev'; // Move internal pointer to correct position reset($pos); while ($find_me = current($pos)) { if ($find_me == $current_post_id) { break; } else { next($pos); } } // Get next/previous $what($pos); while ($post_id = current($pos)) { if ($order[$post_id]['post_status'] == 'publish') { break; } elseif (current_user_can_for_blog($blog_id, 'read')) { break; } else { $what($pos); } } return $post_id; }
/** * Expose public information about a book * * @param array $args * @return array of book information */ protected function getBooksById(array $args) { $book = array(); if (empty($args['id'])) { foreach ($this->public_books as $book_id) { @$book[$book_id]; $book[$book_id]['book_id'] = $book_id; $book[$book_id]['book_url'] = get_blogaddress_by_id($book_id); $book[$book_id]['book_meta'] = \PressBooks\Book::getBookInformation(intval($book_id)); $book_structure = \PressBooks\Book::getBookStructure(intval($book_id)); $book[$book_id]['book_toc'] = $this->getToc($book_structure, $book_id); } } else { // check if blog_id is in the collection if (!in_array($args['id'], $this->public_books)) { return $this->apiErrors('empty'); } $book[$args['id']]['book_id'] = $args['id']; $book[$args['id']]['book_url'] = get_blogaddress_by_id($args['id']); $book[$args['id']]['book_meta'] = \PressBooks\Book::getBookInformation(intval($args['id'])); $book_structure = \PressBooks\Book::getBookStructure(intval($args['id'])); $book[$args['id']]['book_toc'] = $this->getToc($book_structure, $args['id']); } return $book; }
/** * Try to determine if a URL is pointing to internal content. * * @param $url * @param string $type front-matter, part, chapter, back-matter, ... * @param int $pos (optional) position of content, used when creating filenames like: chapter-001, chapter-002, ... * * @return bool|string */ protected function fuzzyHrefMatch($url, $type, $pos) { if (!$pos) { return false; } $url = trim($url); $url = rtrim($url, '/'); $last_part = explode('/', $url); $last_pos = count($last_part) - 1; $anchor = ''; // Look for #anchors if ($last_pos > 0 && '#' == substr(trim($last_part[$last_pos]), 0, 1)) { $anchor = trim($last_part[$last_pos]); $last_part = trim($last_part[$last_pos - 1]); } elseif (false !== strpos($last_part[$last_pos], '#')) { list($last_part, $anchor) = explode('#', $last_part[$last_pos]); $anchor = trim("#{$anchor}"); $last_part = trim($last_part); } else { $last_part = trim($last_part[$last_pos]); } if (!$last_part) { return false; } $lookup = \PressBooks\Book::getBookStructure(); $lookup = $lookup['__export_lookup']; if (!isset($lookup[$last_part])) { return false; } $domain = parse_url($url); $domain = @$domain['host']; if ($domain) { $domain2 = parse_url(wp_guess_url()); if ($domain != @$domain2['host']) { return false; } } // Seems legit... $new_type = $lookup[$last_part]; $new_pos = 0; foreach ($lookup as $p => $t) { if ($t == $new_type) { ++$new_pos; } if ($p == $last_part) { break; } } $new_url = "{$new_type}-" . sprintf("%03s", $new_pos) . "-{$last_part}.{$this->filext}"; if ($anchor) { $new_url .= $anchor; } return $new_url; }
/** * WP Hook for action 'wp_update_attachment_metadata'. Deal with user editing cover image from Media Library. */ function save_attachment($data, $post_id) { if (empty($data['file'])) { return $data; } // Bail $post = get_post($post_id); $meta_post = (new \PressBooks\Metadata())->getMetaPost(); // PHP 5.4+ $upload_dir = wp_upload_dir(); $url = untrailingslashit($upload_dir['baseurl']) . "/{$data['file']}"; if ($meta_post && $post && $post->post_parent == $meta_post->ID) { // Update pb_cover_image to point to edited file update_post_meta($meta_post->ID, 'pb_cover_image', $url); \PressBooks\Book::deleteBookObjectCache(); } elseif ($post && strpos($post->post_name, 'pb-catalog-logo') === 0) { // Update pb_catalog_logo to point to edited file update_user_meta($post->post_author, 'pb_catalog_logo', $url); } return $data; }
/** * Pummel then insert HTML into our database * * @param string $html * @param string $title * @param string $post_type (front-matter', 'chapter', 'back-matter') * @param int $chapter_parent */ protected function kneadAndInsert($html, $title, $post_type, $chapter_parent) { $body = $this->tidy($html); $body = $this->kneadHTML($body); $title = wp_strip_all_tags($title); $new_post = array('post_title' => $title, 'post_content' => $body, 'post_type' => $post_type, 'post_status' => 'draft'); if ('chapter' == $post_type) { $new_post['post_parent'] = $chapter_parent; } $pid = wp_insert_post(add_magic_quotes($new_post)); update_post_meta($pid, 'pb_show_title', 'on'); update_post_meta($pid, 'pb_export', 'on'); Book::consolidatePost($pid, get_post($pid)); // Reorder }
/** * Add Edit CSS menu. */ function add_menu() { if (Book::isBook() && CustomCss::isCustomCss()) { add_theme_page(__('Edit CSS', 'pressbooks'), __('Edit CSS', 'pressbooks'), 'edit_theme_options', 'pb_custom_css', __NAMESPACE__ . '\\display_custom_css'); } }
/** * Put a Part/Chapter/Front Matter/Back Matter in the trash * * @param int $pid * * @return bool */ static function deletePost($pid) { if (false == Book::isBook() || wp_is_post_revision($pid) || 'auto-draft' == get_post_status($pid)) { return false; } /** @var $wpdb \wpdb */ global $wpdb; // remove chapter/part/front matter // decrement order of everything with a higher order, and if chapter, only within that part $post = get_post($pid); $order = $post->menu_order; $type = $post->post_type; $parent = $post->post_parent; $query = "UPDATE {$wpdb->posts} SET menu_order = menu_order - 1 WHERE menu_order > {$order} AND post_type = '{$type}' "; if ('chapter' == $type) { $query .= " AND post_parent = {$parent} "; } $success = $wpdb->query($query); clean_post_cache($post); if ('part' == $type) { // We're setting two things here - the new post_parent (to the first part) // And the new menu order for the chapters that were in the part being deleted. $new_parent_id = $wpdb->get_var("SELECT ID\n\t\t\t\t\t\t\t\t\t\t FROM {$wpdb->posts}\n\t\t\t\t\t\t\t\t\t\tWHERE post_type = 'part'\n\t\t\t\t\t\t\t\t\t\t AND post_status = 'publish'\n\t\t\t\t\t\t\t\t\t\t AND NOT ID = {$pid}\n\t\t\t\t\t\t\t\t\t ORDER BY menu_order\n\t\t\t\t\t\t\t\t\t\tLIMIT 1 "); if ($new_parent_id) { $existing_numposts = $wpdb->get_var("SELECT COUNT(1) AS numposts FROM {$wpdb->posts} WHERE post_type = 'chapter' AND post_parent = {$new_parent_id} "); $query = "UPDATE {$wpdb->posts} SET post_parent = {$new_parent_id}, menu_order = menu_order + {$existing_numposts} WHERE post_parent = {$pid} AND post_type = 'chapter' "; $success = $wpdb->query($query); } else { $query = "UPDATE {$wpdb->posts} SET post_status = 'trash' WHERE post_parent = {$pid} AND post_type = 'chapter' "; $success = $wpdb->query($query); } wp_cache_flush(); } static::deleteBookObjectCache(); return $success ? true : false; }
/** * @param array $book_contents * @param array $metadata */ protected function echoBackMatter($book_contents, $metadata) { $back_matter_printf = '<div class="back-matter %s" id="%s">'; $back_matter_printf .= '<div class="back-matter-title-wrap"><h3 class="back-matter-number">%s</h3><h1 class="back-matter-title">%s</h1></div>'; $back_matter_printf .= '<div class="ugc back-matter-ugc">%s</div>%s'; $back_matter_printf .= '</div>'; $i = $s = 1; foreach ($book_contents['back-matter'] as $back_matter) { if (!$back_matter['export']) { continue; } $id = $back_matter['ID']; $subclass = \PressBooks\Taxonomy\back_matter_type($id); $slug = $back_matter['post_name']; $title = get_post_meta($id, 'pb_show_title', true) ? $back_matter['post_title'] : '<span class="display-none">' . $back_matter['post_title'] . '</span>'; // Preserve auto-indexing in Prince using hidden span $content = $back_matter['post_content']; $short_title = trim(get_post_meta($id, 'pb_short_title', true)); $subtitle = trim(get_post_meta($id, 'pb_subtitle', true)); $author = trim(get_post_meta($id, 'pb_section_author', true)); $sections = \PressBooks\Book::getSubsections($id); if ($sections) { $content = \PressBooks\Book::tagSubsections($content); } if ($author) { $content = '<h2 class="chapter-author">' . Sanitize\decode($author) . '</h2>' . $content; } if ($subtitle) { $content = '<h2 class="chapter-subtitle">' . Sanitize\decode($subtitle) . '</h2>' . $content; } if ($short_title) { $content = '<h6 class="short-title">' . Sanitize\decode($short_title) . '</h6>' . $content; } printf($back_matter_printf, $subclass, $slug, $i, Sanitize\decode($title), $content, $this->doEndnotes($id)); echo "\n"; ++$i; } }
/** * Simple revoke of an import (user hits the 'cancel' button) * * @return type */ static function revokeCurrentImport() { \Pressbooks\Book::deleteBookObjectCache(); return delete_option('pbt_current_import'); }
<?php /** * Change core WordPress strings using $overrides array. * * @author PressBooks <*****@*****.**> * @license GPLv2 (or any later version) * @see pressbooks/includes/pb-l10n.php */ $overrides = array('My Sites' => 'Mina Böcker', 'Create a New Site' => 'Skapa en ny bok'); if (\PressBooks\Book::isBook()) { $overrides['Settings'] = 'Inställningar'; $overrides['Visit Site'] = 'Besök Bok'; $overrides['Edit Site'] = 'Visa Bok'; $overrides['Du har använt din utrymmeskvot. Vänligen ta bort filer innan du lägger upp.'] = 'Tyvärr, du har använt alla dina lagringskvoten. Vill du ha mer utrymme? Uppgradera din bok.'; } return $overrides;
/** * WP_Ajax hook for pb_delete_cover_image */ function delete_cover_image() { if (current_user_can_for_blog(get_current_blog_id(), 'upload_files') && check_ajax_referer('pb-delete-cover-image')) { $image_url = $_POST['filename']; $pid = $_POST['pid']; // Delete old images $old_id = \PressBooks\Image\attachment_id_from_url($image_url); if ($old_id) { wp_delete_attachment($old_id, true); } update_post_meta($pid, 'pb_cover_image', \PressBooks\Image\default_cover_url()); \PressBooks\Book::deleteBookObjectCache(); } // @see http://codex.wordpress.org/AJAX_in_Plugins#Error_Return_Values // Will append 0 to returned json string if we don't die() die; }
/** * Tag the subsections * * @param $content string * * @return string */ function pb_tag_sections($content, $id) { return \PressBooks\Book::tagSubsections($content, $id); }
/** * Restructures \PressBooks\Book::getBookContents() into a format more useful * for direct iteration, and tracks a nesting level for Bookmark and ToC * entries. * * @return array */ function getOrderedBookContents() { $book_contents = \PressBooks\Book::getBookContents(); $ordered = array(); foreach ($book_contents as $type => $struct) { if (strpos($type, '__') === 0) { continue; // Skip __magic keys } switch ($type) { case 'part': foreach ($struct as $part) { $part_content = trim(get_post_meta($part['ID'], 'pb_part_content', true)); if ($part_content || $this->atLeastOneExport($part['chapters'])) { if (!empty($part['post_content'])) { $part['mpdf_level'] = 1; $part['post_content'] .= $part_content; } else { $part['post_content'] = $part_content; $part['mpdf_level'] = 0; } $ordered[] = $part; foreach ($part['chapters'] as $chapter) { if (!$chapter['export']) { continue; } $chapter['mpdf_level'] = $part['mpdf_level'] + 1; $ordered[] = $chapter; if (\PressBooks\Export\Export::shouldParseSections() == true) { $sections = \PressBooks\Book::getSubsections($chapter['ID']); if ($sections) { foreach ($sections as $section) { $section['mpdf_level'] = $part['mpdf_level'] + 2; $ordered[] = $section; } } } } } } break; default: foreach ($struct as $item) { if (!$item['export']) { continue; } $item['mpdf_level'] = 1; $ordered[] = $item; if (\PressBooks\Export\Export::shouldParseSections() == true) { $sections = \PressBooks\Book::getSubsections($item['ID']); if ($sections) { foreach ($sections as $section) { $section['mpdf_level'] = 2; $ordered[] = $section; } } } } break; } } return $ordered; }
function pressbooks_copyright_license() { $option = get_option('pressbooks_theme_options_global'); $book_meta = \PressBooks\Book::getBookInformation(); // if they don't want to see it, return // at minimum we need book copyright information set if (isset($option['copyright_license']) && false == $option['copyright_license'] || !isset($option['copyright_license']) || !isset($book_meta['pb_book_license'])) { return ''; } global $post; $id = $post->ID; $title = is_front_page() ? get_bloginfo('name') : $post->post_title; $post_meta = get_post_meta($id); $link = get_permalink($id); $html = $license = $copyright_holder = ''; $transient = get_transient("license-inf-{$id}"); $updated = array($license, $copyright_holder, $title); $changed = false; $lang = $book_meta['pb_language']; // Copyright holder, set in order of precedence if (isset($post_meta['pb_section_author'])) { // section author overrides book author, copyrightholder $copyright_holder = $post_meta['pb_section_author'][0]; } elseif (isset($book_meta['pb_copyright_holder'])) { // book copyright holder overrides book author $copyright_holder = $book_meta['pb_copyright_holder']; } elseif (isset($book_meta['pb_author'])) { // book author is the fallback, default $copyright_holder = $book_meta['pb_author']; } // Copyright license, set in order of precedence if (isset($post_meta['pb_section_license'])) { // section copyright overrides book $license = $post_meta['pb_section_license'][0]; } elseif (isset($book_meta['pb_book_license'])) { // book is the fallback, default $license = $book_meta['pb_book_license']; } //delete_transient("license-inf-$id"); // check if the user has changed anything if (is_array($transient)) { foreach ($updated as $val) { if (!array_key_exists($val, $transient)) { $changed = true; } } } // if the cache has expired, or the user changed the license if (false === $transient || true == $changed) { // get xml response from API $response = \PressBooks\Metadata::getLicenseXml($license, $copyright_holder, $link, $title, $lang); try { // convert to object $result = simplexml_load_string($response); // evaluate it for errors if (!false === $result || !isset($result->html)) { throw new \Exception('Creative Commons license API not returning expected results at Pressbooks\\Metadata::getLicenseXml'); } else { // process the response, return html $html = \PressBooks\Metadata::getWebLicenseHtml($result->html); } } catch (\Exception $e) { error_log($e->getMessage()); } // store it with the license as a key $value = array($license => $html, $copyright_holder => '', $title => ''); // expires in 24 hours set_transient("license-inf-{$id}", $value, 86400); } else { $html = $transient[$license]; } return $html; }