Exemple #1
0
/**
 * 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;
}
Exemple #5
0
/**
 * 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'] : '&hellip;';
        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'] : '&hellip;';
        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'] : '&hellip;';
            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'] : '&hellip;';
        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');
 }
Exemple #7
0
 /**
  * @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'));
         }
     }
 }
Exemple #10
0
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
 }
Exemple #17
0
/**
 * 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;
 }
Exemple #20
0
/**
 * 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
 }
Exemple #22
0
/**
 * 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;
Exemple #27
0
/**
 * 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;
}
Exemple #28
0
/**
 * 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;
 }
Exemple #30
0
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;
}