Advertisement
Guest User

Saso

a guest
Nov 3rd, 2016
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 119.71 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4. Plugin Name: Quotes llama
  5. Plugin URI:  http://wordpress.org/plugins/quotes-llama/
  6. Version:     0.5.1
  7. Description: Share the thoughts that mean the most... display your quotes in widget, page, template, gallery or post.
  8. Author:      oooorgle
  9. Author URI:  http://wordpress.org/plugins/quotes-llama/
  10. Text Domain: quotes-llama
  11. Domain Path: quotes-llama/lang
  12. License:     Copyheart
  13. License URI: http://copyheart.org
  14. */
  15.  
  16. // deny access to page except through WordPress
  17. defined( "ABSPATH" ) or die( "Cannot access pages directly." );
  18.  
  19. // include our local WP_List_Table class
  20. // http://codex.wordpress.org/Class_Reference/WP_List_Table
  21. if( ! class_exists( "QuotesLlama_List_Table" ) ) {
  22.  
  23.     // http://php.net/manual/en/function.require-once.php
  24.     require_once( "quotes-llama-list-table.php" );
  25.  
  26. }
  27.  
  28.  
  29. class QuotesLlama {
  30.  
  31.     private $userlevel; // Permission level to administer plugin.
  32.     private $plugin_version; // Plugin version.
  33.     private $db_version; // Plugin database table version.
  34.     private $table_name; // Plugin table name.
  35.     private $active_tab; // Currently selected tab.
  36.     private $plugin_options; // Array of plugin options.
  37.     private $url; // The URL of the directory that contains the plugin.
  38.     private $plugin; // The URL of the plugin.
  39.     private $msg; // The msg for success/failure of actions.
  40.  
  41.     public function __construct() {
  42.  
  43.         global $wpdb;
  44.  
  45.         // Plugin version.
  46.         $this->plugin_version = "0.5.1";
  47.  
  48.         // db version.
  49.         $this->db_version = "1.0";
  50.  
  51.         // Full table name.
  52.         $this->table_name = $wpdb->prefix . "quotes_llama";
  53.  
  54.         // Plugin optons array.
  55.         // http://codex.wordpress.org/Function_Reference/get_option
  56.         $this->plugin_options = get_option( "quotes-llama-settings" );
  57.  
  58.         // User level needed to manage plugin. Admin or Editor only.
  59.         // http://codex.wordpress.org/Roles_and_Capabilities
  60.         $this->userlevel = $this->plugin_options["permission_level"];
  61.  
  62.         $this->msg = "";
  63.  
  64.         // Process any $_POSTs.
  65.         // http://codex.wordpress.org/Plugin_API/Action_Reference/init
  66.         add_action( "init", array( $this, "plugin_posts" ) );
  67.  
  68.         // Set shortcode for starting plugin.
  69.         add_action( "init", array( $this, "plugin_shortcodes" ) );
  70.  
  71.         // Non authenticated user privilege .ajax.
  72.         // http://codex.wordpress.org/Function_Reference/add_action
  73.         add_action( "wp_ajax_nopriv_widget_instance", array( $this, "widget_instance" ) );
  74.         add_action( "wp_ajax_widget_instance", array( $this, "widget_instance" ) );
  75.         add_action( "wp_ajax_nopriv_quotes_select", array( $this, "quotes_select" ) );
  76.         add_action( "wp_ajax_quotes_select", array( $this, "quotes_select" ) );
  77.         add_action( "wp_ajax_nopriv_template_page_author", array( $this, "template_page_author" ) );
  78.         add_action( "wp_ajax_template_page_author", array( $this, "template_page_author" ) );
  79.  
  80.         // Plugin path.
  81.         // http://codex.wordpress.org/Function_Reference/plugin_dir_url
  82.         $this->url = plugin_dir_url( __FILE__ );
  83.  
  84.         // Plugin file.
  85.         // http://codex.wordpress.org/Function_Reference/plugin_basename
  86.         $this->plugin = plugin_basename( __FILE__ );
  87.  
  88.         // Define i18n language folder.
  89.         add_action( "plugin_text_domain", array( $this, "plugin_text_domain" ) );
  90.  
  91.         // https://codex.wordpress.org/Function_Reference/is_admin
  92.         if ( !is_admin() ) {
  93.  
  94.             // Page view - only load if viewing the front page.
  95.             add_action( "wp_enqueue_scripts", array( $this, "plugin_scripts" ) );
  96.  
  97.             // init widget class
  98.             add_action( "widgets_init", array( $this, "register_widgets" ) );
  99.  
  100.         } else {
  101.  
  102.             // Dashboard view - only load if viewing the Dashboard.
  103.             add_action( "admin_enqueue_scripts", array( $this, "admin_scripts" ) );
  104.  
  105.             // Create plugin database table.
  106.             register_activation_hook( __FILE__, array( $this, "plugin_db_setup" ) );
  107.  
  108.             // Create plugin options.
  109.             // http://codex.wordpress.org/Function_Reference/register_activation_hook
  110.             register_activation_hook( __FILE__, array( $this, "plugin_activation" ) );
  111.  
  112.             // Remove plugin options and settings when deactivating.
  113.             // http://codex.wordpress.org/Function_Reference/register_deactivation_hook
  114.             register_deactivation_hook( __FILE__, array( $this, "plugin_deactivation" ) );
  115.  
  116.             // Create admin manage links, css, and page fields.
  117.             // http://codex.wordpress.org/Function_Reference/add_filter
  118.             add_filter( "plugin_action_links_" . $this->plugin, array( $this, "plugin_manage_link" ) );
  119.             add_filter( 'set-screen-option', array( $this, "quotes_llama_set_option" ), 10, 3 );
  120.             add_action( "admin_menu", array( $this, "plugin_settings_link" ) );
  121.             add_action( "admin_init", array( $this, "admin_page_fields" ) );
  122.             add_action( "admin_head", array( $this, "plugin_css" ) );
  123.  
  124.             // init widget class
  125.             add_action( "widgets_init", array( $this, "register_widgets" ) );
  126.  
  127.         }
  128.  
  129.     } // End __construct
  130.  
  131.  
  132.     /*
  133.      *  Dashboard scripts, localizations and styles.
  134.     */
  135.     public function admin_scripts() {
  136.  
  137.         // http://codex.wordpress.org/Function_Reference/wp_enqueue_script
  138.         wp_enqueue_script( "quotesllamaAjax", $this->url . "quotes-llama.js", array("jquery"), $this->plugin_version, true );
  139.  
  140.         // http://codex.wordpress.org/Function_Reference/wp_localize_script
  141.         wp_localize_script( "quotesllamaAjax", "quotesllamaOption",
  142.             array( "ajaxurl" => admin_url( "admin-ajax.php" )
  143.             ));
  144.  
  145.         // Enqueues all scripts, styles, settings, and templates necessary to use all media JavaScript APIs.
  146.         // http://codex.wordpress.org/Function_Reference/wp_enqueue_media
  147.         wp_enqueue_media();
  148.  
  149.     }
  150.  
  151.  
  152.     /*
  153.      *  Front-end scripts, localizations and styles.
  154.     */
  155.     public function plugin_scripts() {
  156.  
  157.         wp_enqueue_script( "quotesllamaAjax", $this->url . "quotes-llama.js", array("jquery"), $this->plugin_version, true );
  158.  
  159.         // Our php variables to pass to Javascript and the admin-ajax.php path for .ajax posts from javascript.
  160.         // avoid boolean because of false causing indexing errors in debug.
  161.         // http://codex.wordpress.org/Function_Reference/wp_localize_script
  162.         wp_localize_script( "quotesllamaAjax", "quotesllamaOption",
  163.             array( "ajaxurl" => admin_url( "admin-ajax.php" ),
  164.                 "BackgroundColor" => $this->plugin_options["background_color"],
  165.                 "ForegroundColor" => $this->plugin_options["foreground_color"],
  166.                 "GalleryInterval" => $this->plugin_options["gallery_timer_interval"],
  167.                 "GalleryMinimum" => $this->plugin_options["gallery_timer_minimum"],
  168.                 "Sidebarpos" => $this->plugin_options["sidebar"],
  169.                 "Limit" => $this->plugin_options["character_limit"],
  170.                 "Ellipses" => $this->plugin_options["ellipses_text"],
  171.                 "SourceNewLine" => $this->plugin_options["source_newline"],
  172.                 "MoreText" => $this->plugin_options["read_more_text"],
  173.                 "LessText" => $this->plugin_options["read_less_text"]
  174.             )
  175.  
  176.         );
  177.  
  178.         // http://codex.wordpress.org/Function_Reference/wp_enqueue_style
  179.         wp_enqueue_style( "quotesllamastyle", $this->url . "css/quotes-llama-style.css" );
  180.  
  181.     }
  182.  
  183.  
  184.     /*
  185.      *  Process $_POST requests for
  186.      *  Single feeds, link submissions, and category pages.
  187.      */
  188.     public function plugin_posts() {
  189.  
  190.         // If we are searching the quotes table.
  191.         // Check url for _wp_http_referer and remove it to avoid url too long error when performing multiple searches.
  192.         if( isset( $_REQUEST["quotes_llama_s"] ) ){
  193.  
  194.             $current_url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
  195.  
  196.             // If it contains the referer field strip it and the nonce.
  197.             if ( strpos( $current_url, "_wp_http_referer" ) !== false ) {
  198.  
  199.                 $new_url = remove_query_arg( array( "_wp_http_referer", "_wpnonce" ), stripslashes( $current_url ));
  200.                 wp_redirect( $new_url );
  201.                 exit;
  202.  
  203.             }
  204.  
  205.         }
  206.  
  207.         // $_GET clicked tab or set initial tab.
  208.         if ( isset( $_GET[ "tab" ] ) ) {
  209.  
  210.             $this->active_tab = isset( $_GET[ "tab" ] ) ? $_GET[ "tab" ] : "quotes";
  211.  
  212.         } else {
  213.  
  214.             $this->active_tab = "quotes";
  215.  
  216.         }
  217.  
  218.         // $_REQUEST to Export quotes to csv.
  219.         if ( isset( $_REQUEST[ "exportcsv" ] ) ) {
  220.  
  221.             // http://codex.wordpress.org/Function_Reference/check_admin_referer
  222.             if ( check_admin_referer( "export", "quotes-llama" ) ) {
  223.  
  224.                 $export_csv = new QuotesLlamaBackup( $this->table_name, $this->plugin_options["export_delimiter"] );
  225.  
  226.                 $export_csv->create_csv();
  227.  
  228.             } else {
  229.  
  230.                 $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  231.  
  232.             }
  233.  
  234.         }
  235.  
  236.         // $_REQUEST to Export quotes to json.
  237.         if ( isset( $_REQUEST[ "exportjson" ] ) ) {
  238.  
  239.             if ( check_admin_referer( "export", "quotes-llama" ) ) {
  240.  
  241.                 $export_json = new QuotesLlamaBackup( $this->table_name, $this->plugin_options["export_delimiter"] );
  242.  
  243.                 $export_json->create_json();
  244.  
  245.             } else {
  246.  
  247.                 $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  248.  
  249.             }
  250.  
  251.         }
  252.  
  253.         // $_REQUEST to Import quotes from json.
  254.         if ( isset( $_REQUEST[ "import" ] ) ) {
  255.  
  256.             if ( check_admin_referer( "import", "quotes-llama" ) ) {
  257.  
  258.                 $import = new QuotesLlamaBackup( $this->table_name, $this->plugin_options["export_delimiter"] );
  259.  
  260.                 $import->generate_import();
  261.  
  262.             } else {
  263.  
  264.                 $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  265.  
  266.             }
  267.  
  268.         }
  269.  
  270.         // $_REQUEST to add quote or Save Quote.
  271.         // http://php.net/manual/en/reserved.variables.request.php
  272.         if ( isset( $_REQUEST["submit"] ) ) {
  273.  
  274.             // http://codex.wordpress.org/I18n_for_WordPress_Developers
  275.             if ( $_REQUEST["submit"] == __( "Add Quote", "quotes-llama" ) ) {
  276.  
  277.                 // http://php.net/manual/en/function.extract.php
  278.                 extract( $_REQUEST );
  279.  
  280.                 // http://codex.wordpress.org/Function_Reference/check_admin_referer
  281.                 // http://codex.wordpress.org/Plugin_API/Action_Reference/admin_notices
  282.                 if ( check_admin_referer( "quotes_llama_form", "security" ) ) {
  283.  
  284.                     $this->msg = $this->quotes_insert( $quote, $first_name, $last_name, $source, $img_url );
  285.  
  286.                 } else {
  287.  
  288.                     $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  289.  
  290.                 }
  291.  
  292.             }
  293.  
  294.             if ( $_REQUEST["submit"] == __( "Save Quote", "quotes-llama" ) ) {
  295.  
  296.                 extract( $_REQUEST );
  297.  
  298.                 if ( check_admin_referer( "quotes_llama_form", "security" ) ) {
  299.  
  300.                     $this->msg = $this->quotes_update( $quote_id, $quote, $first_name, $last_name, $source, $img_url );
  301.  
  302.                 }
  303.  
  304.             }
  305.  
  306.         }
  307.  
  308.         // $_REQUEST to delete a single quote.
  309.         if ( isset( $_REQUEST["action"] ) && $_REQUEST["action"] == "quotes_llama_delete_single" ) {
  310.  
  311.             // http://codex.wordpress.org/Function_Reference/wp_verify_nonce
  312.             if ( wp_verify_nonce( $_REQUEST["_wpnonce"], "delete_edit" ) ) {
  313.  
  314.                 // Run our query and set our return message.
  315.                 $this->msg = $this->quotes_delete( $_REQUEST["quote_id"] );
  316.  
  317.                 // Redirect our url without the quote_id or request action.
  318.                 // http://codex.wordpress.org/Function_Reference/wp_redirect
  319.                 wp_redirect( get_bloginfo( "wpurl" ) . "/wp-admin/admin.php?page=quotes-llama" . $this->get_page_number() );
  320.                 exit;
  321.  
  322.             } else {
  323.  
  324.                 $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  325.  
  326.             }
  327.  
  328.         }
  329.  
  330.  
  331.         // $_REQUEST to delete bulk quotes. The upper select box is action.
  332.         // The lower select box is action2. Action2 is defined in quotes-llama-list-table.php
  333.         // where we also edited the display_tablenav( $which ) function to not give 'url too long' errors.
  334.         if ( isset( $_REQUEST["action"], $_REQUEST["action2"] ) && ( $_REQUEST["action"] == "quotes-llama-bulk-delete" || $_REQUEST["action2"] == "quotes-llama-bulk-delete" ) ) {
  335.  
  336.             if ( check_admin_referer( "delete_bulk", "quotes-llama" ) ) {
  337.  
  338.                 // Check if any boxes are marked.
  339.                 if ( isset( $_REQUEST["bulkcheck"] ) && count( $_REQUEST["bulkcheck"] ) ) {
  340.  
  341.                     $this->quotes_delete_bulk( $_REQUEST["bulkcheck"] );
  342.  
  343.                     // Redirect our url without the quotes to delete or the request action.
  344.                     wp_redirect( get_bloginfo( "wpurl" ) . "/wp-admin/admin.php?page=quotes-llama" . $this->get_page_number() );
  345.                     exit;
  346.  
  347.                 } else {
  348.  
  349.                     wp_redirect( get_bloginfo( "wpurl" ) . "/wp-admin/admin.php?page=quotes-llama" . $this->get_page_number() );
  350.                     exit;
  351.  
  352.                 }
  353.  
  354.             } else {
  355.  
  356.                 $this->msg = "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  357.  
  358.             }
  359.  
  360.         }
  361.  
  362.     }
  363.  
  364.  
  365.     /*
  366.      *  Base shortcode.
  367.      */
  368.     public function plugin_shortcodes() {
  369.  
  370.         // http://codex.wordpress.org/Function_Reference/add_shortcode
  371.         add_shortcode( "quotes-llama", array( $this, "plugin_start" ) );
  372.  
  373.     }
  374.  
  375.  
  376.     /*
  377.      *  Start plugin via template or page shortcode.
  378.      *
  379.      */
  380.     public function plugin_start( $atts ) {
  381.  
  382.         // http://codex.wordpress.org/Function_Reference/shortcode_atts
  383.         $att_array = shortcode_atts( array( "mode" => "quote", "id" => 0 ), $atts );
  384.  
  385.         if ( $att_array["mode"] == "gallery" ) {
  386.  
  387.             return $this->template_gallery();
  388.  
  389.         }
  390.  
  391.         if ( $att_array["mode"] == "page" ) {
  392.  
  393.             return $this->template_page();
  394.  
  395.         }
  396.  
  397.         if ( $att_array["mode"] == "quote" && $att_array["id"] == 0 ) {
  398.  
  399.             return $this->template_post();
  400.  
  401.         }
  402.  
  403.         if ( $att_array["id"] > 0 ) {
  404.  
  405.             return $this->template_id( $atts["id"] );
  406.  
  407.         }
  408.  
  409.     }
  410.  
  411.  
  412.     /*
  413.      *  Register options array when activating plugin.
  414.      */
  415.     public function plugin_activation() {
  416.  
  417.         $add_options = array(
  418.             "show_page_author" => true,
  419.             "show_page_source" => true,
  420.             "show_page_image" => true,
  421.             "show_gallery_author" => true,
  422.             "show_gallery_source" => true,
  423.             "show_gallery_image" => true,
  424.             "gallery_timer_interval" => 12,
  425.             "gallery_timer_minimum" => 10,
  426.             "sidebar" => "left",
  427.             "background_color" => "#444",
  428.             "foreground_color" => "silver",
  429.             "default_sort" => "quote_id",
  430.             "default_order" => "dsc",
  431.             "permission_level" => "create_users",
  432.             "admin_reset" => true,
  433.             "export_delimiter" => "|",
  434.             "character_limit" => 0,
  435.             "ellipses_text" => "...",
  436.             "source_newline" => "comma",
  437.             "read_more_text" => "&raquo;",
  438.             "read_less_text" => "&laquo;"
  439.         );
  440.  
  441.         // http://codex.wordpress.org/Function_Reference/add_option
  442.         add_option( "quotes-llama-settings", $add_options );
  443.  
  444.     }
  445.  
  446.  
  447.     /*
  448.      *  Remove api setting when deactivating plugin
  449.      *  and the options but, only if enabled in options.
  450.      */
  451.     public function plugin_deactivation() {
  452.  
  453.         if ( isset( $this->plugin_options["admin_reset"] ) ) {
  454.  
  455.             // http://codex.wordpress.org/Function_Reference/delete_option
  456.             delete_option( "quotes-llama-settings" );
  457.  
  458.         }
  459.  
  460.         // http://codex.wordpress.org/Function_Reference/unregister_setting
  461.         unregister_setting( "quotes-llama-settings", "quotes-llama-settings" );
  462.  
  463.     }
  464.  
  465.  
  466.     /*
  467.      *  Define i18n language folder.
  468.      */
  469.     public function plugin_text_domain() {
  470.  
  471.         // http://codex.wordpress.org/Function_Reference/load_plugin_textdomain
  472.         load_plugin_textdomain( "quotes-llama", false, $this->url . "lang" );
  473.  
  474.     }
  475.  
  476.  
  477.     /*
  478.      *  Information about plugin from top of this file.
  479.      *
  480.      *  @param string $s - Field name to get.
  481.      *
  482.      *  returns string - Field text.
  483.      */
  484.     public function plugin_information( $i ) {
  485.  
  486.         // http://codex.wordpress.org/Function_Reference/get_plugin_data
  487.         $data = get_plugin_data( __FILE__ );
  488.         $info = $data[$i];
  489.  
  490.         return $info;
  491.  
  492.     }
  493.  
  494.  
  495.     /*
  496.      *  Apply admin page css.
  497.      */
  498.     public function plugin_css() {
  499.  
  500.         $url = plugin_dir_url( __FILE__ ) . "css/quotes-llama-admin.css";
  501.  
  502.         echo "<link rel='stylesheet' type='text/css' href='$url'>";
  503.  
  504.     }
  505.  
  506.  
  507.     /*
  508.      *  Setup the database table.
  509.      */
  510.     public function plugin_db_setup() {
  511.  
  512.         global $wpdb;
  513.  
  514.         if ( ! defined( "DB_CHARSET" ) || !( $charset = DB_CHARSET ) ) {
  515.  
  516.             $charset = "utf8";
  517.  
  518.         }
  519.  
  520.         $charset = "CHARACTER SET ".$charset;
  521.  
  522.         if ( defined( "DB_COLLATE" ) && $collate = DB_COLLATE ) {
  523.  
  524.             $collate = "COLLATE ".$collate;
  525.  
  526.         }
  527.  
  528.         // If plugin table does not exist, install it.
  529.         if ( $wpdb->get_var( "SHOW TABLES LIKE '$this->table_name'" ) != $this->table_name ) {
  530.  
  531.             $sql = "CREATE TABLE " . $this->table_name . " (
  532.                 quote_id mediumint(9) NOT NULL AUTO_INCREMENT,
  533.                 quote TEXT NOT NULL,
  534.                 first_name VARCHAR(255),
  535.                 last_name VARCHAR(255),
  536.                 source VARCHAR(255),
  537.                 img_url VARCHAR(255),
  538.                 UNIQUE KEY quote_id (quote_id)
  539.             ) {$charset} {$collate};";
  540.  
  541.             $results = $wpdb->query( $sql );
  542.  
  543.         }
  544.  
  545.     }
  546.  
  547.  
  548.     /*
  549.      *  Admin manage plugin link, admin panel -> plugins.
  550.      *  Prepend before | deactivate | edit
  551.      *
  552.      *  @param array $links - Array of existing panel links.
  553.      *
  554.      *  returns array with new link added.
  555.      */
  556.     public function plugin_manage_link( $links ) {
  557.  
  558.         $plugin_manage_link = "<a href='options-general.php?page=quotes-llama'>Manage</a>";
  559.  
  560.         // http://php.net/manual/en/function.array-unshift.php
  561.         array_unshift( $links, $plugin_manage_link );
  562.  
  563.         return $links;
  564.  
  565.     }
  566.  
  567.  
  568.     /*
  569.      *  Admin settings link, admin panel -> settings.
  570.      *  This is where permission to manage the plugin is set as well.
  571.      */
  572.     public function plugin_settings_link() {
  573.  
  574.         // http://codex.wordpress.org/Roles_and_Capabilities
  575.         // http://codex.wordpress.org/Function_Reference/add_options_page
  576.         // http://codex.wordpress.org/Function_Reference/add_menu_page
  577.         $hook = add_menu_page( "Quotes llama", "Quotes", $this->plugin_options["permission_level"], "quotes-llama", array( $this, "admin_page" ), 'dashicons-editor-quote', 81  );
  578.         add_action( "load-$hook", array( $this, "quotes_llama_add_option" ) );
  579.  
  580.     }
  581.  
  582.  
  583.     /*
  584.      *  Setup admin page settings, sections, and fields.
  585.      */
  586.     public function admin_page_fields() {
  587.  
  588.         // http://codex.wordpress.org/Function_Reference/register_setting
  589.         register_setting( "quotes-llama-settings", "quotes-llama-settings", array( $this, "admin_sanitize" ) );
  590.  
  591.         if ( $this->active_tab == "options" ) {
  592.  
  593.             // Settings sections defined here.
  594.             // Section post.
  595.             // http://codex.wordpress.org/Function_Reference/add_settings_section
  596.             add_settings_section(
  597.                 "page",
  598.                 esc_html__( "Random/Static Quotes", "quotes-llama" ),
  599.                 array( $this, "admin_section_page_callback" ),
  600.                 "quotes-llama"
  601.             );
  602.  
  603.             // Section gallery.
  604.             add_settings_section(
  605.                 "gallery",
  606.                 esc_html__( "Gallery Quotes", "quotes-llama" ),
  607.                 array( $this, "admin_section_gallery_callback" ),
  608.                 "quotes-llama"
  609.             );
  610.  
  611.             // Page options.
  612.             add_settings_section(
  613.                 "authors",
  614.                 esc_html__( "Authors Page", "quotes-llama" ),
  615.                 array( $this, "admin_section_authors_callback" ),
  616.                 "quotes-llama"
  617.             );
  618.  
  619.             // Quote character limit options.
  620.             add_settings_section(
  621.                 "limit",
  622.                 esc_html__( "Limit Quote Display", "quotes-llama" ),
  623.                 array( $this, "admin_section_limit_callback" ),
  624.                 "quotes-llama"
  625.             );
  626.  
  627.             // Quotes list.
  628.             add_settings_section(
  629.                 "quotes_tab",
  630.                 esc_html__( "Quotes List Tab", "quotes-llama" ),
  631.                 array( $this, "admin_section_quotes_tab_callback" ),
  632.                 "quotes-llama"
  633.             );
  634.  
  635.             // Other options.
  636.             add_settings_section(
  637.                 "other",
  638.                 esc_html__( "Other Options", "quotes-llama" ),
  639.                 array( $this, "admin_section_other_callback" ),
  640.                 "quotes-llama"
  641.             );
  642.  
  643.             // Settings fields defined here.
  644.             // Show random author.
  645.             // http://codex.wordpress.org/Function_Reference/add_settings_field
  646.             add_settings_field(
  647.                 "show_page_author",
  648.                 esc_html__( "Author", "quotes-llama" ),
  649.                 array( $this, "admin_page_author_callback" ),
  650.                 "quotes-llama",
  651.                 "page"
  652.             );
  653.  
  654.             // Show random source.
  655.             add_settings_field(
  656.                 "show_page_source",
  657.                 esc_html__( "Source", "quotes-llama" ),
  658.                 array( $this, "admin_page_source_callback" ),
  659.                 "quotes-llama",
  660.                 "page"
  661.             );
  662.  
  663.             // Show random image.
  664.             add_settings_field(
  665.                 "show_page_image",
  666.                 esc_html__( "Image", "quotes-llama" ),
  667.                 array( $this, "admin_page_image_callback" ),
  668.                 "quotes-llama",
  669.                 "page"
  670.             );
  671.  
  672.             // Show gallery author.
  673.             add_settings_field(
  674.                 "show_gallery_author",
  675.                 esc_html__( "Author", "quotes-llama" ),
  676.                 array( $this, "admin_gallery_author_callback" ),
  677.                 "quotes-llama",
  678.                 "gallery"
  679.             );
  680.  
  681.             // Show gallery source.
  682.             add_settings_field(
  683.                 "show_gallery_source",
  684.                 esc_html__( "Source", "quotes-llama" ),
  685.                 array( $this, "admin_gallery_source_callback" ),
  686.                 "quotes-llama",
  687.                 "gallery"
  688.             );
  689.  
  690.             // Show gallery image.
  691.             add_settings_field(
  692.                 "show_gallery_image",
  693.                 esc_html__( "Image", "quotes-llama" ),
  694.                 array( $this, "admin_gallery_image_callback" ),
  695.                 "quotes-llama",
  696.                 "gallery"
  697.             );
  698.  
  699.             // Gallery set timer interval.
  700.             add_settings_field(
  701.                 "gallery_timer_interval",
  702.                 esc_html__( "Timer", "quotes-llama" ),
  703.                 array( $this, "admin_gallery_timer_interval_callback" ),
  704.                 "quotes-llama",
  705.                 "gallery"
  706.             );
  707.  
  708.             // Gallery timer minimum.
  709.             add_settings_field(
  710.                 "gallery_timer_minimum",
  711.                 esc_html__( "Timer Minimum", "quotes-llama" ),
  712.                 array( $this, "admin_gallery_timer_minimum_callback" ),
  713.                 "quotes-llama",
  714.                 "gallery"
  715.             );
  716.  
  717.             // Sidebar position.
  718.             add_settings_field(
  719.                 "sidebar",
  720.                 esc_html__( "Sidebar Position", "quotes-llama" ),
  721.                 array( $this, "admin_sidebar_position_callback" ),
  722.                 "quotes-llama",
  723.                 "authors"
  724.             );
  725.  
  726.             // Background color.
  727.             add_settings_field(
  728.                 "background_color",
  729.                 esc_html__( "Background Color", "quotes-llama" ),
  730.                 array( $this, "admin_background_color_callback" ),
  731.                 "quotes-llama",
  732.                 "authors"
  733.             );
  734.  
  735.             // Foreground color.
  736.             add_settings_field(
  737.                 "foreground_color",
  738.                 esc_html__( "Foreground Color", "quotes-llama" ),
  739.                 array( $this, "admin_foreground_color_callback" ),
  740.                 "quotes-llama",
  741.                 "authors"
  742.             );
  743.  
  744.             // Quote character limit.
  745.             add_settings_field(
  746.                 "character_limit",
  747.                 esc_html__( "Character Limit", "quotes-llama" ),
  748.                 array( $this, "admin_character_limit_callback" ),
  749.                 "quotes-llama",
  750.                 "limit"
  751.             );
  752.  
  753.             // Ellipses text.
  754.             add_settings_field(
  755.                 "ellipses_text",
  756.                 esc_html__( "Ellipses Text", "quotes-llama" ),
  757.                 array( $this, "admin_ellipses_text_callback" ),
  758.                 "quotes-llama",
  759.                 "limit"
  760.             );
  761.  
  762.             // Read more text.
  763.             add_settings_field(
  764.                 "read_more_text",
  765.                 esc_html__( "Read More Text", "quotes-llama" ),
  766.                 array( $this, "admin_read_more_text_callback" ),
  767.                 "quotes-llama",
  768.                 "limit"
  769.             );
  770.  
  771.             // Read less text.
  772.             add_settings_field(
  773.                 "read_less_text",
  774.                 esc_html__( "Read Less Text", "quotes-llama" ),
  775.                 array( $this, "admin_read_less_text_callback" ),
  776.                 "quotes-llama",
  777.                 "limit"
  778.             );
  779.  
  780.             // Default sort column.
  781.             add_settings_field(
  782.                 "default_sort",
  783.                 esc_html__( "Default Sort Column", "quotes-llama" ),
  784.                 array( $this, "admin_orderby_callback" ),
  785.                 "quotes-llama",
  786.                 "quotes_tab"
  787.             );
  788.  
  789.             // Default sort order.
  790.             add_settings_field(
  791.                 "default_order",
  792.                 esc_html__( "Default Order By", "quotes-llama" ),
  793.                 array( $this, "admin_order_callback" ),
  794.                 "quotes-llama",
  795.                 "quotes_tab"
  796.             );
  797.  
  798.             // Source on new line.
  799.             add_settings_field(
  800.                 "source_newline",
  801.                 esc_html__( "Source Separator", "quotes-llama" ),
  802.                 array( $this, "admin_source_newline_callback" ),
  803.                 "quotes-llama",
  804.                 "other"
  805.             );
  806.             // Permission level.
  807.             add_settings_field(
  808.                 "permission_level",
  809.                 esc_html__( "Manage Plugin", "quotes-llama" ),
  810.                 array( $this, "admin_permission_level_callback" ),
  811.                 "quotes-llama",
  812.                 "other"
  813.             );
  814.  
  815.             // Reset options.
  816.             add_settings_field(
  817.                 "admin_reset",
  818.                 esc_html__( "Reset When Deactivating", "quotes-llama" ),
  819.                 array( $this, "admin_reset_callback" ),
  820.                 "quotes-llama",
  821.                 "other"
  822.             );
  823.  
  824.             // CSV delimiter.
  825.             add_settings_field(
  826.                 "export_delimiter",
  827.                 esc_html__( "CSV Delimiter", "quotes-llama" ),
  828.                 array( $this, "admin_export_delimiter_callback" ),
  829.                 "quotes-llama",
  830.                 "other"
  831.             );
  832.  
  833.             // CSV delimiter.
  834.             add_settings_field(
  835.                 "widget_page",
  836.                 esc_html__( "Widgets", "quotes-llama" ),
  837.                 array( $this, "admin_widget_page_callback" ),
  838.                 "quotes-llama",
  839.                 "other"
  840.             );
  841.  
  842.         }
  843.  
  844.     }
  845.  
  846.  
  847.     /*
  848.      *  Render tabs in admin page.
  849.      */
  850.     public function admin_page() {
  851.  
  852.         // First we need to check that the user has permisson to view the admin page.
  853.         // http://codex.wordpress.org/Function_Reference/current_user_can
  854.         if ( current_user_can( $this->plugin_options["permission_level"] ) ) {
  855.  
  856.             // Display our action msg if we have completed an action.
  857.             echo $this->msg;
  858.  
  859.             echo "<div class='wrap'>";
  860.  
  861.                 echo "<h2>" . $this->plugin_information( "Name" ) . "</h2>";
  862.                 echo "<h3>" . $this->plugin_information( "Description" ) . "</h3>";
  863.                 $this->admin_tabs();
  864.                 $this->admin_tab_quotes();
  865.                 $this->admin_tab_options();
  866.                 $this->admin_tab_add();
  867.                 $this->admin_tab_export_import();
  868.                 $this->admin_tab_short_codes();
  869.  
  870.             echo "</div>";
  871.  
  872.         } else {
  873.  
  874.             echo "<div class='error'>" . esc_html__("You do not have sufficient permissions to access this page.", "quotes-llama") . "</div>";
  875.  
  876.         }
  877.  
  878.     }
  879.  
  880.  
  881.     /*
  882.      *  Admin tabs.
  883.      */
  884.     public function admin_tabs() {
  885.  
  886.         // This is where we build our admin tabs. ?>
  887.         <h2 class="nav-tab-wrapper">
  888.  
  889.             <a href="?page=quotes-llama&tab=quotes"
  890.                 class="nav-tab <?php echo $this->active_tab == 'quotes' ? 'nav-tab-active' : ''; ?>">
  891.  
  892.                 <?php // http://codex.wordpress.org/Function_Reference/esc_html_e
  893.                  esc_html_e( "Quotes List", "quotes-llama" ); ?>
  894.  
  895.             </a>
  896.  
  897.             <a href="?page=quotes-llama&tab=add"
  898.                 class="nav-tab <?php echo $this->active_tab == 'add' ? 'nav-tab-active' : ''; ?>">
  899.  
  900.                 <?php esc_html_e( "New Quote", "quotes-llama" ); ?>
  901.  
  902.             </a>
  903.  
  904.             <a href="?page=quotes-llama&tab=options"
  905.                 class="nav-tab <?php echo $this->active_tab == 'options' ? 'nav-tab-active' : ''; ?>">
  906.  
  907.                 <?php esc_html_e( "Options", "quotes-llama" ); ?>
  908.  
  909.             </a>
  910.  
  911.             <a href="?page=quotes-llama&tab=export"
  912.                 class="nav-tab <?php echo $this->active_tab == 'export' ? 'nav-tab-active' : ''; ?>">
  913.  
  914.                 <?php esc_html_e( "Import/Export", "quotes-llama" ); ?>
  915.  
  916.             </a>
  917.  
  918.             <a href="?page=quotes-llama&tab=short_codes"
  919.                 class="nav-tab <?php echo $this->active_tab == 'short_codes' ? 'nav-tab-active' : ''; ?>">
  920.  
  921.                 <?php esc_html_e( "Shortcode", "quotes-llama" ); ?>
  922.  
  923.             </a>
  924.  
  925.         </h2> <?php
  926.  
  927.     }
  928.  
  929.  
  930.     /*
  931.      *  Quotes list tab.
  932.      */
  933.     public function admin_tab_quotes() {
  934.  
  935.         // Tab - Quotes list.
  936.         if ( $this->active_tab == "quotes" ) {
  937.  
  938.             // Render page. ?>
  939.             <div class="wrap"> <?php
  940.  
  941.                 // $_REQUEST to get a quote for editing.
  942.                 // Placed here so edit form will render instead of quotes list.
  943.                 if ( isset( $_REQUEST["action"] ) && $_REQUEST["action"] == "quotes_llama_edit" ) {
  944.  
  945.                     if ( wp_verify_nonce( $_REQUEST["_wpnonce"], "delete_edit" ) ) { ?>
  946.  
  947.                         <div class="wrap">
  948.  
  949.                             <h2><?php esc_html_e( "Edit Quote", "quotes-llama" ); ?></h2>
  950.  
  951.                             <?php echo $this->quotes_form( $_REQUEST["quote_id"], $this->get_page_number() ); ?>
  952.  
  953.                         </div><?php
  954.  
  955.                     } else {
  956.  
  957.                         echo "<div class='error'><p>" . "Security Token Mismatch. Please reload the page and try again." . "</p></div>";
  958.  
  959.                     }
  960.  
  961.                     return;
  962.  
  963.                 }
  964.  
  965.                 // Create an instance of our quotes table list class.
  966.                 $quotes_table = new QuotesLlamaTable();
  967.  
  968.                 // If we are searching the quotes table.
  969.                 if( isset( $_REQUEST["quotes_llama_s"] ) ){
  970.  
  971.                     $quotes_table->prepare_items( $_REQUEST["quotes_llama_s"], 20 );
  972.  
  973.                 } else {
  974.  
  975.                     // Or get all quotes.
  976.                     $quotes_table->prepare_items();
  977.  
  978.                 }
  979.  
  980.                 // Form that contains the quotes table. ?>
  981.                 <form id="quotes-filter" method="get" class="quotes-llama-admin-form">
  982.  
  983.                     <!-- What column to search -->
  984.                     <select name="search_column" style="float: right;">
  985.  
  986.                         <option value="quote"<?php if ( isset( $_REQUEST["search_column"] ) && $_REQUEST["search_column"] == "quote" ) { echo " selected"; } ?>>
  987.  
  988.                             <?php esc_html_e( "Quote", "quotes-llama" ); ?>
  989.  
  990.                         </option>
  991.  
  992.                         <option value="first_name"<?php if ( isset( $_REQUEST["search_column"] ) && $_REQUEST["search_column"] == "first_name" ) { echo " selected"; }; ?>>
  993.  
  994.                             <?php esc_html_e( "First Name", "quotes-llama" ); ?>
  995.  
  996.                         </option>
  997.  
  998.                         <option value="last_name"<?php if ( isset( $_REQUEST["search_column"] ) && $_REQUEST["search_column"] == "last_name" ) { echo " selected"; }; ?>>
  999.  
  1000.                             <?php esc_html_e( "Last Name", "quotes-llama" ); ?>
  1001.  
  1002.                         </option>
  1003.  
  1004.                         <option value="source"<?php if ( isset( $_REQUEST["search_column"] ) && $_REQUEST["search_column"] == "source" ) { echo " selected"; }; ?>>
  1005.  
  1006.                             <?php esc_html_e( "Source", "quotes-llama" ); ?>
  1007.  
  1008.                         </option>
  1009.  
  1010.                         <option value="img_url"<?php if ( isset( $_REQUEST["search_column"] ) && $_REQUEST["search_column"] == "img_url" ) { echo " selected"; }; ?>>
  1011.  
  1012.                             <?php esc_html_e( "Image URL", "quotes-llama" ); ?>
  1013.  
  1014.                         </option>
  1015.  
  1016.                     </select> <?php
  1017.  
  1018.                     wp_nonce_field( "delete_bulk", "quotes-llama" );
  1019.  
  1020.                     // Wordpress generated search form fields.
  1021.                     // http://developer.wordpress.org/reference/classes/wp_list_table/search_box/
  1022.                      $quotes_table->search_box( esc_html__( "Search", "quotes-llama" ), "quotes-llama-admin-search"); ?>
  1023.  
  1024.                     <input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>"> <?php
  1025.  
  1026.                      // Render table
  1027.                     $quotes_table->display() ?>
  1028.  
  1029.                 </form>
  1030.  
  1031.             </div><?php
  1032.  
  1033.         }
  1034.  
  1035.     }
  1036.  
  1037.  
  1038.     /*
  1039.      *  Add new quote tab.
  1040.      */
  1041.     public function admin_tab_add() {
  1042.  
  1043.         // Tab - New quote.
  1044.         if ( $this->active_tab == "add" ) { ?>
  1045.  
  1046.             <div id="addnew" class="wrap quotes-llama-admin-form">
  1047.  
  1048.                 <h2>
  1049.  
  1050.                     <?php esc_html_e( "New Quote", "quotes-llama" ); ?>
  1051.  
  1052.                 </h2>
  1053.  
  1054.                 <?php echo $this->quotes_form( 0, "" ); ?>
  1055.  
  1056.             </div> <?php
  1057.  
  1058.         }
  1059.  
  1060.     }
  1061.  
  1062.  
  1063.     /*
  1064.      *  Options tab.
  1065.      */
  1066.     public function admin_tab_options() {
  1067.  
  1068.         // Tab - options view.
  1069.         if ( $this->active_tab == "options" ) {
  1070.  
  1071.             // Save settings form and button. ?>
  1072.             <form action="options.php" method="POST" class="quotes-llama-admin-form">
  1073.  
  1074.                 <!-- http://codex.wordpress.org/Function_Reference/settings_fields -->
  1075.                 <?php settings_fields( "quotes-llama-settings" ); ?>
  1076.  
  1077.                 <!-- http://codex.wordpress.org/Function_Reference/do_settings_sections -->
  1078.                 <?php do_settings_sections( "quotes-llama" );
  1079.  
  1080.                  "<li>" . esc_html__( "Widget options are set in the", "quotes-llama" ) . " " .
  1081.                     "<a href='" . get_bloginfo( 'wpurl' ) . "/wp-admin/widgets.php'>" .
  1082.                     esc_html__( "widgets screen.", "quotes-llama" ) .
  1083.                     "</a></li>";
  1084.  
  1085.                 // http://codex.wordpress.org/Function_Reference/submit_button
  1086.                 //submit_button( $text, $type, $name, $wrap, $other_attributes )
  1087.                 submit_button( esc_html__( "Save Options", "quotes-llama" ) ); ?>
  1088.  
  1089.             </form> <?php
  1090.  
  1091.         }
  1092.     }
  1093.  
  1094.  
  1095.     /*
  1096.      *  Export/Import tab.
  1097.      */
  1098.     public function admin_tab_export_import() {
  1099.  
  1100.         if ( $this->active_tab == "export" ) { ?>
  1101.  
  1102.             <div class="quotes-llama-inline">
  1103.  
  1104.                 <form method="post" action="<?php echo get_bloginfo( 'wpurl' ); ?>/wp-admin/admin.php?page=quotes-llama"> <?php
  1105.  
  1106.                     echo "<h2>" . esc_html__( "Export" ) . "</h2>";
  1107.  
  1108.                     echo "<p>" . esc_html__( "Backup your quotes to either .csv or .json formats.", "quotes-llama" ) . "</p>";
  1109.  
  1110.                     wp_nonce_field( "export", "quotes-llama" );
  1111.  
  1112.                     submit_button( esc_html__( "Export .csv", "quotes-llama" ), "large", "exportcsv", false, array( "exportcsv" => "quotes" ) );
  1113.  
  1114.                     echo "&nbsp";
  1115.  
  1116.                     submit_button( esc_html__( "Export .json", "quotes-llama" ), "large", "exportjson", false, array( "exportjson" => "quotes" ) );
  1117.  
  1118.                     echo "<p>" . esc_html__( "The .csv delimiter can be set in the options tab.", "quotes-llama" ) . "</p>"; ?>
  1119.  
  1120.                 </form>
  1121.  
  1122.                 <form name="" method="post" action="<?php echo get_bloginfo( 'wpurl' ); ?>/wp-admin/options-general.php?page=quotes-llama"  enctype="multipart/form-data"> <?php
  1123.  
  1124.                     // http://codex.wordpress.org/Function_Reference/wp_nonce_field
  1125.                     wp_nonce_field( "import", "quotes-llama" );
  1126.  
  1127.                     echo "<h2>" . esc_html__( "Import" ) . "</h2>";
  1128.  
  1129.                     echo "<p>" . esc_html__( "Restore your quotes from either .csv or .json formats. Browse for a file, then select the import button." ) . "</p>"; ?>
  1130.  
  1131.                     <input type="file" name="quotes-llama-file"> <?php
  1132.  
  1133.                     submit_button( esc_html__( "Import", "quotes-llama" ), "secondary", "import", true, array( "import" => "quotes" ) ); ?>
  1134.  
  1135.                 </form>
  1136.  
  1137.             </div> <?php
  1138.  
  1139.         }
  1140.  
  1141.     }
  1142.  
  1143.  
  1144.     /*
  1145.      *  Shortcodes tab.
  1146.      */
  1147.     public function admin_tab_short_codes() {
  1148.  
  1149.         if ( $this->active_tab == "short_codes" ) { ?>
  1150.  
  1151.             <div>
  1152.  
  1153.                 <p>
  1154.  
  1155.                     <?php esc_html_e( "To include this plugin in a page or post:", "quotes-llama" ); ?>
  1156.                     <br><b><code>[quotes-llama mode='gallery']</code></b>
  1157.                     <?php esc_html_e( "Gallery of quotes.", "quotes-llama" ); ?>
  1158.                     <br><b><code>[quotes-llama mode='page']</code></b>
  1159.                     <?php esc_html_e( "Authors page.", "quotes-llama" ); ?>
  1160.                     <br><b><code>[quotes-llama]</code></b>
  1161.                     <?php esc_html_e( "Random quote.", "quotes-llama" ); ?>
  1162.                     <br><b><code>[quotes-llama id='id#']</code></b>
  1163.                     <?php esc_html_e( "Static quote.", "quotes-llama" ); ?>
  1164.  
  1165.                 </p>
  1166.  
  1167.                 <p>
  1168.  
  1169.                     <?php esc_html_e( "To include this plugin in a template file:", "quotes-llama" ); ?>
  1170.                     <br><b><code>do_shortcode( "[quotes-llama mode='gallery']" );</code></b>
  1171.                     <?php esc_html_e( "Gallery of quotes.", "quotes-llama" ); ?>
  1172.                     <br><b><code>do_shortcode( "[quotes-llama mode='page']" );</code></b>
  1173.                     <?php esc_html_e( "Authors page.", "quotes-llama" ); ?>
  1174.                     <br><b><code>do_shortcode( "[quotes-llama]" );</code></b>
  1175.                     <?php esc_html_e( "Random quote.", "quotes-llama" ); ?>
  1176.                     <br><b><code>do_shortcode( "[quotes-llama id='id#']" );</code></b>
  1177.                     <?php esc_html_e( "Static quote.", "quotes-llama" ); ?>
  1178.  
  1179.                 </p>
  1180.  
  1181.                 <div class="quotes-llama-admin-div">
  1182.  
  1183.                     <hr class="quotes-llama-admin-hr">
  1184.  
  1185.                     <?php esc_html_e( "Plugin Website:", "quotes-llama" ); ?>
  1186.  
  1187.                     <a href="<?php echo $this->plugin_information( "PluginURI" ); ?>"
  1188.                         target="_blank"
  1189.                         title="<?php echo $this->strip_trim_esc_attr( $this->plugin_information( 'Name' ) ); ?>">
  1190.  
  1191.                         <?php echo $this->strip_trim_wp_kses_post( $this->plugin_information( "Name" ) ); ?>
  1192.  
  1193.                     </a>
  1194.  
  1195.                     <br>
  1196.  
  1197.                     <?php esc_html_e( "Authors Website:", "quotes-llama" ); ?>
  1198.  
  1199.                     <a href="http://oooorgle.com/"
  1200.                         target="_blank"
  1201.                         title="<?php esc_attr_e( 'oooorgle.com', 'quotes-llama'  ); ?>">
  1202.  
  1203.                         <?php esc_html_e( "oooorgle", "quotes-llama" ); ?>
  1204.  
  1205.                     </a>
  1206.  
  1207.                 </div>
  1208.  
  1209.                 <div class="quotes-llama-admin-div">
  1210.  
  1211.                     <?php esc_html_e( "License:", "quotes-llama" ); ?>
  1212.  
  1213.                     <a href="http://copyheart.org"
  1214.                         target="_blank"
  1215.                         title="<?php esc_attr_e( 'CoyHeart', 'quotes-llama' ); ?>">
  1216.  
  1217.                         <?php esc_html_e( "Copyheart", "quotes-llama" ); ?>
  1218.  
  1219.                     </a>
  1220.  
  1221.                     <p>
  1222.  
  1223.                         <?php echo $this->strip_trim_wp_kses_post( "Running version " . $this->plugin_information( "Version" ) ) . "<br>"; ?>
  1224.                         <?php esc_html_e( "If you like this plugin: share it with someone!", "quotes-llama" );
  1225.                         echo "<br> ";
  1226.                         esc_html_e( "Perhaps consider ", "quotes-llama" ); ?>
  1227.                         <a href="https://wordpress.org/support/view/plugin-reviews/quotes-llama"
  1228.                             target="_blank"
  1229.                             title="<?php esc_attr_e( 'Write a review to help promote this plugin', 'quotes-llama'  ); ?>">
  1230.  
  1231.                             <?php esc_html_e( "writing a review", "quotes-llama" ); ?>
  1232.  
  1233.                         </a>
  1234.                         <?php esc_html_e( " and rating the plugin to help promote it further in the WordPress community.", "quotes-llama" );
  1235.                         echo "<br> ";
  1236.                         esc_html_e( "And if that hasn't worn you out, you can always show your appreciation and support further development by making a small ", "quotes-llama" ); ?>
  1237.                         <a href="http://oooorgle.com/plugins/wp/quotes-llama/"
  1238.                             target="_blank"
  1239.                             title="<?php esc_attr_e( 'Donations are appreciated!', 'quotes-llama'  ); ?>">
  1240.  
  1241.                             <?php esc_html_e( "donation.", "quotes-llama" ); ?>
  1242.  
  1243.                         </a>
  1244.  
  1245.                     </p>
  1246.  
  1247.                 </div>
  1248.  
  1249.             </div> <?php
  1250.  
  1251.         }
  1252.  
  1253.     }
  1254.  
  1255.  
  1256.     /*
  1257.      *  Section post.
  1258.      */
  1259.     public function admin_section_page_callback() {
  1260.  
  1261.         esc_html_e( "When using", "quotes-llama" );
  1262.         echo " <code>[quotes-llama]</code> or <code>[quotes-llama id='id#']</code> ";
  1263.         esc_html_e( "in posts, pages, and templates.", "quotes-llama" );
  1264.  
  1265.     }
  1266.  
  1267.  
  1268.     /*
  1269.      *  Section gallery.
  1270.      */
  1271.     public function admin_section_gallery_callback() {
  1272.  
  1273.         esc_html_e( "When using", "quotes-llama" );
  1274.         echo " <code>[quotes-llama mode='gallery']</code> ";
  1275.         esc_html_e( "to display the gallery.", "quotes-llama" );
  1276.  
  1277.     }
  1278.  
  1279.  
  1280.     /*
  1281.      *  Section page.
  1282.      */
  1283.     public function admin_section_authors_callback() {
  1284.  
  1285.         esc_html_e( "When using", "quotes-llama" );
  1286.         echo " <code>[quotes-llama mode='page']</code> ";
  1287.         esc_html_e( "to display the Authors page.", "quotes-llama" );
  1288.  
  1289.     }
  1290.  
  1291.  
  1292.     /*
  1293.      *  Section page.
  1294.      */
  1295.     public function admin_section_limit_callback() {
  1296.  
  1297.         esc_html_e( "Display a limited # of characters for each quote.", "quotes-llama" );
  1298.  
  1299.     }
  1300.  
  1301.  
  1302.     /*
  1303.      *  Section quotes tab.
  1304.      */
  1305.     public function admin_section_quotes_tab_callback() {
  1306.  
  1307.         esc_html_e( "Options for the Quotes List tab." );
  1308.  
  1309.     }
  1310.  
  1311.  
  1312.     /*
  1313.      *  Section other options.
  1314.      */
  1315.     public function admin_section_other_callback() {
  1316.  
  1317.         esc_html__( "All other options." );
  1318.  
  1319.     }
  1320.  
  1321.  
  1322.     /*
  1323.      *  Show post author checkbox.
  1324.      */
  1325.     public function admin_page_author_callback() { ?>
  1326.  
  1327.         <input type="checkbox"
  1328.             id="show_page_author"
  1329.             name="quotes-llama-settings[show_page_author]"
  1330.             style="display: inline;"
  1331.             <?php if ( $this->check_plugin_option( "show_page_author" ) ) echo "checked"; ?>>
  1332.  
  1333.         <label for="show_page_author">
  1334.  
  1335.             <?php esc_html_e( "Display author in single quotes.", "quotes-llama" ); ?>
  1336.  
  1337.         </label><?php
  1338.  
  1339.     }
  1340.  
  1341.  
  1342.     /*
  1343.      *  Show post source checkbox.
  1344.      */
  1345.     public function admin_page_source_callback() { ?>
  1346.  
  1347.         <input type="checkbox"
  1348.             id="show_page_source"
  1349.             name="quotes-llama-settings[show_page_source]"
  1350.             style="display: inline;"
  1351.             <?php if ( $this->check_plugin_option( "show_page_source" ) ) echo "checked" ; ?>>
  1352.  
  1353.         <label for="show_page_source">
  1354.  
  1355.             <?php esc_html_e( "Display source in single quotes.", "quotes-llama" ); ?>
  1356.  
  1357.         </label><?php
  1358.  
  1359.     }
  1360.  
  1361.  
  1362.     /*
  1363.      *  Show post image checkbox.
  1364.      */
  1365.     public function admin_page_image_callback() { ?>
  1366.  
  1367.         <input type="checkbox"
  1368.             id="show_page_image"
  1369.             name="quotes-llama-settings[show_page_image]"
  1370.             style="display: inline;"
  1371.             <?php if ( $this->check_plugin_option( "show_page_image" ) ) echo "checked" ; ?>>
  1372.  
  1373.         <label for="show_page_image">
  1374.  
  1375.             <?php esc_html_e( "Display image in single quotes.", "quotes-llama" ); ?>
  1376.  
  1377.         </label><?php
  1378.  
  1379.     }
  1380.  
  1381.  
  1382.     /*
  1383.      *  Show gallery author checkbox.
  1384.      */
  1385.     public function admin_gallery_author_callback() { ?>
  1386.  
  1387.         <input type="checkbox"
  1388.             id="show_gallery_author"
  1389.             name="quotes-llama-settings[show_gallery_author]"
  1390.             style="display: inline;"
  1391.             <?php if ( $this->check_plugin_option( "show_gallery_author" ) ) echo "checked"; ?>>
  1392.  
  1393.         <label for="show_gallery_author">
  1394.  
  1395.             <?php esc_html_e( "Display authors in the gallery.", "quotes-llama" ); ?>
  1396.  
  1397.         </label><?php
  1398.  
  1399.     }
  1400.  
  1401.  
  1402.     /*
  1403.      *  Show gallery source checkbox.
  1404.      */
  1405.     public function admin_gallery_source_callback() { ?>
  1406.  
  1407.         <input type="checkbox"
  1408.             id="show_gallery_source"
  1409.             name="quotes-llama-settings[show_gallery_source]"
  1410.             style="display: inline;"
  1411.             <?php if ( $this->check_plugin_option( "show_gallery_source" ) ) echo "checked" ; ?>>
  1412.  
  1413.         <label for="show_gallery_source">
  1414.  
  1415.             <?php esc_html_e( "Display sources in the gallery.", "quotes-llama" ); ?>
  1416.  
  1417.         </label><?php
  1418.  
  1419.     }
  1420.  
  1421.  
  1422.     /*
  1423.      *  Gallery refresh interval adjuster.
  1424.      *  This value is used in the JS function quotes_llama_quote()
  1425.      */
  1426.     public function admin_gallery_timer_interval_callback() {
  1427.  
  1428.         $gallery_timer_interval = $this->plugin_options["gallery_timer_interval"]; ?>
  1429.  
  1430.         <select name="quotes-llama-settings[gallery_timer_interval]"
  1431.             id="gallery_timer_interval">
  1432.  
  1433.             <option value="18"<?php if ( "18" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1434.  
  1435.                 <?php esc_html_e( "Fastest", "quotes-llama" ); ?>
  1436.  
  1437.             </option>
  1438.  
  1439.             <option value="16"<?php if ( "16" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1440.  
  1441.                 <?php esc_html_e( "Faster", "quotes-llama" ); ?>
  1442.  
  1443.             </option>
  1444.  
  1445.             <option value="14"<?php if ( "14" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1446.  
  1447.                 <?php esc_html_e( "Fast", "quotes-llama" ); ?>
  1448.  
  1449.             </option>
  1450.  
  1451.             <option value="12"<?php if ( "12" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1452.  
  1453.                 <?php esc_html_e( "Normal", "quotes-llama" ); ?>
  1454.  
  1455.             </option>
  1456.  
  1457.             <option value="10"<?php if ( "10" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1458.  
  1459.                 <?php esc_html_e( "Slow", "quotes-llama" ); ?>
  1460.  
  1461.             </option>
  1462.  
  1463.             <option value="8"<?php if ( "8" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1464.  
  1465.                 <?php esc_html_e( "Slower", "quotes-llama" ); ?>
  1466.  
  1467.             </option>
  1468.  
  1469.             <option value="6"<?php if ( "6" == $gallery_timer_interval ) { echo " selected"; } ?>>
  1470.  
  1471.                 <?php esc_html_e( "Slowest", "quotes-llama" ); ?>
  1472.  
  1473.             </option>
  1474.  
  1475.         </select>
  1476.  
  1477.         <label for="gallery_timer_interval">
  1478.  
  1479.             <?php echo " " . esc_html__( "Gallery speed.", "quotes-llama" ); ?>
  1480.  
  1481.         </label><?php
  1482.  
  1483.     }
  1484.  
  1485.  
  1486.     /*
  1487.      *  Gallery timer minimum time.
  1488.      *  This value is used in the JS function quotes_llama_quote()
  1489.      */
  1490.     public function admin_gallery_timer_minimum_callback() { ?>
  1491.  
  1492.         <input type="text"
  1493.             id="gallery_timer_minimum"
  1494.             name="quotes-llama-settings[gallery_timer_minimum]"
  1495.             value="<?php echo $this->plugin_options['gallery_timer_minimum']; ?>"
  1496.             size="5">
  1497.  
  1498.         <label for="gallery_timer_minimum">
  1499.  
  1500.             <?php esc_html_e( "Display quotes for at least this many seconds.", "quotes-llama" ); ?>
  1501.  
  1502.         </label><?php
  1503.  
  1504.     }
  1505.  
  1506.  
  1507.     /*
  1508.      *  Show gallery image checkbox.
  1509.      */
  1510.     public function admin_gallery_image_callback() { ?>
  1511.  
  1512.         <input type="checkbox"
  1513.             id="show_gallery_image"
  1514.             name="quotes-llama-settings[show_gallery_image]"
  1515.             style="display: inline;"
  1516.             <?php if ( $this->check_plugin_option( "show_gallery_image" ) ) echo "checked" ; ?>>
  1517.  
  1518.         <label for="show_gallery_image">
  1519.  
  1520.             <?php esc_html_e( "Display images in the gallery.", "quotes-llama" ); ?>
  1521.  
  1522.         </label><?php
  1523.  
  1524.     }
  1525.  
  1526.  
  1527.     /*
  1528.      *  Sidebar position textfield.
  1529.      */
  1530.     public function admin_sidebar_position_callback() {
  1531.  
  1532.         $sidebar = $this->plugin_options["sidebar"]; ?>
  1533.  
  1534.         <select name="quotes-llama-settings[sidebar]"
  1535.         id="sidebar">
  1536.  
  1537.             <option value="left"<?php if ( "left" == $sidebar ) { echo " selected"; } ?>>
  1538.  
  1539.                 <?php esc_html_e( "Left", "quotes-llama" ); ?>
  1540.  
  1541.             </option>
  1542.  
  1543.             <option value="right"<?php if ( "right" == $sidebar ) { echo " selected"; } ?>>
  1544.  
  1545.                 <?php esc_html_e( "Right", "quotes-llama" ); ?>
  1546.  
  1547.             </option>
  1548.  
  1549.         </select>
  1550.  
  1551.         <label for="sidebar">
  1552.  
  1553.             <?php echo " " . esc_html__( "Align the sidebar.", "quotes-llama" ); ?>
  1554.  
  1555.         </label><?php
  1556.  
  1557.     }
  1558.  
  1559.  
  1560.     /*
  1561.      *  Default orderby droplist.
  1562.      */
  1563.     public function admin_orderby_callback() {
  1564.  
  1565.         $default_sort = $this->plugin_options["default_sort"]; ?>
  1566.  
  1567.         <select name="quotes-llama-settings[default_sort]"
  1568.         id="default_sort">
  1569.  
  1570.             <option value="quote_id"<?php if ( "quote_id" == $default_sort ) { echo " selected"; } ?>>
  1571.  
  1572.                 <?php esc_html_e( "ID", "quotes-llama" ); ?>
  1573.  
  1574.             </option>
  1575.  
  1576.             <option value="quote"<?php if ( "quote" == $default_sort ) { echo " selected"; } ?>>
  1577.  
  1578.                 <?php esc_html_e( "Quote", "quotes-llama" ); ?>
  1579.  
  1580.             </option>
  1581.  
  1582.             <option value="last_name"<?php if ( "last_name" == $default_sort ) { echo " selected"; } ?>>
  1583.  
  1584.                 <?php esc_html_e( "Author", "quotes-llama" ); ?>
  1585.  
  1586.             </option>
  1587.  
  1588.             <option value="source"<?php if ( "source" == $default_sort ) { echo " selected"; } ?>>
  1589.  
  1590.                 <?php esc_html_e( "Source", "quotes-llama" ); ?>
  1591.  
  1592.             </option>
  1593.  
  1594.             <option value="img_url"<?php if ( "img_url" == $default_sort ) { echo " selected"; } ?>>
  1595.  
  1596.                 <?php esc_html_e( "Image", "quotes-llama" ); ?>
  1597.  
  1598.             </option>
  1599.  
  1600.         </select>
  1601.  
  1602.         <label for="default_sort">
  1603.  
  1604.             <?php echo " " . esc_html__( "Sort by column.", "quotes-llama" ); ?>
  1605.  
  1606.         </label><?php
  1607.  
  1608.     }
  1609.  
  1610.  
  1611.     /*
  1612.      *  Default order droplist.
  1613.      */
  1614.     public function admin_order_callback() {
  1615.  
  1616.         $default_order = $this->plugin_options["default_order"]; ?>
  1617.  
  1618.         <select name="quotes-llama-settings[default_order]"
  1619.         id="default_order">
  1620.  
  1621.             <option value="asc"<?php if ( "asc" == $default_order ) { echo " selected"; } ?>>
  1622.  
  1623.                 <?php esc_html_e( "Asc", "quotes-llama" ); ?>
  1624.  
  1625.             </option>
  1626.  
  1627.             <option value="dsc"<?php if ( "dsc" == $default_order ) { echo " selected"; } ?>>
  1628.  
  1629.                 <?php esc_html_e( "Dsc", "quotes-llama" ); ?>
  1630.  
  1631.             </option>
  1632.  
  1633.         </select>
  1634.  
  1635.         <label for="default_order">
  1636.  
  1637.             <?php echo " " . esc_html__( "Ascending/Descending.", "quotes-llama" ); ?>
  1638.  
  1639.         </label><?php
  1640.  
  1641.     }
  1642.  
  1643.  
  1644.     /*
  1645.      *  Background color textfield.
  1646.      */
  1647.     public function admin_background_color_callback() { ?>
  1648.  
  1649.         <input type="text"
  1650.             id="background_color"
  1651.             name="quotes-llama-settings[background_color]"
  1652.             value="<?php echo $this->plugin_options['background_color']; ?>"
  1653.             size="5">
  1654.  
  1655.         <label for="background_color">
  1656.  
  1657.             <?php esc_html_e( "Sets the background color for the quotes page index.", "quotes-llama" ); ?>
  1658.  
  1659.         </label><?php
  1660.  
  1661.     }
  1662.  
  1663.  
  1664.     /*
  1665.      *  Foreground color textfield.
  1666.      */
  1667.     public function admin_foreground_color_callback() { ?>
  1668.  
  1669.         <input type="text"
  1670.             id="foreground_color"
  1671.             name="quotes-llama-settings[foreground_color]"
  1672.             value="<?php echo $this->plugin_options['foreground_color']; ?>"
  1673.             size="5">
  1674.  
  1675.         <label for="foreground_color">
  1676.  
  1677.             <?php esc_html_e( "Sets the foreground color for the quotes page index.", "quotes-llama" ); ?>
  1678.  
  1679.         </label><?php
  1680.  
  1681.     }
  1682.  
  1683.  
  1684.     /*
  1685.      *  Character limit for quotes display.
  1686.      */
  1687.     public function admin_character_limit_callback() { ?>
  1688.  
  1689.         <input type="text"
  1690.             id="character_limit"
  1691.             name="quotes-llama-settings[character_limit]"
  1692.             value="<?php echo $this->plugin_options['character_limit']; ?>"
  1693.             size="5">
  1694.  
  1695.         <label for="character_limit">
  1696.  
  1697.             <?php esc_html_e( "Limit quotes to # of characters. ( 0 = disable limit )", "quotes-llama" ); ?>
  1698.  
  1699.         </label><?php
  1700.  
  1701.     }
  1702.  
  1703.  
  1704.     /*
  1705.      *  Ellipses text to display at end of character limit.
  1706.      */
  1707.     public function admin_ellipses_text_callback() { ?>
  1708.  
  1709.         <input type="text"
  1710.             id="ellipses_text"
  1711.             name="quotes-llama-settings[ellipses_text]"
  1712.             value="<?php echo $this->plugin_options['ellipses_text']; ?>"
  1713.             size="5">
  1714.  
  1715.         <label for="ellipses_text">
  1716.  
  1717.             <?php esc_html_e( "Text that ends the quote limit.", "quotes-llama" ); ?>
  1718.  
  1719.         </label><?php
  1720.  
  1721.     }
  1722.  
  1723.  
  1724.     /*
  1725.      *  Read more text to display at end of limited quote.
  1726.      */
  1727.     public function admin_read_more_text_callback() { ?>
  1728.  
  1729.         <input type="text"
  1730.             id="read_more_text"
  1731.             name="quotes-llama-settings[read_more_text]"
  1732.             value="<?php echo $this->plugin_options['read_more_text']; ?>"
  1733.             size="5">
  1734.  
  1735.         <label for="read_more_text">
  1736.  
  1737.             <?php esc_html_e( "The text to expand the quote.", "quotes-llama" ); ?>
  1738.  
  1739.         </label><?php
  1740.  
  1741.     }
  1742.  
  1743.  
  1744.     /*
  1745.      *  Read less text to display at end of limited quote.
  1746.      */
  1747.     public function admin_read_less_text_callback() { ?>
  1748.  
  1749.         <input type="text"
  1750.             id="read_less_text"
  1751.             name="quotes-llama-settings[read_less_text]"
  1752.             value="<?php echo $this->plugin_options['read_less_text']; ?>"
  1753.             size="5">
  1754.  
  1755.         <label for="read_less_text">
  1756.  
  1757.             <?php esc_html_e( "The text to collapse the quote.", "quotes-llama" ); ?>
  1758.  
  1759.         </label><?php
  1760.  
  1761.     }
  1762.  
  1763.     /*
  1764.      *  Show quote source on a new line instead of comma sepration drop list.
  1765.      */
  1766.     public function admin_source_newline_callback() {
  1767.  
  1768.         $source_newline = $this->plugin_options["source_newline"]; ?>
  1769.  
  1770.         <select name="quotes-llama-settings[source_newline]"
  1771.             id="source_newline">
  1772.  
  1773.             <option value="comma"<?php if ( "comma" == $source_newline ) { echo " selected"; } ?>>
  1774.  
  1775.                 <?php esc_html_e( "Comma [,]", "quotes-llama" ); ?>
  1776.  
  1777.             </option>
  1778.  
  1779.             <option value="br"<?php if ( "br" == $source_newline ) { echo " selected"; } ?>>
  1780.  
  1781.                 <?php esc_html_e( "New Line [<br>]", "quotes-llama" ); ?>
  1782.  
  1783.             </option>
  1784.  
  1785.         </select>
  1786.  
  1787.         <label for="source_newline">
  1788.  
  1789.             <?php esc_html_e( "Separate the author from the source with either a comma or new line.", "quotes-llama" ); ?>
  1790.  
  1791.         </label><?php
  1792.  
  1793.     }
  1794.  
  1795.  
  1796.     /*
  1797.      *  Permission level required to manage plugin
  1798.      *  Administrator or editor only.
  1799.      *  http://codex.wordpress.org/Roles_and_Capabilities
  1800.      */
  1801.     public function admin_permission_level_callback() {
  1802.  
  1803.         $permission_level = $this->plugin_options["permission_level"]; ?>
  1804.  
  1805.         <select name="quotes-llama-settings[permission_level]"
  1806.             id="permission_level">
  1807.  
  1808.             <option value="create_users"<?php if ( "create_users" == $permission_level ) { echo " selected"; } ?>>
  1809.  
  1810.                 <?php esc_html_e( "Administrators", "quotes-llama" ); ?>
  1811.  
  1812.             </option>
  1813.  
  1814.             <option value="edit_pages"<?php if ( "edit_pages" == $permission_level ) { echo " selected"; } ?>>
  1815.  
  1816.                 <?php esc_html_e( "Editors", "quotes-llama" ); ?>
  1817.  
  1818.             </option>
  1819.  
  1820.         </select>
  1821.  
  1822.         <label for="permission_level">
  1823.  
  1824.             <?php echo " " . esc_html__( "Set the role which has permission to manage this plugin.", "quotes-llama" ); ?>
  1825.  
  1826.         </label><?php
  1827.  
  1828.     }
  1829.  
  1830.  
  1831.     /*
  1832.      *  Reset options checkbox in admin options.
  1833.      */
  1834.     public function admin_reset_callback() { ?>
  1835.  
  1836.         <input type="checkbox"
  1837.             id="admin_reset"
  1838.             name="quotes-llama-settings[admin_reset]"
  1839.             style="display: inline;"
  1840.             <?php if( isset( $this->plugin_options["admin_reset"] ) && $this->plugin_options["admin_reset"] == "on" ) echo "checked" ; ?>>
  1841.  
  1842.             <label for="admin_reset">
  1843.  
  1844.                 <?php esc_html_e( "Reset plugin options to their defaults when deactivating this plugin.", "quotes-llama" ); ?>
  1845.  
  1846.             </label><?php
  1847.  
  1848.     }
  1849.  
  1850.  
  1851.     /*
  1852.      *  CSV Export Delimiter.
  1853.      */
  1854.     public function admin_export_delimiter_callback() { ?>
  1855.  
  1856.         <input type="text"
  1857.             id="export_delimiter"
  1858.             name="quotes-llama-settings[export_delimiter]"
  1859.             style="display: inline;"
  1860.             value="<?php echo $this->check_plugin_option( "export_delimiter" ); ?>"
  1861.             size="3">
  1862.  
  1863.             <label for="export_delimiter">
  1864.  
  1865.                 <?php esc_html_e( ".csv delimiter.", "quotes-llama" );
  1866.  
  1867.                 echo "<cite> " . esc_html__( "Field separator for importing and exporting quotes in .csv format.", "quotes-llama" ) . "</cite>"; ?>
  1868.  
  1869.             </label><?php
  1870.  
  1871.     }
  1872.  
  1873.  
  1874.     /*
  1875.      *  widget page link.
  1876.      */
  1877.     public function admin_widget_page_callback() {
  1878.  
  1879.         esc_html_e( "Widget options are set in the", "quotes-llama" );
  1880.         echo " <a href='" . get_bloginfo("wpurl") . "/wp-admin/widgets.php'>";
  1881.         esc_html_e( "widgets page", "quotes-llama" );
  1882.         echo "</a>.";
  1883.  
  1884.     }
  1885.  
  1886.  
  1887.     /*
  1888.      *  Admin form sanitization.
  1889.      *
  1890.      *  @param Array $input - Array of options to sanitize.
  1891.      *
  1892.      *  @return Array - Sanitized array of options.
  1893.      */
  1894.     public function admin_sanitize( $input ) {
  1895.  
  1896.         if ( ! $input ) return;
  1897.  
  1898.         // Initialize the new array that will hold the sanitize values
  1899.         $new_input = array();
  1900.  
  1901.         // Loop through the input and sanitize each of the values
  1902.         // http://codex.wordpress.org/Function_Reference/sanitize_text_field
  1903.         foreach ( $input as $key => $val ) {
  1904.  
  1905.             $new_input[ $key ] = ( isset( $input[ $key ] ) ) ?
  1906.  
  1907.             sanitize_text_field( $val ) : "";
  1908.  
  1909.         }
  1910.  
  1911.         return $new_input;
  1912.  
  1913.     }
  1914.  
  1915.  
  1916.     /*
  1917.      *  Add or edit a quote
  1918.      *
  1919.      *  @param int $quote_id - id of quote to edit.
  1920.      *
  1921.      *  heredocs http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
  1922.      *  http://codex.wordpress.org/Function_Reference/wp_nonce_field
  1923.      */
  1924.     public function quotes_form( $quote_id = 0, $return_page = "" ) {
  1925.  
  1926.         // Default submit value is empty fields to add new quote.
  1927.         $submit_value = __( "Add Quote", "quotes-llama" );
  1928.  
  1929.         // Default form name.
  1930.         $form_name = "addquote";
  1931.  
  1932.         // Default action url.
  1933.         $action_url = get_bloginfo("wpurl")."/wp-admin/admin.php?page=quotes-llama#addnew";
  1934.  
  1935.         $quote = $first_name = $last_name = $source = $img_url = $hidden_input = $back = "";
  1936.  
  1937.         // If id, then editing a quote, set form name to edit.
  1938.         if ( $quote_id ) {
  1939.  
  1940.             $form_name = "editquote";
  1941.             $quote_data = $this->quotes_select( $quote_id );
  1942.  
  1943.             foreach ( $quote_data as $index => $value ) {
  1944.  
  1945.                 $quote_data[$index] = $quote_data[$index];
  1946.  
  1947.             }
  1948.  
  1949.             $hidden_input = "<input type=\"hidden\" name=\"quote_id\" value=\"{$quote_id}\" />";
  1950.             $submit_value = esc_html__( "Save Quote", "quotes-llama" );
  1951.             $back = "<input type='submit' name='submit' value='" . esc_html__( 'Back', 'quotes-llama' ) . "'>&nbsp;";
  1952.             $action_url = get_bloginfo( "wpurl" )."/wp-admin/admin.php?page=quotes-llama" . $return_page;
  1953.  
  1954.             // Set each table field from $quote_data.
  1955.             $quote = $this->strip_trim_wp_kses_post( $quote_data['quote'] );
  1956.             $first_name = $this->strip_trim_wp_kses_post( $quote_data['first_name'] );
  1957.             $last_name = $this->strip_trim_wp_kses_post( $quote_data['last_name'] );
  1958.             $source = $this->strip_trim_wp_kses_post( $quote_data['source'] );
  1959.             $img_url = $this->strip_trim_wp_kses_post( $quote_data['img_url'] );
  1960.  
  1961.         }
  1962.  
  1963.         $quote_label = esc_html__( "Quote", "quotes-llama" );
  1964.         $first_label = esc_html__( "First Name", "quotes-llama" );
  1965.         $last_label = esc_html__( "Last Name", "quotes-llama" );
  1966.         $source_label = esc_html__( "Source", "quotes-llama" );
  1967.         $imgurl_label = esc_html__( "Image URL", "quotes-llama" );
  1968.         $img_button = "<button class='quotes-llama-media-button'>Select image</button>";
  1969.         $security = wp_nonce_field( "quotes_llama_form", "security" );
  1970.         $quotes_edit_heredoc = <<< quotes_edit_heredoc
  1971.  
  1972.         <form name="{$form_name}"
  1973.             method="post"
  1974.             action="{$action_url}">
  1975.  
  1976.                 {$hidden_input}
  1977.  
  1978.                 {$security}
  1979.  
  1980.             <table class="form-table"
  1981.                 cellpadding="5"
  1982.                 cellspacing="2"
  1983.                 width="100%">
  1984.  
  1985.                 <tbody>
  1986.  
  1987.                     <tr class="form-field form-required">
  1988.  
  1989.                         <th style="text-align:left;"
  1990.                             scope="row"
  1991.                             valign="top">
  1992.  
  1993.                             <label for="quotes_llama_quote">
  1994.  
  1995.                                 {$quote_label}
  1996.  
  1997.                             </label>
  1998.  
  1999.                         </th>
  2000.  
  2001.                         <td>
  2002.  
  2003.                             <textarea id="quotes_llama_quote"
  2004.                                 name="quote"
  2005.                                 rows="5"
  2006.                                 cols="50"
  2007.                                 style="width: 97%;">{$quote}</textarea>
  2008.  
  2009.                         </td>
  2010.  
  2011.                     </tr>
  2012.  
  2013.                     <tr class="form-field">
  2014.  
  2015.                         <th style="text-align:left;"
  2016.                             scope="row"
  2017.                             valign="top">
  2018.  
  2019.                             <label for="quotes-llama-widget-author">
  2020.  
  2021.                                 {$first_label}
  2022.  
  2023.                             </label>
  2024.  
  2025.                         </th>
  2026.  
  2027.                         <td>
  2028.  
  2029.                             <input type="text"
  2030.                                 id="quotes-llama-widget-author"
  2031.                                 name="first_name"
  2032.                                 size="40"
  2033.                                 value="{$first_name}"
  2034.                                 placeholder="optional">
  2035.  
  2036.                         </td>
  2037.  
  2038.                     </tr>
  2039.  
  2040.                     <tr class="form-field">
  2041.  
  2042.                         <th style="text-align:left;"
  2043.                             scope="row"
  2044.                             valign="top">
  2045.  
  2046.                             <label for="quotes-llama-widget-author">
  2047.  
  2048.                                 {$last_label}
  2049.  
  2050.                             </label>
  2051.  
  2052.                         </th>
  2053.  
  2054.                         <td>
  2055.  
  2056.                             <input type="text"
  2057.                                 id="quotes-llama-widget-author"
  2058.                                 name="last_name"
  2059.                                 size="40"
  2060.                                 value="{$last_name}"
  2061.                                 placeholder="optional">
  2062.  
  2063.                         </td>
  2064.  
  2065.                     </tr>
  2066.  
  2067.                     <tr class="form-field">
  2068.  
  2069.                         <th style="text-align:left;"
  2070.                             scope="row"
  2071.                             valign="top">
  2072.  
  2073.                             <label for="quotes_llama_source">
  2074.  
  2075.                                 {$source_label}
  2076.  
  2077.                             </label>
  2078.  
  2079.                         </th>
  2080.  
  2081.                         <td>
  2082.  
  2083.                             <input type="text"
  2084.                                 id="quotes_llama_source"
  2085.                                 name="source"
  2086.                                 size="40"
  2087.                                 value="{$source}"
  2088.                                 placeholder="optional">
  2089.  
  2090.                         </td>
  2091.  
  2092.                     </tr>
  2093.  
  2094.                     <tr class="form-field">
  2095.  
  2096.                         <th style="text-align:left;"
  2097.                             scope="row"
  2098.                             valign="top">
  2099.  
  2100.                             <label for="quotes_llama_imgurl">
  2101.  
  2102.                                 {$imgurl_label}
  2103.  
  2104.                             </label>
  2105.  
  2106.                         </th>
  2107.  
  2108.                         <td>
  2109.  
  2110.                             <input type="text"
  2111.                                 id="quotes_llama_imgurl"
  2112.                                 name="img_url"
  2113.                                 size="40"
  2114.                                 value="{$img_url}"
  2115.                                 placeholder="optional">
  2116.  
  2117.                             {$img_button}
  2118.  
  2119.                         </td>
  2120.  
  2121.                     </tr>
  2122.  
  2123.                 </tbody>
  2124.  
  2125.             </table>
  2126.  
  2127.             <p class="submit">
  2128.  
  2129.                 {$back}
  2130.  
  2131.                 <input name="submit"
  2132.                     value="{$submit_value}"
  2133.                     type="submit"
  2134.                     class="button button-primary">
  2135.  
  2136.             </p>
  2137.  
  2138.         </form>
  2139.  
  2140. quotes_edit_heredoc;
  2141. // There can be no spaces or tabs or anything on same line as quotes_edit_heredoc;.
  2142.  
  2143.         return $quotes_edit_heredoc;
  2144.  
  2145.     } // End quotes_form
  2146.  
  2147.  
  2148.     /*
  2149.      *  Add a new quote to the database.
  2150.      *
  2151.      *  @param string $quote required - The text to be quoted.
  2152.      *  @param string $first_name - Authors first and middle name.
  2153.      *  @param string $last_name - Authors last name.
  2154.      *  @param string $source - The source text.
  2155.      *  @param string $img_url - The url to an image file.
  2156.      *
  2157.      *  @return string - Message of result.
  2158.      */
  2159.     public function quotes_insert( $quote, $first_name = "", $last_name = "", $source = "", $img_url = "" ) {
  2160.  
  2161.         global $allowedposttags;
  2162.  
  2163.         if ( ! $quote ) {
  2164.  
  2165.             return "<div class='error'>" . __( "There was no quote to add to the database.", "quotes-llama" ) . "</div>";
  2166.  
  2167.         }
  2168.  
  2169.         global $wpdb;
  2170.  
  2171.         if ( $wpdb->get_var("SHOW TABLES LIKE '$this->table_name'") != $this->table_name ) {
  2172.  
  2173.             return "<div class='error'>" . esc_html__("Database table not found!", "quotes-llama") . "</div>";
  2174.  
  2175.         } else {
  2176.  
  2177.             // Validate data before insert.
  2178.             $quote = $this->validate( $quote );
  2179.             $first_name = $this->validate( $first_name );
  2180.             $last_name = $this->validate( $last_name );
  2181.             $source = $this->validate( $source );
  2182.             $img_url = $this->validate( $img_url );
  2183.  
  2184.             // Insert - handles prepare.
  2185.             // http://codex.wordpress.org/Class_Reference/wpdb#INSERT_row
  2186.             $results = $wpdb->insert(
  2187.                 $this->table_name,
  2188.                 array(
  2189.                     "quote" => $quote,
  2190.                     "first_name" => $first_name,
  2191.                     "last_name" => $last_name,
  2192.                     "source" => $source,
  2193.                     "img_url" => $img_url
  2194.                 ),
  2195.                 array( "%s", "%s", "%s", "%s", "%s" )
  2196.             );
  2197.  
  2198.             if ( FALSE === $results ) {
  2199.  
  2200.                 return "<div class='error'>" . esc_html__("An error occurred in the MySQL query.", "quotes-llama") . "</div>";
  2201.  
  2202.             } else {
  2203.  
  2204.                 return "<div class='updated'>" . esc_html__("Quote Added", "quotes-llama") . "</div>";
  2205.  
  2206.             }
  2207.  
  2208.         }
  2209.  
  2210.     }
  2211.  
  2212.  
  2213.     /*
  2214.      *  Update a quote.
  2215.      *
  2216.      *  @param string $quote_id required - The id of the quote in the database.
  2217.      *  @param string $quote required - The text to be quoted.
  2218.      *  @param string $first_name - Authors first and middle name.
  2219.      *  @param string $last_name - Authors last name.
  2220.      *  @param string $source - The source text.
  2221.      *  @param string $img_url - The url to an image file.
  2222.      *
  2223.      *  @return string - Message of result.
  2224.      */
  2225.     public function quotes_update( $quote_id, $quote, $first_name = "", $last_name = "", $source = "", $img_url = "" ) {
  2226.  
  2227.         global $allowedposttags;
  2228.  
  2229.         if ( ! $quote ) {
  2230.  
  2231.             return "<div class='error'>" . esc_html__( "Quote not updated.", "quotes-llama" ) . "</div>";
  2232.  
  2233.         }
  2234.  
  2235.         global $wpdb;
  2236.  
  2237.         if ( $wpdb->get_var( "SHOW TABLES LIKE '$this->table_name'" ) != $this->table_name ) {
  2238.  
  2239.             return "<div class='error'>" . esc_html__( "Quotes llama database table not found", "quotes-llama" ) . "</div>";
  2240.  
  2241.         } else {
  2242.  
  2243.             // Validate data before insert.
  2244.             $quote = $this->validate( $quote );
  2245.             $first_name = $this->validate( $first_name );
  2246.             $last_name = $this->validate( $last_name );
  2247.             $source = $this->validate( $source );
  2248.             $img_url = $this->validate( $img_url );
  2249.  
  2250.             // http://codex.wordpress.org/Class_Reference/wpdb#UPDATE_rows
  2251.             $results = $wpdb->update(
  2252.                 $this->table_name,
  2253.                 array(
  2254.                     "quote" => $quote,
  2255.                     "first_name" => $first_name,
  2256.                     "last_name" => $last_name,
  2257.                     "source" => $source,
  2258.                     "img_url" => $img_url
  2259.                 ),
  2260.                 array( "quote_id" => $quote_id ),
  2261.                 array( "%s", "%s", "%s", "%s", "%s" )
  2262.             );
  2263.  
  2264.             if ( false === $results ) {
  2265.  
  2266.                 return "<div class='error'>" . esc_html__( "There was an error in the MySQL query.", "quotes-llama" ) . "</div>";
  2267.  
  2268.             } else {
  2269.  
  2270.                 return "<div class='updated'>" . esc_html__( "Quote Saved", "quotes-llama" ) . "</div>";
  2271.  
  2272.             }
  2273.  
  2274.         }
  2275.  
  2276.     }
  2277.  
  2278.  
  2279.     /*
  2280.      *  Delete a single quote.
  2281.      *
  2282.      *  @param int $quote_id - The quote_id of the quote to delete in the database.
  2283.      *
  2284.      *  @return string - Message of result.
  2285.      */
  2286.     public function quotes_delete( $quote_id ) {
  2287.  
  2288.         if ( $quote_id ) {
  2289.  
  2290.             global $wpdb;
  2291.  
  2292.             // http://codex.wordpress.org/Class_Reference/wpdb#DELETE_Rows
  2293.             $result = $wpdb->delete( $this->table_name, array( "quote_id" => $quote_id ) );
  2294.  
  2295.             if ( false === $result ) {
  2296.  
  2297.                 return "<div class='error'>" . esc_html__( "There was an error in the MySQL query.", "quotes-llama" ) . "</div>";
  2298.  
  2299.             } else {
  2300.  
  2301.                 return "<div class='updated'>" . esc_html__( "Quote Deleted", "quotes-llama" ) . "</div>";
  2302.  
  2303.             }
  2304.  
  2305.         } else {
  2306.  
  2307.             return "<div class='error'>" . esc_html__( "Quote cannot be deleted.", "quotes-llama" ) . "</div>";
  2308.  
  2309.         }
  2310.  
  2311.     }
  2312.  
  2313.  
  2314.     /*
  2315.      *  Bulk delete quotes.
  2316.      *
  2317.      *  @param Array $quote_ids - Array of ids to delete.
  2318.      *
  2319.      *  @return string message of result.
  2320.      */
  2321.     public function quotes_delete_bulk( $quote_ids ) {
  2322.  
  2323.         if ( $quote_ids ) {
  2324.  
  2325.             global $wpdb;
  2326.  
  2327.             // Count the number of checkboxes.
  2328.             $id_count = count( $quote_ids );
  2329.  
  2330.             // Prepare the placeholders array for ->prepare() it needs a string of the values.
  2331.             // http://php.net/manual/en/function.array-fill.php
  2332.             $id_holder = array_fill( 0, $id_count, "%s" );
  2333.  
  2334.             // Create one string from placeholders %s, %s, %s, %s, %s.
  2335.             $holders_id = "( " . implode( ", ", $id_holder ) . " )";
  2336.  
  2337.             // Create delete bulk query string.
  2338.             $query = "DELETE FROM " . $this->table_name . " WHERE quote_id IN " . $holders_id;
  2339.  
  2340.             // Delete rows.
  2341.             $result = $wpdb->query( $wpdb->prepare( $query, $quote_ids ) );
  2342.  
  2343.             if ( $result ) {
  2344.  
  2345.                 return "<div class='updated'>" . esc_html__( "Quotes Deleted", "quotes-llama" ) . "</div>";
  2346.  
  2347.             } else {
  2348.  
  2349.                 return "<div class='error'>" . esc_html__( "Unable to delete quotes.", "quotes-llama" ) . "</div>";
  2350.  
  2351.             }
  2352.  
  2353.         } else {
  2354.  
  2355.             return "<div class='error'>" . esc_html__( "No quotes selected.", "quotes-llama" ) . "</div>";
  2356.  
  2357.         }
  2358.  
  2359.     }
  2360.  
  2361.  
  2362.     /*
  2363.      *  Get quotes for widget, gallery, page, search, and random requests
  2364.      *
  2365.      *  @param int $quote_id - id of quote to get or type of quote
  2366.      *
  2367.      *  @return result array.
  2368.      */
  2369.     public function quotes_select( $quote_id = 0 ) {
  2370.  
  2371.         global $wpdb;
  2372.  
  2373.         // Get quote by id for manage quotes page and static quote id on pages etc.
  2374.         if ( is_numeric( $quote_id ) && $quote_id > 0 ) {
  2375.  
  2376.             $quote = $wpdb->prepare( "SELECT
  2377.                 quote_id,
  2378.                 quote,
  2379.                 first_name,
  2380.                 last_name,
  2381.                 source,
  2382.                 img_url FROM " . $this->table_name .
  2383.                 " WHERE quote_id = %d", $quote_id );
  2384.  
  2385.             $quote_data = $wpdb->get_row( $quote, ARRAY_A );
  2386.  
  2387.             return $quote_data;
  2388.  
  2389.         }
  2390.  
  2391.         // Page, Get authors first, last name for sidebar author list.
  2392.         if ( $quote_id == "author_list" ) {
  2393.  
  2394.             $authors_data = "SELECT first_name, last_name, count(first_name) AS quotecount FROM " .
  2395.                 $this->table_name . " GROUP BY last_name, first_name ORDER BY last_name";
  2396.  
  2397.             $authors = $wpdb->get_results( $authors_data );
  2398.  
  2399.             return $authors;
  2400.  
  2401.         }
  2402.  
  2403.         // Widget and Gallery, Get random quote for .ajax request or function call.
  2404.         // Echo and cancel .ajax return or return data.
  2405.         if ( $quote_id == "random" || isset( $_REQUEST["random"] ) ) {
  2406.  
  2407.                 $sql = "SELECT quote, first_name, last_name, source, img_url
  2408.                         FROM " . $this->table_name .
  2409.                         " ORDER BY RAND() LIMIT 1";
  2410.  
  2411.                 $quote_data = $wpdb->get_row( $sql, ARRAY_A );
  2412.  
  2413.                 if ( isset( $_REQUEST["random"] ) ) {
  2414.  
  2415.                     echo json_encode( $quote_data );
  2416.  
  2417.                     die();
  2418.  
  2419.                 }
  2420.  
  2421.                 if ( $quote_id == "random" ) {
  2422.  
  2423.                     return $quote_data;
  2424.  
  2425.                 }
  2426.  
  2427.         }
  2428.  
  2429.         // Page, Get all quotes for author in sidebar.
  2430.         if ( isset( $_REQUEST["quotes_by_author"] ) ) {
  2431.  
  2432.             // http://codex.wordpress.org/Function_Reference/wp_verify_nonce
  2433.             if ( isset( $_REQUEST["security"] ) && wp_verify_nonce( $_REQUEST["security"], "quotes_llama_page" ) ) {
  2434.  
  2435.                 // .ajax request first name.
  2436.                 if ( isset( $_REQUEST["first"] ) && $_REQUEST["first"] != "" ) {
  2437.  
  2438.                     $first = $_REQUEST["first"];
  2439.  
  2440.                 } else {
  2441.  
  2442.                     $first = false;
  2443.  
  2444.                 }
  2445.  
  2446.                 // .ajax request last name.
  2447.                 if ( isset( $_REQUEST["last"] ) && $_REQUEST["last"] != "" ) {
  2448.  
  2449.                     $last = $_REQUEST["last"];
  2450.  
  2451.                 } else {
  2452.  
  2453.                     $last = false;
  2454.  
  2455.                 }
  2456.  
  2457.                 if ( $first && $last ) {
  2458.  
  2459.                     $quotes = $wpdb->get_results( $wpdb->prepare( "SELECT quote,
  2460.                         first_name,
  2461.                         last_name,
  2462.                         source,
  2463.                         img_url FROM " . $this->table_name .
  2464.                         " WHERE first_name = '%s' AND last_name = '%s'
  2465.                         ORDER BY last_name, first_name", $first, $last ) );
  2466.  
  2467.                 // http://php.net/manual/en/function.empty.php
  2468.                 } elseif ( $first && empty( $last ) ) {
  2469.  
  2470.                     $quotes = $wpdb->get_results( $wpdb->prepare( "SELECT quote,
  2471.                         first_name,
  2472.                         last_name,
  2473.                         source,
  2474.                         img_url FROM " . $this->table_name .
  2475.                         " WHERE first_name = '%s' ORDER BY first_name", $first ) );
  2476.  
  2477.                 } elseif ( empty( $first ) && $last ) {
  2478.  
  2479.                     $quotes = $wpdb->get_results( $wpdb->prepare( "SELECT quote,
  2480.                         first_name,
  2481.                         last_name,
  2482.                         source,
  2483.                         img_url FROM " . $this->table_name .
  2484.                         " WHERE last_name = '%s' ORDER BY last_name", $last ) );
  2485.  
  2486.                 }
  2487.  
  2488.                 // Render results.
  2489.                 $this->template_page_author( $quotes );
  2490.  
  2491.                 die();
  2492.  
  2493.             } else {
  2494.  
  2495.                 echo "<div class='error'><p>" . __( "Security token mismatch, please reload the page and try again.", "quotes-llama" ) . "</p></div>";
  2496.  
  2497.             }
  2498.  
  2499.         }
  2500.  
  2501.         // Page, Search for quote.
  2502.         if ( isset ( $_REQUEST["search_for_quote"] ) ) {
  2503.  
  2504.             // Check nonce
  2505.             if ( isset( $_REQUEST["security"] ) && wp_verify_nonce( $_REQUEST["security"], "quotes_llama_page" ) ) {
  2506.  
  2507.                 if ( isset ( $_REQUEST["term"] ) ) {
  2508.  
  2509.                     $term = $_REQUEST["term"];
  2510.  
  2511.                 } else {
  2512.  
  2513.                     $term = "";
  2514.  
  2515.                 }
  2516.  
  2517.                 if ( isset ( $_REQUEST["search_column"] ) ) {
  2518.  
  2519.                     $search_column = $_REQUEST["search_column"];
  2520.  
  2521.                 } else {
  2522.  
  2523.                     $search_column = "quote";
  2524.  
  2525.                 }
  2526.  
  2527.                 $quotes = $wpdb->get_results( $wpdb->prepare( "SELECT quote,
  2528.                     first_name,
  2529.                     last_name,
  2530.                     source,
  2531.                     img_url FROM " . $this->table_name .
  2532.                     " WHERE $search_column LIKE '%%%s%%'
  2533.                     ORDER BY last_name, first_name", $term ) );
  2534.  
  2535.                 // Render results.
  2536.                 $this->template_page_search( $quotes );
  2537.  
  2538.                 die();
  2539.  
  2540.             } else {
  2541.  
  2542.                 echo "<div class='error'><p>" . __( "Security token mismatch, please reload the page and try again.", "quotes-llama" ) . "</p></div>";
  2543.  
  2544.             }
  2545.  
  2546.         }
  2547.  
  2548.     }
  2549.  
  2550.  
  2551.     /*
  2552.      *  Check if an option isset
  2553.      *
  2554.      *  @param string $option - the option to check on.
  2555.      *
  2556.      *  @return mixed - false if no option or option string if found.
  2557.      */
  2558.     public function check_plugin_option( $option ) {
  2559.  
  2560.         if ( ! $option ) {
  2561.  
  2562.             return false;
  2563.  
  2564.         }
  2565.  
  2566.         if ( isset ( $this->plugin_options["$option"] ) ) {
  2567.  
  2568.             return $this->plugin_options["$option"];
  2569.  
  2570.         } else {
  2571.  
  2572.             return false;
  2573.  
  2574.         }
  2575.  
  2576.     }
  2577.  
  2578.  
  2579.     /*
  2580.      *  Run stripslashes(), trim() and wp_kses_post on string for output to display.
  2581.      *
  2582.      *  @param string $str - String to sanitize.
  2583.      *
  2584.      *  @return string - Escaped string with no /'s or whitespace but with allowed html tags.
  2585.      */
  2586.     public function strip_trim_wp_kses_post( $str ) {
  2587.  
  2588.         // http://php.net/manual/en/function.stripslashes.php
  2589.         // http://php.net/manual/en/function.trim.php
  2590.         // https://codex.wordpress.org/Function_Reference/wp_kses_post
  2591.         $str = stripslashes( wp_kses_post( trim( $str ) ) );
  2592.  
  2593.         return $str;
  2594.  
  2595.     }
  2596.  
  2597.  
  2598.     /*
  2599.      *  Run stripslashes(), trim() and esc_attr on string for output to display.
  2600.      *
  2601.      *  @param string $str - String to sanitize.
  2602.      *
  2603.      *  @return string - Escaped string with no /'s or whitespace.
  2604.      */
  2605.     public function strip_trim_esc_attr( $str ) {
  2606.  
  2607.         // http://codex.wordpress.org/Function_Reference/esc_attr
  2608.         $str = stripslashes( esc_attr( trim( $str ) ) );
  2609.  
  2610.         return $str;
  2611.  
  2612.     }
  2613.  
  2614.  
  2615.     /*
  2616.      *  Run stripslashes(), trim() and esc_url on string for output to display.
  2617.      *
  2618.      *  @param string $str - String to sanitize.
  2619.      *
  2620.      *  @return string - Escaped string with no /'s or whitespace.
  2621.      */
  2622.     public function strip_trim_esc_url( $str ) {
  2623.  
  2624.         // http://codex.wordpress.org/Function_Reference/esc_url
  2625.         $str = stripslashes( esc_url( trim( $str ) ) );
  2626.  
  2627.         return $str;
  2628.  
  2629.     }
  2630.  
  2631.  
  2632.     /*
  2633.      *  Renders page view [quotes-llama mode='page']
  2634.      *  Lists all the authors and search form.
  2635.      *
  2636.      *  @return String - must return string, not echo or display or will render at top of page regardless of positioning.
  2637.      */
  2638.     public function template_page() {
  2639.  
  2640.         global $wpdb;
  2641.  
  2642.         // http://codex.wordpress.org/Function_Reference/wp_create_nonce
  2643.         $security = wp_create_nonce( "quotes_llama_page" );
  2644.  
  2645.         // Get sort from options.
  2646.         $default_sort = $this->plugin_options["default_sort"];
  2647.  
  2648.         // Our logged in heredoc holder.
  2649.         $template_page_loggedin = "";
  2650.  
  2651.         // Display search form if logged in.
  2652.         if ( is_user_logged_in() ) {
  2653.  
  2654.             // heredoc vars
  2655.             $search_text = esc_html__( "Search", "quotes-llama" );
  2656.             $search_column_quote = "";
  2657.             $search_column_quote_title = esc_html__( "Quote", "quotes-llama" );
  2658.             $search_column_first_name = "";
  2659.             $search_column_first_name_title = esc_html__( "First Name", "quotes-llama" );
  2660.             $search_column_last_name = "";
  2661.             $search_column_last_name_title = esc_html__( "Last Name", "quotes-llama" );
  2662.             $search_column_source = "";
  2663.             $search_column_source_title = esc_html__( "Source", "quotes-llama" );
  2664.             $search_column_img_url = "";
  2665.             $search_column_img_url_title = esc_html__( "Img URL", "quotes-llama" );
  2666.  
  2667.             if ( isset( $_REQUEST["search_column"] ) ) {
  2668.  
  2669.                 switch ( $_REQUEST["search_column"] ) {
  2670.  
  2671.                     case "quote":
  2672.                         $search_column_quote = " selected";
  2673.                         break;
  2674.                     case "first_name":
  2675.                         $search_column_first_name = " selected";
  2676.                         break;
  2677.                     case "last_name":
  2678.                         $search_column_last_name = " selected";
  2679.                         break;
  2680.                     case "source":
  2681.                         $search_column_source = " selected";
  2682.                         break;
  2683.                     case "img_url":
  2684.                         $search_column_img_url = " selected";
  2685.                         break;
  2686.                     default:
  2687.                         $search_column_quote = " selected";
  2688.  
  2689.                 }
  2690.  
  2691.             }
  2692.  
  2693.             // Start logged in heredoc - display search box
  2694.             $template_page_loggedin = '<div class="quotes-llama-page-quotes-form">' .
  2695.  
  2696.                 '<input type="text" ' .
  2697.                     'class="quotes-llama-page-quotesearch" ' .
  2698.                     'id="quotes-llama-page-quotesearch" ' .
  2699.                     'name="quotes-llama-page-quotesearch" ' .
  2700.                     'security="' . $security . '" ' .
  2701.                     'size="20">' .
  2702.  
  2703.                 '<button ' .
  2704.                     'class="quotes-llama-page-searchbutton" ' .
  2705.                     'id="quotes-llama-page-searchbutton" ' .
  2706.                     'name="quotes-llama-page-searchbutton" ' .
  2707.                     'size="30">' .
  2708.  
  2709.                         $search_text .
  2710.  
  2711.                 '</button>' .
  2712.  
  2713.                 '<select name="search_column" class="search_column">' .
  2714.  
  2715.                     '<option value="quote">' .
  2716.  
  2717.                         $search_column_quote_title .
  2718.  
  2719.                     '</option>' .
  2720.  
  2721.  
  2722.                     '<option value="first_name">' .
  2723.  
  2724.                         $search_column_first_name_title .
  2725.  
  2726.                     '</option>' .
  2727.  
  2728.                     '<option value="last_name">' .
  2729.  
  2730.                         $search_column_last_name_title .
  2731.  
  2732.                     '</option>' .
  2733.  
  2734.                     '<option value="source">' .
  2735.  
  2736.                         $search_column_source_title .
  2737.  
  2738.                     '</option>' .
  2739.  
  2740.                     '<option value="img_url">' .
  2741.  
  2742.                         $search_column_img_url_title .
  2743.  
  2744.                     '</option>' .
  2745.  
  2746.                 '</select>' .
  2747.  
  2748.             '</div>';
  2749.  
  2750.         }
  2751.  
  2752.         // Build list of authors for page selection.
  2753.         $quotesresult = $this->quotes_select( "author_list" );
  2754.         $firstLetterIndexedArray = array();
  2755.         $header_letter_list = "";
  2756.         $author_link_list = "";
  2757.         $quotes_title = esc_html__( "Quotes", "quotes-llama" );
  2758.         $current_letter = "";
  2759.         $initial_quote = do_shortcode( "[quotes-llama]" );
  2760.  
  2761.         // Iteration indicator for adding letter separator.
  2762.         $current_quote_data = "";
  2763.  
  2764.         foreach ( $quotesresult as $quoteresult ) {
  2765.  
  2766.             // Total number of quotes.
  2767.             $countofquote = $quoteresult->quotecount;
  2768.  
  2769.             // First and middle name.
  2770.             $first_name = trim( $quoteresult->first_name );
  2771.  
  2772.             // Last name.
  2773.             $last_name = trim( $quoteresult->last_name );
  2774.  
  2775.             // Does this author have both first and last name.
  2776.             if ( $last_name ) {
  2777.  
  2778.                 $name_index = strtoupper( substr( $last_name, 0, 1 ) );
  2779.  
  2780.             } else {
  2781.  
  2782.                 $name_index = strtoupper( substr( $first_name, 0, 1 ) );
  2783.  
  2784.             }
  2785.  
  2786.             // Add index letter to array.
  2787.             $firstLetterIndexedArray[] = array( "index" => $name_index, "last" => $last_name, "count" => $countofquote, "first" => $first_name );
  2788.  
  2789.         }
  2790.  
  2791.         // Sort the index array.
  2792.         sort( $firstLetterIndexedArray );
  2793.  
  2794.         // Build string of header letter links from index array.
  2795.         foreach ( $firstLetterIndexedArray as $letter ) {
  2796.  
  2797.             if ( $current_letter != $letter["index"] ) {
  2798.  
  2799.                 $header_letter_list .= '<a href="#' . $letter["index"] . '"><button>' . $this->strip_trim_wp_kses_post( $letter["index"] ) . '</button></a>';
  2800.  
  2801.                 $current_letter = $letter["index"];
  2802.  
  2803.             }
  2804.  
  2805.         }
  2806.  
  2807.         // Build string of author links from index array.
  2808.         foreach ( $firstLetterIndexedArray as $quote_data ) {
  2809.  
  2810.             if ( $current_quote_data == $quote_data["index"] ) {
  2811.  
  2812.                 // Add just the author if separator already added.
  2813.                 $author_link_list .= '<li><a class="quotes-llama-page-link" ' .
  2814.                         'name="' . $this->strip_trim_esc_attr( $quote_data["first"] . '" "' . $quote_data["last"] ) . '" ' .
  2815.                         'first="' . $this->strip_trim_esc_attr( $quote_data["first"] ) . '" ' .
  2816.                         'last="' . $this->strip_trim_esc_attr( $quote_data["last"] ) . '" ' .
  2817.                         'security="' . $security . '" ' .
  2818.                         'href="#quotes-llama-page-print" ' .
  2819.                         'title="' . $this->strip_trim_esc_attr( $quote_data["first"] . '" "' . $quote_data["last"] ) . '">';
  2820.  
  2821.                 // if first and last name
  2822.                 if ( $quote_data["last"] ) {
  2823.  
  2824.                     $author_link_list .= $this->strip_trim_wp_kses_post( $quote_data["last"] . ", " . $quote_data["first"] );
  2825.  
  2826.                 } else {
  2827.  
  2828.                     $author_link_list .= $this->strip_trim_wp_kses_post( $quote_data["first"] );
  2829.  
  2830.                 }
  2831.  
  2832.                 $author_link_list .= '</a></li>';
  2833.  
  2834.             } else {
  2835.  
  2836.                 // Add letter to sidebar separator and add author.
  2837.                 $author_link_list .= '<div class="quotes-llama-page-letter">' .
  2838.                         '<a name="' . $this->strip_trim_esc_attr( $quote_data["index"] ) . '">' .
  2839.                             '<center>' .
  2840.                                 $this->strip_trim_wp_kses_post( $quote_data["index"] ) .
  2841.                             '</center>' .
  2842.                         '</a>' .
  2843.                     '</div>' .
  2844.                     '<li>' .
  2845.                     '<a class="quotes-llama-page-link" ' .
  2846.                         'name="' . $this->strip_trim_esc_attr( $quote_data["first"] . '" "' . $quote_data["last"] ) . '" ' .
  2847.                         'first="' . $this->strip_trim_esc_attr( $quote_data["first"] ) . '" ' .
  2848.                         'last="' . $this->strip_trim_esc_attr( $quote_data["last"] ) . '" ' .
  2849.                         'security="' . $security . '" ' .
  2850.                         'href="#quotes-llama-page-print" ' .
  2851.                         'title="' . $this->strip_trim_esc_attr( $quote_data["first"] . '" "' . $quote_data["last"] ) . '">';
  2852.  
  2853.                         // if first and last name display that text
  2854.                         if ( $quote_data["last"] ) {
  2855.  
  2856.                             $author_link_list .= $this->strip_trim_wp_kses_post( $quote_data["last"] . ", " . $quote_data["first"] );
  2857.  
  2858.                         } else {
  2859.  
  2860.                             $author_link_list .= $this->strip_trim_esc_attr( $quote_data["first"] );
  2861.  
  2862.                         }
  2863.  
  2864.                     $author_link_list .= '</a></li>';
  2865.  
  2866.                 $current_quote_data = $quote_data["index"];
  2867.  
  2868.             }
  2869.  
  2870.         }
  2871.  
  2872.         // Now that we have all our data formatted build our output div.
  2873.         $template_page = '<div class="quotes-llama-page-status"></div>' .
  2874.  
  2875.             '<div class="quotes-llama-page-container">' .
  2876.  
  2877.                 '<div class="quotes-llama-page-sidebarleft">' .
  2878.  
  2879.                     '<div class="quotes-llama-page-title">' .
  2880.  
  2881.                         '<center>' .
  2882.  
  2883.                             '<h3>' .
  2884.  
  2885.                             $quotes_title .
  2886.  
  2887.                             '</h3>' .
  2888.  
  2889.                         '</center>' .
  2890.  
  2891.                         '<center class="quotes-llama-page-alpha">' .
  2892.  
  2893.                             $header_letter_list .
  2894.  
  2895.                         '</center>' .
  2896.  
  2897.                     '</div>' .
  2898.  
  2899.                     $author_link_list .
  2900.  
  2901.                 '</div>' .
  2902.  
  2903.                 '<div id="quotes-llama-printquote" class="quotes-llama-page-quote">' . $initial_quote . '</div>' .
  2904.  
  2905.             '</div>' .
  2906.  
  2907.             '<br clear="both">';
  2908.  
  2909.  
  2910.         return $template_page_loggedin . $template_page;
  2911.  
  2912.     }
  2913.  
  2914.  
  2915.     /*
  2916.      *  Renders results of quotes search from the page view.
  2917.      *
  2918.      *  @param Array $quotes - Array of search results.
  2919.      */
  2920.     public function template_page_search( $quotes ) {
  2921.  
  2922.         if ( $quotes ) {
  2923.  
  2924.             $author = "";
  2925.  
  2926.             foreach ( $quotes as $quote ) {
  2927.  
  2928.                 if ( $author == $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name ) ) { ?>
  2929.  
  2930.                     <div class="quotes-llama-quote-quote quotes-llama-page-more">
  2931.  
  2932.                         <?php echo $this->strip_trim_wp_kses_post( $quote->quote ); ?>
  2933.  
  2934.                     </div>
  2935.  
  2936.                     <div class="quotes-llama-page-source">
  2937.  
  2938.                         <?php // if there is a source
  2939.                         if ( $quote->source ) {
  2940.  
  2941.                             echo "<cite>" . make_clickable( $this->strip_trim_wp_kses_post( $quote->source ) ) . "</cite>";
  2942.  
  2943.                         } ?>
  2944.  
  2945.                     </div> <?php
  2946.  
  2947.                 } else { ?>
  2948.  
  2949.                     <div class="quotes-llama-quote-author">
  2950.  
  2951.                         <h2>
  2952.  
  2953.                             <?php // Check that we have an image url to use.
  2954.                             if ( $quote->img_url ) { ?>
  2955.  
  2956.                                 <img src="<?php echo $quote->img_url; ?>"
  2957.                                     hspace="5"
  2958.                                     align="left"> <?php
  2959.  
  2960.                             }
  2961.  
  2962.                             echo $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name ); ?>
  2963.  
  2964.                         </h2>
  2965.  
  2966.                     </div>
  2967.  
  2968.                     <div class="quotes-llama-quote-quote quotes-llama-page-more">
  2969.  
  2970.                         <?php echo $this->strip_trim_wp_kses_post( $quote->quote ); ?>
  2971.  
  2972.                     </div>
  2973.  
  2974.                     <div class="quotes-llama-page-source">
  2975.  
  2976.                         <?php // if there is a source
  2977.                         if ( $quote->source ) {
  2978.  
  2979.                             echo "<cite>" . make_clickable( $this->strip_trim_wp_kses_post( $quote->source ) ) . "</cite>";
  2980.  
  2981.                         } ?>
  2982.  
  2983.                     </div> <?php
  2984.  
  2985.                 }
  2986.  
  2987.                 $author = $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name );
  2988.  
  2989.                 echo "<br clear='both'>";
  2990.  
  2991.             } ?>
  2992.  
  2993.             <div class="quotes-llama-quote-author-back quotes-llama-inline"> <?php
  2994.  
  2995.                 echo "<input type='button' value='Print' class='quotes-llama-print')"; ?>
  2996.  
  2997.             </div> <?php
  2998.  
  2999.         } else {
  3000.  
  3001.             esc_html_e( "Search returned nothing", "quotes-llama" );
  3002.  
  3003.         }
  3004.  
  3005.     } // end template_page_search()
  3006.  
  3007.  
  3008.     /*
  3009.      *  Renders a list of author quotes in the page view.
  3010.      *
  3011.      *  @param Array $quotes - Array of authors quotes.
  3012.      */
  3013.     public function template_page_author( $quotes ) {
  3014.  
  3015.         $author = "";
  3016.  
  3017.         foreach ( $quotes as $quote ) {
  3018.  
  3019.             if ( $author == $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name ) ) { ?>
  3020.  
  3021.                 <div class="quotes-llama-quote-quote quotes-llama-page-more">
  3022.  
  3023.                     <?php echo $this->strip_trim_wp_kses_post( $quote->quote ); ?>
  3024.  
  3025.                 </div>
  3026.  
  3027.                 <div class="quotes-llama-page-source">
  3028.  
  3029.                     <?php // if there is a source
  3030.                     if ( $quote->source ) {
  3031.  
  3032.                         echo "<cite>" . make_clickable( $this->strip_trim_wp_kses_post( $quote->source ) ) . "</cite>";
  3033.  
  3034.                     } ?>
  3035.  
  3036.                 </div> <?php
  3037.  
  3038.             } else {
  3039.  
  3040.                 // include authors image. ?>
  3041.                 <div class="quotes-llama-quote-author">
  3042.  
  3043.                     <h2>
  3044.  
  3045.                         <?php // Check that we have an image url to use.
  3046.                         if ( $quote->img_url ) { ?>
  3047.  
  3048.                             <img src="<?php echo $quote->img_url; ?>"
  3049.                                 hspace="5"
  3050.                                 align="left"> <?php
  3051.  
  3052.                         }
  3053.  
  3054.                         echo $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name ); ?>
  3055.  
  3056.                     </h2>
  3057.  
  3058.                 </div>
  3059.  
  3060.                 <div class="quotes-llama-quote-quote quotes-llama-page-more">
  3061.  
  3062.                     <?php echo $this->strip_trim_wp_kses_post( $quote->quote ); ?>
  3063.  
  3064.                 </div>
  3065.  
  3066.                 <div class="quotes-llama-page-source">
  3067.  
  3068.                     <?php // if there is a source
  3069.                     if ( $quote->source ) {
  3070.  
  3071.                         echo "<cite>" . make_clickable( $this->strip_trim_wp_kses_post( $quote->source ) ) . "</cite>";
  3072.  
  3073.                     } ?>
  3074.  
  3075.                 </div> <?php
  3076.  
  3077.             }
  3078.  
  3079.             $author = $this->strip_trim_wp_kses_post( $quote->first_name . " " . $quote->last_name );
  3080.  
  3081.             echo "<br clear='both'><hr>";
  3082.  
  3083.         } ?>
  3084.  
  3085.         <div class="quotes-llama-quote-author-back quotes-llama-inline"> <?php
  3086.  
  3087.             echo "<a class='quotes-llama-quote-author-back quotes-llama-inline' title='" . esc_html__( 'Return to' ) . ' ' . $this->strip_trim_wp_kses_post( $author ) . "' href='#" . $author . "'><input type='button' value='&larr;'></a>";
  3088.             echo "<input type='button' value='Print' class='quotes-llama-print')"; ?>
  3089.  
  3090.         </div>
  3091.  
  3092.         <?php die();
  3093.  
  3094.     }
  3095.  
  3096.     /*
  3097.      *  Renders a static quote by id in page, post or template.
  3098.      *
  3099.      *  @param int $id - quote id?
  3100.      *  @param bool $show_author - show the author?
  3101.      *  @param bool $show_source - show the source?
  3102.      *  @param bool $show_image - show the image?
  3103.      *
  3104.      *  @return String - must return string, not echo or display or will render at top of page regardless of positioning.
  3105.      */
  3106.     public function template_id( $id = 1, $show_author = false, $show_source = false, $show_image = false ) {
  3107.  
  3108.         $use_comma = false;
  3109.  
  3110.         $show_author = $this->check_plugin_option( "show_page_author" );
  3111.         $show_source = $this->check_plugin_option( "show_page_source" );
  3112.         $show_image = $this->check_plugin_option( "show_page_image" );
  3113.         $source_newline = $this->check_plugin_option( "source_newline" );
  3114.        
  3115.         // Get the quote by the id shortcode.
  3116.         $quote_data = $this->quotes_select( $id );
  3117.  
  3118.         $image = "";
  3119.  
  3120.         if ( $show_image ) {
  3121.  
  3122.             $image_exist = $this->strip_trim_wp_kses_post( $quote_data["img_url"] );
  3123.  
  3124.             if ( isset( $image_exist ) && !empty( $image_exist ) ) {
  3125.  
  3126.                 $image = "<img src='" . $image_exist . "' align='left'>";
  3127.  
  3128.             }
  3129.  
  3130.         }
  3131.  
  3132.         // if showing author or source
  3133.         if ( $show_author || $show_source ) {
  3134.  
  3135.             $author_source = "<span class='quotes-llama-widget-author'>";
  3136.  
  3137.             // if showing author build string
  3138.             if ( $show_author && ( $quote_data["first_name"] || $quote_data["last_name"] ) ) {
  3139.  
  3140.                 $use_comma = true;
  3141.  
  3142.                 $author_source .= $this->strip_trim_wp_kses_post( $quote_data["first_name"] .
  3143.                     " " . $quote_data["last_name"] );
  3144.  
  3145.             }
  3146.  
  3147.             // If showing both author and source, add a comma to author_source or new line if option set to new line.
  3148.             if ( $use_comma && ( $show_source && $quote_data["source"] ) ) {
  3149.  
  3150.                 if ( $source_newline == "br" ) {
  3151.  
  3152.                     $author_source .= "<br>";
  3153.  
  3154.                 } else {
  3155.  
  3156.                     $author_source .= ",";
  3157.  
  3158.                 }
  3159.  
  3160.             }
  3161.  
  3162.             // If showing source build string.
  3163.             if ( $show_source ) {
  3164.  
  3165.                 // Check that there is a source.
  3166.                 if ( $quote_data["source"] ) {
  3167.  
  3168.                     $author_source .= " <cite>" .
  3169.                         make_clickable( $this->strip_trim_wp_kses_post( $quote_data["source"] ) ) . "</cite>";
  3170.  
  3171.                 }
  3172.  
  3173.             }
  3174.  
  3175.             $author_source .= "</span>";
  3176.  
  3177.         } else {
  3178.  
  3179.             $author_source = "";
  3180.  
  3181.         }
  3182.        
  3183.         // Build our div
  3184.         return '<div class="quotes-llama-widget-random widget-text wp_widget_plugin_box">' .
  3185.  
  3186.             $image .
  3187.  
  3188.             '<span class="quotes-llama-widget-more">' .
  3189.  
  3190.                 $this->strip_trim_wp_kses_post( $quote_data["quote"] ) .
  3191.  
  3192.             '</span>' .
  3193.  
  3194.             $author_source .
  3195.  
  3196.         '</div>';
  3197.  
  3198.     }
  3199.  
  3200.  
  3201.     /*
  3202.      *  Renders a single random quote in page, post or template.
  3203.      *
  3204.      *  @param bool $show_author - show the author?
  3205.      *  @param bool $show_source - show the source?
  3206.      *  @param bool $show_image - show the image?
  3207.      *
  3208.      *  @return String - must return string, not echo or display or will render at top of page regardless of positioning.
  3209.      */
  3210.     public function template_post( $show_author = false, $show_source = false, $show_image = false ) {
  3211.  
  3212.         $use_comma = false;
  3213.  
  3214.         $show_author = $this->check_plugin_option( "show_page_author" );
  3215.         $show_source = $this->check_plugin_option( "show_page_source" );
  3216.         $show_image = $this->check_plugin_option( "show_page_image" );
  3217.         $source_newline = $this->check_plugin_option( "source_newline" );
  3218.  
  3219.         // Get a random quote.
  3220.         $quote_data = $this->quotes_select( "random" );
  3221.  
  3222.         $image = "";
  3223.  
  3224.         if ( $show_image ) {
  3225.  
  3226.             $image_exist = $this->strip_trim_wp_kses_post( $quote_data["img_url"] );
  3227.  
  3228.             if ( isset( $image_exist ) && !empty( $image_exist ) ) {
  3229.  
  3230.                 $image = "<img src='" . $image_exist . "' align='left'>";
  3231.  
  3232.             }
  3233.  
  3234.         }
  3235.  
  3236.         // if showing author or source
  3237.         if ( $show_author || $show_source ) {
  3238.  
  3239.             $author_source = "<span class='quotes-llama-widget-author'>";
  3240.  
  3241.             // if showing author build string
  3242.             if ( $show_author && ( $quote_data["first_name"] || $quote_data["last_name"] ) ) {
  3243.  
  3244.                 $use_comma = true;
  3245.  
  3246.                 $author_source .= $this->strip_trim_wp_kses_post( $quote_data["first_name"] .
  3247.                     " " . $quote_data["last_name"] );
  3248.  
  3249.             }
  3250.  
  3251.             // If showing both author and source, add a comma to author_source or new line if option set to new line.
  3252.             if ( $use_comma && ( $show_source && $quote_data["source"] ) ) {
  3253.  
  3254.                 if ( $source_newline == "br" ) {
  3255.  
  3256.                     $author_source .= "<br>";
  3257.  
  3258.                 } else {
  3259.  
  3260.                     $author_source .= ",";
  3261.  
  3262.                 }
  3263.  
  3264.             }
  3265.  
  3266.             // If showing source build string.
  3267.             if ( $show_source ) {
  3268.  
  3269.                 // Check that there is a source.
  3270.                 if ( $quote_data["source"] ) {
  3271.  
  3272.                     $author_source .= " <cite>" .
  3273.                         make_clickable( $this->strip_trim_wp_kses_post( $quote_data["source"] ) ) . "</cite>";
  3274.  
  3275.                 }
  3276.  
  3277.             }
  3278.  
  3279.             $author_source .= "</span>";
  3280.  
  3281.         } else {
  3282.  
  3283.             $author_source = "";
  3284.  
  3285.         }
  3286.  
  3287.         // Return the built div.
  3288.         return '<div class="quotes-llama-widget-random widget-text wp_widget_plugin_box">' .
  3289.  
  3290.             $image .
  3291.  
  3292.             '<span class="quotes-llama-widget-more">' .
  3293.  
  3294.                 $this->strip_trim_wp_kses_post( $quote_data["quote"] ) .
  3295.  
  3296.             '</span>' .
  3297.  
  3298.             $author_source .
  3299.  
  3300.         '</div>';
  3301.  
  3302.     }
  3303.  
  3304.  
  3305.     /*
  3306.      *  Gallery html contianer for shortcode call.
  3307.      *  Must return string and not just display or echo in order to maintain load order of shortcode call.
  3308.      *  See JS files Gallery sections for dynamic content and funtion.
  3309.      *
  3310.      *  @return String - must return string, not echo or display or will render at top of page regardless of positioning.
  3311.      */
  3312.     public function template_gallery() {
  3313.  
  3314.         return '<div class="quotes-llama-gallery" ' .
  3315.             'gauthor="' . $this->check_plugin_option( "show_gallery_author" ) . '"' .
  3316.             'gsource="' . $this->check_plugin_option( "show_gallery_source" ) . '"' .
  3317.             'gimage="' . $this->check_plugin_option( "show_gallery_image" ) . '">' .
  3318.                
  3319.             '<div class="quotes-llama-gallery-rotate">' .
  3320.                 '<div class="quotes-llama-gallery-countdown quotes-llama-gallery-reenable"></div>' .
  3321.                 '<div class="quotes-llama-gallery-quotebox"></div>' .
  3322.             '</div>' .
  3323.                
  3324.         '</div>';
  3325.  
  3326.     }
  3327.  
  3328.  
  3329.     /*
  3330.      *  Registers the widget class.
  3331.      */
  3332.     public function register_widgets() {
  3333.  
  3334.         register_widget( "QuotesLlamaWidget" );
  3335.  
  3336.     }
  3337.  
  3338.  
  3339.     /*
  3340.      *  Renders a widget instance in the sidebar.
  3341.      *
  3342.      *  @param bool $show_author - show the author?
  3343.      *  @param bool $show_source - show the source?
  3344.      *  @param bool $show_image - show the image?
  3345.      *  @param string $div_instance - previous instance id so we can replace it instead of nest into it.
  3346.      */
  3347.     public function widget_instance( $quote_id = 0, $show_author = true, $show_source = true, $show_image = true, $next_quote = true, $gallery = false, $div_instance = 0 ) {
  3348.  
  3349.         $use_comma = false;
  3350.         $source_newline = $this->check_plugin_option( "source_newline" );
  3351.  
  3352.         // If updating options in one of the widget instances.
  3353.         if ( isset( $_REQUEST["author"] ) ) $show_author = $_REQUEST["author"];
  3354.         if ( isset( $_REQUEST["source"] ) ) $show_source = $_REQUEST["source"];
  3355.         if ( isset( $_REQUEST["image"] ) ) $show_image = $_REQUEST["image"];
  3356.         if ( isset( $_REQUEST["next_quote"] ) ) $next_quote = $_REQUEST["next_quote"];
  3357.         if ( isset( $_REQUEST["gallery"] ) ) $gallery = $_REQUEST["gallery"];
  3358.         if ( isset( $_REQUEST["quote_id"] ) ) $quote_id = $_REQUEST["quote_id"];
  3359.         if ( isset( $_REQUEST["div_instance"] ) ) $div_instance = $_REQUEST["div_instance"];
  3360.  
  3361.         // Get a random quote if no static quote id is provided.
  3362.         if ( $quote_id > 0 ) {
  3363.  
  3364.             // disable auto-refresh
  3365.             $gallery = false;
  3366.  
  3367.             $quote_data = $this->quotes_select( $quote_id );
  3368.  
  3369.         } else {
  3370.  
  3371.             $quote_data = $this->quotes_select( "random" );
  3372.  
  3373.         }
  3374.  
  3375.         $image = "";
  3376.         $author_source = "";
  3377.  
  3378.         // Check for gallery widget mode. Return here if enabled.
  3379.         if ( $gallery ) {
  3380.  
  3381.             // Create div to load .ajax refresh into.
  3382.             $div_instance = "q" . rand( 1000, 100000 ); ?>
  3383.  
  3384.             <div id="<?php echo $div_instance; ?>"
  3385.                 class="quotes-llama-widget-gallery widget-text wp_widget_plugin_box"
  3386.                 wauthor="<?php echo $show_author; ?>"
  3387.                 wsource="<?php echo $show_source; ?>"
  3388.                 wimage="<?php echo $show_image; ?>">
  3389.  
  3390.             </div><?php
  3391.  
  3392.             return;
  3393.  
  3394.         }
  3395.  
  3396.         // If showing image, build string.
  3397.         if ( $show_image ) {
  3398.  
  3399.             $image_exist = $this->strip_trim_wp_kses_post( $quote_data["img_url"] );
  3400.  
  3401.             if ( isset( $image_exist ) && !empty( $image_exist ) ) {
  3402.  
  3403.                 $image = "<img src='" . $image_exist . "' align='left'>";
  3404.  
  3405.             }
  3406.  
  3407.         }
  3408.  
  3409.         // Span for author and source.
  3410.         $author_source = "<span class='quotes-llama-widget-author'>";
  3411.  
  3412.         // If showing author, add to author_source.
  3413.         if ( $show_author && ( $quote_data["first_name"] || $quote_data["last_name"] ) ) {
  3414.  
  3415.             $use_comma = true;
  3416.  
  3417.             $author_source .= $this->strip_trim_wp_kses_post( $quote_data["first_name"] .
  3418.                     " " . $quote_data["last_name"] );
  3419.  
  3420.         }
  3421.  
  3422.         // If showing both author and source, add a comma to author_source or new line if option set to new line.
  3423.         if ( $use_comma && ( $show_source && $quote_data["source"] ) ) {
  3424.  
  3425.             if ( $source_newline == "br" ) {
  3426.  
  3427.                 $author_source .= "<br>";
  3428.  
  3429.             } else {
  3430.  
  3431.                 $author_source .= ",";
  3432.  
  3433.             }
  3434.  
  3435.         }
  3436.  
  3437.         // If showing source, add to author_source. Also close span either way.
  3438.         if ( $show_source && $quote_data["source"] ) {
  3439.  
  3440.             $author_source .= " <cite>" . make_clickable( $this->strip_trim_wp_kses_post( $quote_data["source"] ) ) . "</cite></span>";
  3441.  
  3442.         } else {
  3443.  
  3444.             $author_source .= "</span>";
  3445.  
  3446.         }
  3447.  
  3448.         // If no id already, create div id for widget next link
  3449.         // so next quote click uses the same unique id. Skip this on next click.
  3450.         if ( !$div_instance ) {
  3451.  
  3452.             $div_instance = "q" . rand( 1000, 100000 );
  3453.  
  3454.             // Render initial widget div. ?>
  3455.             <div id="<?php echo $div_instance; ?>"
  3456.                 class="quotes-llama-widget-random widget-text wp_widget_plugin_box"><?php
  3457.  
  3458.         }
  3459.  
  3460.         echo $image;
  3461.  
  3462.         // If quote id is provided set static class or just set next quote link class.
  3463.         if ( $quote_id > 0 ) {
  3464.  
  3465.             // If limiting quote
  3466.             echo '<span class="quotes-llama-widget-static-more">';
  3467.  
  3468.         } else {
  3469.  
  3470.             // full quote
  3471.             echo '<span class="quotes-llama-widget-next-more">';
  3472.  
  3473.         }
  3474.  
  3475.             echo $this->strip_trim_wp_kses_post( $quote_data['quote'] );
  3476.  
  3477.         echo "</span>";
  3478.  
  3479.         echo $author_source;
  3480.  
  3481.         // if showing static quote or if disabled in option, disable next quote link.
  3482.         if ( !$quote_id && $next_quote ) { ?>
  3483.  
  3484.             <span class="quotes-llama-widget-next"
  3485.                 divid="<?php echo $div_instance; ?>"
  3486.                 author="<?php echo $show_author; ?>"
  3487.                 source="<?php echo $show_source; ?>"
  3488.                 img="<?php echo $show_image; ?>">
  3489.  
  3490.                 <i><?php esc_html_e( "next quote" ); ?></i>
  3491.  
  3492.             </span> <?php
  3493.  
  3494.         }
  3495.  
  3496.         echo "</div>";
  3497.  
  3498.     }
  3499.  
  3500.  
  3501.     /*
  3502.      *  Sanitize a single element.
  3503.      *
  3504.      *  @param string $data - String to sanitize.
  3505.      *
  3506.      *  @return string - Sanitized string.
  3507.      */
  3508.     public function validate( $data ) {
  3509.  
  3510.         global $allowedposttags;
  3511.  
  3512.         // http://codex.wordpress.org/Function_Reference/wp_kses
  3513.         // http://php.net/manual/en/function.stripslashes.php
  3514.         $data = wp_kses( stripslashes( trim( $data ) ), $allowedposttags );
  3515.  
  3516.         // http://codex.wordpress.org/Function_Reference/esc_sql
  3517.         $data = esc_sql( $data );
  3518.  
  3519.         return $data;
  3520.  
  3521.     }
  3522.  
  3523.  
  3524.     /*
  3525.      *  Adds screen options to admin page.
  3526.      *  have to make sure that your derived class is instantiated
  3527.      *  before the screen option panel is rendered so that the
  3528.      *  parent class can retrieve the column names.
  3529.      *  http://wpengineer.com/2426/wp_list_table-a-step-by-step-guide/
  3530.      */
  3531.     public function quotes_llama_add_option() {
  3532.  
  3533.         global $quotes_table;
  3534.  
  3535.         $option = 'per_page';
  3536.  
  3537.         $args = array(
  3538.             'label' => 'Quotes per page',
  3539.             'default' => 10,
  3540.             'option' => 'quotes_llama_per_page'
  3541.         );
  3542.  
  3543.         add_screen_option( $option, $args );
  3544.  
  3545.         $quotes_table = new QuotesLlamaTable;
  3546.  
  3547.     }
  3548.  
  3549.  
  3550.     /*
  3551.      *  Sets value for table screen options in admin page
  3552.      *
  3553.      *  @param $status - ? IDK what status is for.
  3554.      *  @param $option - The option name.
  3555.      *  @param $value - The option value.
  3556.      *
  3557.      *  @return string - Sanitized string.
  3558.      */
  3559.     public function quotes_llama_set_option( $status, $option, $value ) {
  3560.  
  3561.         return $value;
  3562.  
  3563.     }
  3564.  
  3565.  
  3566.     /*
  3567.      *  Gets the current page number, search term, search column, sort coulmn, sort order.
  3568.      *
  3569.      *  @return string - String ocurrent page number.
  3570.      */
  3571.     public function get_page_number() {
  3572.  
  3573.         $return_page = "";
  3574.  
  3575.         // Get the paged variable.
  3576.         if ( isset( $_REQUEST["paged"] ) ) {
  3577.  
  3578.             $return_page .= "&paged=" . $_REQUEST["paged"];
  3579.  
  3580.         }
  3581.  
  3582.         // Get the search term variable.
  3583.         if ( isset( $_REQUEST["quotes_llama_s"] ) ) {
  3584.  
  3585.             $return_page .= "&s=" . $_REQUEST["quotes_llama_s"];
  3586.  
  3587.         }
  3588.  
  3589.         // Get the search column variable.
  3590.         if ( isset( $_REQUEST["search_column"] ) ) {
  3591.  
  3592.             $return_page .= "&search_column=" . $_REQUEST["search_column"];
  3593.  
  3594.         }
  3595.  
  3596.         // Get the order variable.
  3597.         if ( isset( $_REQUEST["order"] ) ) {
  3598.  
  3599.             $return_page .= "&order=" . $_REQUEST["order"];
  3600.  
  3601.         }
  3602.  
  3603.         // Get the sort column variable.
  3604.         if ( isset( $_REQUEST["orderby"] ) ) {
  3605.  
  3606.             $return_page .= "&orderby=" . $_REQUEST["orderby"];
  3607.  
  3608.         }
  3609.  
  3610.         return $return_page;
  3611.  
  3612.     }
  3613.  
  3614.     /*
  3615.      *  Return a selected image from the media library.
  3616.      *
  3617.      *  Returns link to image.
  3618.      */
  3619.     public function get_image_from_media_library() {
  3620.  
  3621.         if ( $attachments = get_children( array(
  3622.             'post_type' => 'attachment',
  3623.             'post_mime_type'=>'image',
  3624.             'numberposts' => 1,
  3625.             'post_status' => null,
  3626.             //'post_parent' => $post->ID
  3627.         )));
  3628.  
  3629.         foreach ( $attachments as $attachment ) {
  3630.  
  3631.             // http://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src
  3632.             $img = wp_get_attachment_image_src( $attachment->ID, "thumbnail" );
  3633.  
  3634.         }
  3635.  
  3636.         return $img;
  3637.  
  3638.     }
  3639. } // end class QuotesLlama
  3640.  
  3641.  
  3642.  
  3643. class QuotesLlamaWidget extends WP_Widget {
  3644.  
  3645.     /*
  3646.      *  Widget - constructor
  3647.      *  http://codex.wordpress.org/Widgets_API
  3648.      *  http://developer.wordpress.org/reference/functions/wp_register_widget_control/
  3649.      */
  3650.     public function __construct() {
  3651.  
  3652.         $widget_ops = array( "description" => __( "Display a quote.", "quotes-llama" ) );
  3653.  
  3654.         parent::__construct( "quotesllamawidget", __( "Quotes llama", "quotes-llama" ), $widget_ops );
  3655.  
  3656.     }
  3657.  
  3658.  
  3659.     /*
  3660.      *  Widget - Render admin page form.
  3661.      *
  3662.      *  @param array $instance - Array of this particular widgets options
  3663.      */
  3664.     public function form( $instance ) {
  3665.  
  3666.         if ( $instance ) {
  3667.  
  3668.             $title = $instance["title"];
  3669.             $show_author = $instance["show_author"];
  3670.             $show_source = $instance["show_source"];
  3671.             $show_image = $instance["show_image"];
  3672.             $next_quote = $instance["next_quote"];
  3673.             $gallery = $instance["gallery"];
  3674.             $quote_id = $instance["quote_id"];
  3675.  
  3676.         } else {
  3677.  
  3678.             $title = "";
  3679.             $show_author = true;
  3680.             $show_source = true;
  3681.             $show_image = true;
  3682.             $next_quote = true;
  3683.             $gallery = false;
  3684.             $quote_id = "";
  3685.  
  3686.         } ?>
  3687.  
  3688.         <p>
  3689.  
  3690.             <label for="<?php echo $this->get_field_id( 'title' ); ?>">
  3691.  
  3692.                 <?php esc_html_e( "Title", "quotes-llama" ); ?>
  3693.  
  3694.             </label>
  3695.  
  3696.             <?php // http://codex.wordpress.org/Function_Reference/get_field_name ?>
  3697.             <input class="widefat"
  3698.                 id="<?php echo $this->get_field_id( 'title' ); ?>"
  3699.                 name="<?php echo $this->get_field_name( 'title' ); ?>"
  3700.                 type="text"
  3701.                 value="<?php esc_attr_e( $title, 'quotes-llama' ); ?>"
  3702.                 placeholder="<?php esc_html_e( '(Optional)' ); ?>">
  3703.  
  3704.         </p>
  3705.  
  3706.         <p>
  3707.  
  3708.             <input type="checkbox"
  3709.                 id="<?php echo $this->get_field_id( 'show_author' ); ?>"
  3710.                 name="<?php echo $this->get_field_name( 'show_author' ); ?>"
  3711.                 value="1"
  3712.                 <?php checked( "1", $show_author ); ?>>
  3713.  
  3714.             <label for="<?php echo $this->get_field_id( 'show_author' ); ?>">
  3715.  
  3716.                 <?php esc_html_e( "Show author.", "quotes-llama" ); ?>
  3717.  
  3718.             </label>
  3719.  
  3720.         </p>
  3721.  
  3722.         <p>
  3723.  
  3724.             <input type="checkbox"
  3725.                 id="<?php echo $this->get_field_id( 'show_source' ); ?>"
  3726.                 name="<?php echo $this->get_field_name( 'show_source' ); ?>"
  3727.                 value="1"
  3728.                 <?php checked( "1", $show_source ); ?>>
  3729.  
  3730.             <label for="<?php echo $this->get_field_id( 'show_source' ); ?>">
  3731.  
  3732.                 <?php esc_html_e( "Show source.", "quotes-llama" ); ?>
  3733.  
  3734.             </label>
  3735.  
  3736.         </p>
  3737.  
  3738.         <p>
  3739.  
  3740.             <input type="checkbox"
  3741.                 id="<?php echo $this->get_field_id( 'show_image' ); ?>"
  3742.                 name="<?php echo $this->get_field_name( 'show_image' ); ?>"
  3743.                 value="1"
  3744.                 <?php checked( "1", $show_image ); ?>>
  3745.  
  3746.             <label for="<?php echo $this->get_field_id( 'show_image' ); ?>">
  3747.  
  3748.                 <?php esc_html_e( "Show image.", "quotes-llama" ); ?>
  3749.  
  3750.             </label>
  3751.  
  3752.         </p>
  3753.        
  3754.         <p>
  3755.  
  3756.             <input type="checkbox"
  3757.                 id="<?php echo $this->get_field_id( 'next_quote' ); ?>"
  3758.                 name="<?php echo $this->get_field_name( 'next_quote' ); ?>"
  3759.                 value="1"
  3760.                 <?php checked( "1", $next_quote ); ?>>
  3761.  
  3762.             <label for="<?php echo $this->get_field_id( 'next_quote' ); ?>">
  3763.  
  3764.                 <?php esc_html_e( "Show 'next quote' link.", "quotes-llama" ); ?>
  3765.  
  3766.             </label>
  3767.  
  3768.         </p>
  3769.  
  3770.         <p>
  3771.  
  3772.             <input type="checkbox"
  3773.                 id="<?php echo $this->get_field_id( 'gallery' ); ?>"
  3774.                 name="<?php echo $this->get_field_name( 'gallery' ); ?>"
  3775.                 value="1"
  3776.                 <?php checked( "1", $gallery ); ?>>
  3777.  
  3778.             <label for="<?php echo $this->get_field_id( 'gallery' ); ?>">
  3779.  
  3780.                 <?php esc_html_e( "Auto-Refresh", "quotes-llama" ); ?>
  3781.  
  3782.             </label>
  3783.  
  3784.         </p>
  3785.  
  3786.         <p>
  3787.  
  3788.             <label for="<?php echo $this->get_field_id( 'quote_id' ); ?>">
  3789.  
  3790.                 <?php esc_html_e( "Quote ID", "quotes-llama" ); ?>
  3791.  
  3792.             </label>
  3793.  
  3794.             <input class="widefat"
  3795.                 id="<?php echo $this->get_field_id( 'quote_id' ); ?>"
  3796.                 name="<?php echo $this->get_field_name( 'quote_id' ); ?>"
  3797.                 type="text"
  3798.                 value="<?php esc_attr_e( $quote_id ); ?>"
  3799.                 placeholder="<?php esc_html_e( 'To display a static quote, enter the ID here.' ); ?>">
  3800.  
  3801.         </p> <?php
  3802.  
  3803.     }
  3804.  
  3805.  
  3806.     /*
  3807.      *  widget - update options
  3808.      */
  3809.     public function update( $new_instance, $old_instance ) {
  3810.  
  3811.         $instance = $old_instance;
  3812.  
  3813.         // Fields
  3814.         // http://php.net/manual/en/function.strip-tags.php
  3815.         $instance["title"] = strip_tags( $new_instance["title"] );
  3816.         $instance["show_author"] = strip_tags( $new_instance["show_author"] );
  3817.         $instance["show_source"] = strip_tags( $new_instance["show_source"] );
  3818.         $instance["show_image"] = strip_tags( $new_instance["show_image"] );
  3819.         $instance["next_quote"] = strip_tags( $new_instance["next_quote"] );
  3820.         $instance["gallery"] = strip_tags( $new_instance["gallery"] );
  3821.         $instance["quote_id"] = $new_instance["quote_id"];
  3822.         return $instance;
  3823.  
  3824.     }
  3825.  
  3826.  
  3827.     /*
  3828.      *  Widget - Render sidebar.
  3829.      *
  3830.      *  @param Array $args, The name of your widget class.
  3831.      *  @param Array $instance - Contains options for this particular widget.
  3832.      */
  3833.     public function widget( $args, $instance ) {
  3834.  
  3835.         // http://php.net/manual/en/function.extract.php
  3836.         extract( $args );
  3837.  
  3838.         // These are the widget options.
  3839.         // http://codex.wordpress.org/Function_Reference/apply_filters
  3840.         $title = apply_filters( "widget_title", $instance["title"] );
  3841.         $show_author = $instance["show_author"];
  3842.         $show_source = $instance["show_source"];
  3843.         $show_image = $instance["show_image"];
  3844.         $next_quote = $instance["next_quote"];
  3845.         $gallery = $instance["gallery"];
  3846.  
  3847.         if ( isset( $instance["quote_id"] ) ) {
  3848.  
  3849.             $quote_id = $instance["quote_id"];
  3850.  
  3851.         } else {
  3852.  
  3853.             $quote_id = 0;
  3854.  
  3855.         }
  3856.  
  3857.         echo $before_widget;
  3858.  
  3859.         // Begin rendering the widget div.
  3860.         echo "<div class='widget-text wp_widget_plugin_box'>";
  3861.  
  3862.             // Check if title is set.
  3863.             if ( $title ) {
  3864.  
  3865.                 echo $before_title . $title . $after_title;
  3866.  
  3867.             }
  3868.  
  3869.             // Display random quote widget in blog sidebar.
  3870.             echo "<div class='quotes-llama-widget-random'>";
  3871.  
  3872.                 $widge = new QuotesLlama;
  3873.  
  3874.                 $widge->widget_instance( $quote_id, $show_author, $show_source, $show_image, $next_quote, $gallery );
  3875.  
  3876.             echo "</div>";
  3877.  
  3878.         // End widget div.
  3879.         echo "</div>";
  3880.  
  3881.         echo $after_widget;
  3882.  
  3883.     }
  3884.  
  3885. } // End class QuotesLlamaWidget
  3886.  
  3887.  
  3888.  
  3889. class QuotesLlamaTable extends QuotesLlama_List_Table {
  3890.  
  3891.     private $strip_trim;
  3892.  
  3893.     /*
  3894.      *  REQUIRED. Set up a constructor that references the parent constructor.
  3895.      */
  3896.     public function __construct() {
  3897.  
  3898.         // Set parent defaults for singular, plural, supports ajax
  3899.         parent::__construct( array(
  3900.             "singular" => "quote",
  3901.             "plural" => "quotes",
  3902.             "ajax" => false
  3903.             )
  3904.  
  3905.         );
  3906.  
  3907.         $this->strip_trim = new QuotesLlama;
  3908.  
  3909.     }
  3910.  
  3911.  
  3912.     /*
  3913.      *  Set a default column if not one.
  3914.      *
  3915.      *  @param array $item - A singular item (one full row's worth of data)
  3916.      *  @param array $column_name - The name/slug of the column to be processed
  3917.      *
  3918.      *  @return string - Default Text or HTML to be placed inside the column <td>
  3919.      */
  3920.     public function column_default( $item, $column_name ) {
  3921.  
  3922.         switch( $column_name ) {
  3923.             case "id":
  3924.             case "thequote":
  3925.             case "firstname":
  3926.             case "lastname":
  3927.             case "source":
  3928.             case "img":
  3929.                 return $item[ $column_name ];
  3930.             default:
  3931.                 // Show the whole array if no match
  3932.                 return print_r( $item, true );
  3933.         }
  3934.  
  3935.     }
  3936.  
  3937.  
  3938.     /*
  3939.      *  id column.
  3940.      */
  3941.     public function column_id( $item ) {
  3942.  
  3943.         return "<span style='color:silver'>" . $this->strip_trim->strip_trim_wp_kses_post( $item["quote_id"] ) . "</span>";
  3944.  
  3945.     }
  3946.  
  3947.  
  3948.     /*
  3949.      *  Quote column.
  3950.      */
  3951.     public function column_thequote( $item ) {
  3952.  
  3953.         $return_page = "";
  3954.  
  3955.         // Get the paged variable.
  3956.         if ( isset( $_REQUEST["paged"] ) ) {
  3957.  
  3958.             $return_page .= "&paged=" . $_REQUEST["paged"];
  3959.  
  3960.         }
  3961.  
  3962.         // Get the search term variable.
  3963.         if ( isset( $_REQUEST["quotes_llama_s"] ) ) {
  3964.  
  3965.             $return_page .= "&s=" . $_REQUEST["quotes_llama_s"];
  3966.  
  3967.         }
  3968.  
  3969.         // Get the search column variable.
  3970.         if ( isset( $_REQUEST["search_column"] ) ) {
  3971.  
  3972.             $return_page .= "&search_column=" . $_REQUEST["search_column"];
  3973.  
  3974.         }
  3975.  
  3976.         // Get the order variable.
  3977.         if ( isset( $_REQUEST["order"] ) ) {
  3978.  
  3979.             $return_page .= "&order=" . $_REQUEST["order"];
  3980.  
  3981.         }
  3982.  
  3983.         // Get the sort column variable.
  3984.         if ( isset( $_REQUEST["orderby"] ) ) {
  3985.  
  3986.             $return_page .= "&orderby=" . $_REQUEST["orderby"];
  3987.  
  3988.         }
  3989.  
  3990.         // http://codex.wordpress.org/Function_Reference/wp_nonce_url
  3991.         $edit = wp_nonce_url("?page=" . $_REQUEST["page"] . $return_page . "&action=quotes_llama_edit&quote_id=" . $item["quote_id"], "delete_edit");
  3992.         $delete = wp_nonce_url("?page=" . $_REQUEST["page"] . $return_page . "&action=quotes_llama_delete_single&quote_id=" . $item["quote_id"], "delete_edit");
  3993.  
  3994.         // Links to edit / delete individual quotes.
  3995.         $actions = array(
  3996.             "edit" => "<a href='" . $edit . "'>Edit</a>",
  3997.             "delete" => "<a href='" . $delete . "' onclick='return confirm(\"" . esc_html__('Delete quote', 'quotes-llama') . " (" . $item["quote_id"] . ")? " . esc_html__('Select Cancel to stop, OK to delete.', 'quotes-llama') . "\")';>Delete</a>"
  3998.         );
  3999.  
  4000.         // Return the quote contents.
  4001.         return stripslashes( $item["quote"] ) .
  4002.             $this->row_actions( $actions );
  4003.  
  4004.     }
  4005.  
  4006.  
  4007.     /*
  4008.      *  First name column.
  4009.      */
  4010.     public function column_firstname( $item ) {
  4011.  
  4012.         return $this->strip_trim->strip_trim_wp_kses_post( $item["first_name"] );
  4013.  
  4014.     }
  4015.  
  4016.     /*
  4017.      *  Last name column.
  4018.      */
  4019.     public function column_lastname( $item ) {
  4020.  
  4021.         return $this->strip_trim->strip_trim_wp_kses_post( $item["last_name"] );
  4022.  
  4023.     }
  4024.  
  4025.     /*
  4026.      *  Source column.
  4027.      */
  4028.     public function column_source( $item ) {
  4029.  
  4030.         return make_clickable( $this->strip_trim->strip_trim_wp_kses_post( $item["source"] ) );
  4031.  
  4032.     }
  4033.  
  4034.  
  4035.     /*
  4036.      *  Image url column.
  4037.      */
  4038.     public function column_img( $item ) {
  4039.  
  4040.         // Check that we have an image url to use.
  4041.         if ( $item["img_url"] ) {
  4042.  
  4043.             return "<a href='" . $item["img_url"] . "' target='_blank' title='" . $this->strip_trim->strip_trim_wp_kses_post( $this->column_firstname( $item ) . " " . $this->column_lastname( $item ) ) . "\n" . $this->strip_trim->strip_trim_esc_url( $item["img_url"] ) . "'><img src='" . $this->strip_trim->strip_trim_esc_url( $item["img_url"] ) . "' width='75' title='" . $this->strip_trim->strip_trim_esc_attr( $this->column_firstname( $item ) . " " . $this->column_lastname( $item ) ) . "\n" . $this->strip_trim->strip_trim_esc_url( $item["img_url"] ) . "' alt='" . $this->strip_trim->strip_trim_esc_attr( $this->column_firstname( $item ) . " " . $this->column_lastname( $item ) ) . "\n" . $this->strip_trim->strip_trim_esc_url( $item["img_url"] ) . "'></a>";
  4044.  
  4045.         } else {
  4046.  
  4047.             return esc_html__( "No Image", "quotes-llama" );
  4048.  
  4049.         }
  4050.  
  4051.     }
  4052.  
  4053.  
  4054.     /*
  4055.      *  REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
  4056.      *  is given special treatment when columns are processed. It ALWAYS needs to
  4057.      *  be defined and have it's own method.
  4058.      */
  4059.     public function column_cb( $item ) { ?>
  4060.  
  4061.         <input type="checkbox"
  4062.             name="bulkcheck[]"
  4063.             value="<?php echo $this->strip_trim->strip_trim_wp_kses_post( $item['quote_id'] ); ?>"> <?php
  4064.  
  4065.     }
  4066.  
  4067.  
  4068.     /*
  4069.      *  The table's columns and titles.
  4070.      *  The 'cb' column is treated differently than the rest. Including a checkbox
  4071.      *  column in the table we must create a column_cb() method.
  4072.      */
  4073.     public function get_columns() {
  4074.  
  4075.         $columns = array(
  4076.             "cb" => "<input type='checkbox' />", // Render a checkbox.
  4077.             "id" => "ID",
  4078.             "thequote" => "Quote",
  4079.             "firstname" => "First Name",
  4080.             "lastname" => "Last Name",
  4081.             "source" => "Source",
  4082.             "img" => "Image"
  4083.         );
  4084.  
  4085.         return $columns;
  4086.  
  4087.     }
  4088.  
  4089.  
  4090.     /*
  4091.      *  One or more columns to be sortable.
  4092.      *  This merely defines which columns should be sortable and makes them
  4093.      *  clickable - it does not handle the actual sorting.
  4094.      *  Column => data field to sort.
  4095.      */
  4096.     public function get_sortable_columns() {
  4097.  
  4098.         $sortable_columns = array(
  4099.             "id"     => array("quote_id",false), // True is already sorted.
  4100.             "thequote"     => array("quote",false),
  4101.             "firstname"    => array("first_name",false),
  4102.             "lastname"    => array("last_name",false),
  4103.             "source"  => array("source",false),
  4104.             "img"  => array("img_url",false)
  4105.         );
  4106.  
  4107.         return $sortable_columns;
  4108.  
  4109.     }
  4110.  
  4111.  
  4112.     /*
  4113.      *  Bulk actions dropdown.
  4114.      */
  4115.     public function get_bulk_actions() {
  4116.  
  4117.         $actions = array(
  4118.             "quotes-llama-bulk-delete" => __( "Delete", "quotes-llama" ),
  4119.         );
  4120.  
  4121.         return $actions;
  4122.  
  4123.     }
  4124.  
  4125.  
  4126.     /*
  4127.      *  Prepare data for display.
  4128.      */
  4129.     public function prepare_items( $search = NULL, $per_page = 20 ) {
  4130.  
  4131.         global $wpdb;
  4132.  
  4133.         // Get our columns. Both hidden and sortable and
  4134.         // build column header array.
  4135.         $this->_column_headers = $this->get_column_info();
  4136.  
  4137.         /*
  4138.          *  Nested function to usort table.
  4139.          */
  4140.         function usort_quotes( $a, $b ) {
  4141.  
  4142.             $quotes_usort_options = get_option( "quotes-llama-settings" );
  4143.  
  4144.             // If no sort, default to options.
  4145.             $orderby = ( !empty( $_REQUEST["orderby"] ) ) ? $_REQUEST["orderby"] : $quotes_usort_options["default_sort"];
  4146.  
  4147.             // If no order, default to options.
  4148.             $order = ( !empty( $_REQUEST["order"] ) ) ? $_REQUEST["order"] : $quotes_usort_options["default_order"];
  4149.  
  4150.             // Determine sort order
  4151.             // http://php.net/manual/en/function.strnatcmp.php
  4152.             $result = strnatcmp( $a[$orderby], $b[$orderby] );
  4153.  
  4154.             // Send final sort direction to usort.
  4155.             return ( $order==="asc" ) ? $result : -$result;
  4156.  
  4157.         }
  4158.  
  4159.         if( NULL != $search ) {
  4160.  
  4161.             if ( isset( $_REQUEST["quotes_llama_s"] ) ) {
  4162.  
  4163.                 // http://codex.wordpress.org/Function_Reference/sanitize_text_field
  4164.                 $search = sanitize_text_field( $_REQUEST["quotes_llama_s"] );
  4165.  
  4166.             }
  4167.  
  4168.             // Trim search term.
  4169.             $search = trim( $search );
  4170.  
  4171.             // Search column, default to quote.
  4172.             $search_column = trim( ( !empty( $_REQUEST["search_column"] ) ) ? $_REQUEST["search_column"] : "quote");
  4173.  
  4174.             // Query our search data to build table with.
  4175.             $data = $wpdb->get_results($wpdb->prepare("SELECT * FROM " .
  4176.                 $wpdb->prefix . "quotes_llama WHERE $search_column LIKE '%%%s%%'", $search), ARRAY_A);
  4177.  
  4178.         } else {
  4179.  
  4180.             // Query all our quote data.
  4181.             $data = $wpdb->get_results( "SELECT * FROM " .
  4182.                 $wpdb->prefix . "quotes_llama", ARRAY_A );
  4183.  
  4184.         }
  4185.  
  4186.         // Sort data.
  4187.         // http://php.net/manual/en/function.usort.php
  4188.         uasort ( $data, "usort_quotes" );
  4189.  
  4190.         // What page user is on.
  4191.         $current_page = $this->get_pagenum();
  4192.  
  4193.         // How many items in data array.
  4194.         $total_items = count( $data );
  4195.  
  4196.         // get the current user ID
  4197.         $user = get_current_user_id();
  4198.  
  4199.         // get the current admin screen
  4200.         $screen = get_current_screen();
  4201.  
  4202.         // retrieve the "per_page" option
  4203.         $screen_option_per_page = $screen->get_option('per_page', 'option');
  4204.  
  4205.         // retrieve the value of the option stored for the current user
  4206.         $per_page = get_user_meta($user, $screen_option_per_page, true);
  4207.  
  4208.         if ( empty ( $per_page) || $per_page < 1 ) {
  4209.  
  4210.             // get the default value if none is set
  4211.             $per_page = $screen->get_option( 'per_page', 'default' );
  4212.  
  4213.         }
  4214.  
  4215.         // Paginate data to fit our page count. wp_list_table's search_box() doesn't paginate.
  4216.         $data = array_slice( $data, ( ( $current_page-1 ) * $per_page ), $per_page );
  4217.  
  4218.         // Set sorted data to item var.
  4219.         $this->items = $data;
  4220.  
  4221.         // Register our pagination options.
  4222.         $this->set_pagination_args( array(
  4223.                 "total_items" => $total_items,
  4224.                 "per_page"    => $per_page,
  4225.                 "total_pages" => ceil( $total_items/$per_page )
  4226.             )
  4227.  
  4228.         );
  4229.  
  4230.     }
  4231.  
  4232. } // End class QuotesLlamaTable
  4233.  
  4234.  
  4235.  
  4236. class QuotesLlamaBackup {
  4237.  
  4238.     private $table_name;
  4239.     private $separator;
  4240.     private $filename;
  4241.  
  4242.     /*
  4243.      *  @param array $table_n - Quotes table.
  4244.      *  @param string $sep - csv delimiter.
  4245.      */
  4246.     public function __construct( $table_n, $sep ) {
  4247.  
  4248.         $this->table_name = $table_n;
  4249.         $this->separator = $sep;
  4250.         $this->filename = "quotes";
  4251.  
  4252.     }
  4253.  
  4254.  
  4255.     /*
  4256.      *  Create .csv export.
  4257.      *
  4258.      *  @param string $filename - Filename to write to.
  4259.      */
  4260.     public function create_csv() {
  4261.  
  4262.         $dateNow = date( "d-m-Y_His" );
  4263.  
  4264.         // Getting the text generated to download.
  4265.         $csvFile = $this->generate_csv();
  4266.  
  4267.         // http://php.net/manual/en/function.readfile.php
  4268.         header( "Pragma: public" );
  4269.         header( "Expires: 0" );
  4270.         header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
  4271.  
  4272.         // Set browser to download file.
  4273.         header( "Cache-Control: private", false );
  4274.         header( "Content-Type: application/octet-stream" );
  4275.         header( "Content-Disposition: attachment; filename=\"" . $this->filename . "_" . $dateNow . ".csv\";" );
  4276.         header( "Content-Transfer-Encoding: binary" );
  4277.  
  4278.         // echo create the csv file.
  4279.         echo $csvFile;
  4280.  
  4281.         die();
  4282.     }
  4283.  
  4284.  
  4285.     /*
  4286.      *  Get data for .csv.
  4287.      *
  4288.      *  @return string $csv_output - quote data with columns
  4289.      */
  4290.     public function generate_csv() {
  4291.  
  4292.         global $wpdb;
  4293.  
  4294.         // .csv data.
  4295.         $csv_output = "";
  4296.  
  4297.         // Get column names.
  4298.         $result = $wpdb->get_results( "SHOW COLUMNS FROM " . $this->table_name );
  4299.  
  4300.         if ( count( $result ) > 0 ) {
  4301.  
  4302.             // remove quote_id from header columns.
  4303.             // http://php.net/manual/en/function.unset.php
  4304.             unset( $result[0] );
  4305.  
  4306.             foreach( $result as $row ) {
  4307.  
  4308.                 $csv_output = $csv_output . $row->Field . $this->separator;
  4309.  
  4310.             }
  4311.  
  4312.             // Trim trailing separator.
  4313.             // http://php.net/manual/en/function.substr.php
  4314.             $csv_output = substr( $csv_output, 0, -1 );
  4315.  
  4316.         }
  4317.  
  4318.         // Added our header so new line for data.
  4319.         $csv_output .= "\n";
  4320.  
  4321.         // Get all our quote data.
  4322.         $values = $wpdb->get_results( "SELECT * FROM " . $this->table_name, ARRAY_A );
  4323.  
  4324.         // http://php.net/manual/en/function.urldecode.php
  4325.         foreach ( $values as $value ) {
  4326.  
  4327.             // Remove the quote_id from each record.
  4328.             unset( $value["quote_id"] );
  4329.  
  4330.             // convert to numeric array.
  4331.             // http://php.net/manual/en/function.array-values.php
  4332.             $fields = array_values( $value );
  4333.  
  4334.             // Generating string with field separator.
  4335.             // http://php.net/manual/en/function.implode.php
  4336.             $csv_output .= stripslashes( implode( $this->separator, $fields ) );
  4337.             $csv_output .= "\n";
  4338.  
  4339.         }
  4340.  
  4341.         return $csv_output;
  4342.  
  4343.     }
  4344.  
  4345.  
  4346.     /*
  4347.      *  Get data for .json
  4348.      *  and create the file.
  4349.      */
  4350.     public function create_json() {
  4351.  
  4352.         global $wpdb;
  4353.         $dateNow = date( "d-m-Y_His" );
  4354.         $results = "SELECT * FROM " . $this->table_name;
  4355.         $quotes = $wpdb->get_results( $results, ARRAY_A );
  4356.  
  4357.         // remove the quote_id strip backslashes.
  4358.         foreach ( $quotes as $quote => $data ) {
  4359.  
  4360.             unset( $data["quote_id"] );
  4361.  
  4362.             $data["quote"] = stripslashes( $data["quote"] );
  4363.             $data["first_name"] = stripslashes( $data["first_name"] );
  4364.             $data["last_name"] = stripslashes( $data["last_name"] );
  4365.             $data["source"] = stripslashes( $data["source"] );
  4366.             $data["img_url"] = str_replace( "\"", "", $data["img_url"] );
  4367.  
  4368.             $quotes[$quote] = $data;
  4369.  
  4370.         }
  4371.  
  4372.         // http://php.net/manual/en/function.json-encode.php
  4373.         // http://php.net/manual/en/json.constants.php
  4374.         $json_output = json_encode( $quotes, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
  4375.  
  4376.         header( "Content-Type: text/json" );
  4377.         header( "Content-Disposition: attachment; filename=\"" . $this->filename . "_" . $dateNow . ".json\";" );
  4378.  
  4379.         echo $json_output;
  4380.  
  4381.         die();
  4382.  
  4383.     }
  4384.  
  4385.  
  4386.     /*
  4387.      *  Generates the import query string for importing
  4388.      *  from a valid json or csv file.
  4389.      */
  4390.     public function generate_import() {
  4391.  
  4392.         // http://php.net/manual/en/function.pathinfo.php
  4393.         // http://codex.wordpress.org/Function_Reference/sanitize_file_name
  4394.         $exts = array( "json", "JSON", "CSV", "csv" );
  4395.         $filename = sanitize_file_name( $_FILES["quotes-llama-file"]["name"] );
  4396.         $filetmp = $_FILES["quotes-llama-file"]["tmp_name"];
  4397.         $fileext = pathinfo( $_FILES["quotes-llama-file"]["name"], PATHINFO_EXTENSION );
  4398.         $fileerror = $_FILES["quotes-llama-file"]["error"];
  4399.  
  4400.         // Upload file and check it was successful
  4401.         // http://php.net/manual/en/features.file-upload.errors.php
  4402.         if ( $fileerror ) {
  4403.  
  4404.             $thismsg = $this->error_messages( $fileerror );
  4405.  
  4406.             echo "<div class='error'><p>" . $thismsg . "</p></div>";
  4407.  
  4408.             return;
  4409.         }
  4410.  
  4411.         // successfully uploaded file check type, has data, and is a valid file.
  4412.         if ( $fileerror === UPLOAD_ERR_OK && is_uploaded_file( $filetmp ) ) {
  4413.  
  4414.             // if our file is not of the type we are expecting.
  4415.             if( ! in_array( $fileext, $exts ) ) {
  4416.  
  4417.                 echo "<div class='error'><p>" . __( "The file type ." . $fileext . " is not supported.", "quotes-llama" ) . "</p></div>";
  4418.  
  4419.                 return;
  4420.  
  4421.             }
  4422.  
  4423.             // Check our upload is not an empty file.
  4424.             // http://php.net/manual/en/function.file-get-contents.php
  4425.             if ( ! ( $json_data = file_get_contents( $_FILES["quotes-llama-file"]["tmp_name"] ) ) ) {
  4426.  
  4427.                 echo "<div class='error'><p>" . __( "Unable to import because the file is empty.", "quotes-llama" ) . "</p></div>";
  4428.  
  4429.                 return;
  4430.  
  4431.             }
  4432.  
  4433.             // If this is a json file.
  4434.             if ( $fileext == "json" || $fileext == "JSON" ) {
  4435.  
  4436.                 // Check that our data is in fact JSON data.
  4437.                 if ( is_null( $quote_json = json_decode( $json_data, true ) ) ) {
  4438.  
  4439.                     echo "<div class='error'><p>" . $this->error_messages() . "</p></div>";
  4440.  
  4441.                     return;
  4442.  
  4443.                 } else {
  4444.  
  4445.                     // Import the json data.
  4446.                     $result = $this->quotes_import($quote_json) . " from " . $filename;
  4447.  
  4448.                 }
  4449.  
  4450.             // If this is a csv file.
  4451.             } elseif ( $fileext == "csv" || $fileext == "CSV" ) {
  4452.  
  4453.                 // Parse the csv into an array.
  4454.                 // http://php.net/manual/en/function.str-getcsv.php
  4455.                 $header = NULL;
  4456.  
  4457.                 $quote_entries = array();
  4458.  
  4459.                 $count = 1;
  4460.  
  4461.                 // http://php.net/manual/en/function.fopen.php
  4462.                 if ( ( $handle = fopen( $filetmp, "r" ) ) !== FALSE ) {
  4463.  
  4464.                     // http://php.net/manual/en/function.fgetcsv.php
  4465.                     while ( ( $row = fgetcsv( $handle, 2000, $this->separator ) ) !== FALSE ) {
  4466.  
  4467.                         // Check count of $row
  4468.                         // fgetcsv() returns array of one row from the CSV file.
  4469.                         // The array's count() is therefore the number of source columns.
  4470.                         if ( count( $row ) <> 5 ) {
  4471.  
  4472.                             echo "<div class='error'><p>" . __( "There was an error. Verification returned on line", "quotes-llama" );
  4473.                             echo " " . $count . ". ";
  4474.                             echo __( "Be sure the csv delimiter in the options tab is set to match your file. Your files encoding may not be supported. Errors within the file structure such as incorrect columns and fields can cause the import to fail as well.", "quotes-llama" ) . "</p></div>";
  4475.  
  4476.                             // http://php.net/manual/en/function.fclose.php
  4477.                             fclose( $handle );
  4478.  
  4479.                             return;
  4480.  
  4481.                         // combine our header and data arrays int one array.
  4482.                         } else {
  4483.  
  4484.                             // Assign first row data to header columns [header][row]
  4485.                             if ( !$header ) {
  4486.  
  4487.                                 $header = $row;
  4488.  
  4489.                                 // If the .csv file was saved in utf8 then it probably
  4490.                                 // has BOM characters in the column headers.
  4491.                                 // We need to strip them or we get
  4492.                                 // echo pack("CCC", 0xEF, 0xBB, 0xBF) . "quote";
  4493.                                 // and other characters which fail to import the field.
  4494.                                 // Verifying 5 column headers.
  4495.                                 // http://php.net/manual/en/function.pack.php
  4496.                                 // http://stackoverflow.com/a/20692384/5730352
  4497.                                 for ( $i = 0; $i <= 4; $i++ ) {
  4498.  
  4499.                                     $header[$i] = preg_replace( '/[\x00-\x1F\x80-\xFF]/', '', $header[$i] );
  4500.  
  4501.                                 }
  4502.  
  4503.                             } else {
  4504.  
  4505.                                 // http://php.net/manual/en/function.array-combine.php
  4506.                                 $quote_entries[] = array_combine( $header, $row );
  4507.  
  4508.                             }
  4509.  
  4510.                         }
  4511.  
  4512.                         ++$count;
  4513.  
  4514.                     }
  4515.  
  4516.                     fclose( $handle );
  4517.  
  4518.                     // Ready to import.
  4519.                     $result = $this->quotes_import($quote_entries);
  4520.  
  4521.                 }
  4522.  
  4523.             }
  4524.  
  4525.             // Check result of import.
  4526.             if ( ! $result ) {
  4527.  
  4528.                 echo "<div class='error'><p>" . __( "Import failed. Please try again.", "quotes-llama" ) . "</p></div>";
  4529.  
  4530.             } else if ( 0 === $result) {
  4531.  
  4532.                 echo "<div class='updated'><p>" . __( "No quotes imported", "quotes-llama" ) . "</p></div>";
  4533.  
  4534.             } else {
  4535.  
  4536.                 // http://codex.wordpress.org/Function_Reference/_n
  4537.                 echo "<div class='updated'><p>" .
  4538.                     sprintf( _n( "Your quote was imported", "%d quotes imported", $result, "quotes-llama" ), $result ) .
  4539.                     "</p></div>";
  4540.  
  4541.             }
  4542.  
  4543.             return;
  4544.  
  4545.         }
  4546.  
  4547.     }
  4548.  
  4549.  
  4550.     /*
  4551.      *  Import quotes from array provided by either .csv or .json formats.
  4552.      *
  4553.      *  @param array $quotes_data - Array of quote data.
  4554.      *
  4555.      *  @return mixed - int results count, or error string.
  4556.      */
  4557.     public function quotes_import( $quotes_data = array() ) {
  4558.  
  4559.         global $wpdb;
  4560.  
  4561.         if ( ! $quotes_data ) {
  4562.  
  4563.             return 0;
  4564.  
  4565.         }
  4566.  
  4567.         // Create insert statement.
  4568.         $query = "INSERT INTO " . $this->table_name .
  4569.                     " (quote, first_name, last_name, source, img_url)" .
  4570.                     " VALUES ";
  4571.  
  4572.         // Array for insert values and placeholders.
  4573.         $values = array();
  4574.  
  4575.         // Prepare insert values.
  4576.         foreach ( $quotes_data as $quote ) {
  4577.  
  4578.             $values[] = $wpdb->prepare( "(%s,%s,%s,%s,%s)", $quote['quote'], $quote['first_name'], $quote['last_name'], $quote['source'], $quote['img_url']);
  4579.  
  4580.         }
  4581.  
  4582.         // Combine statement and values.
  4583.         // http://php.net/manual/en/function.implode.php
  4584.         $query .= implode( ",\n", $values );
  4585.  
  4586.         // Return success count or error.
  4587.         return $wpdb->query( $query );
  4588.  
  4589.     }
  4590.  
  4591.  
  4592.     /*
  4593.      *  Handle error messages for file uploads and JSON decodes.
  4594.      *
  4595.      *  @param int $error_code - The error code encountered.
  4596.      *
  4597.      *  @return string - Description of the error.
  4598.      */
  4599.     public function error_messages( $error_code = "none" ) {
  4600.  
  4601.         // If no error code provided it is a JSON error.
  4602.         if ( $error_code == "none") {
  4603.  
  4604.             if ( ! function_exists( "json_last_error_msg" ) ) {
  4605.  
  4606.                 /*
  4607.                  *  Handle error messages for validating JSON file data.
  4608.                  *  http://php.net/manual/en/function.json-last-error-msg.php
  4609.                  *
  4610.                  *  @return string - Description of the error.
  4611.                 */
  4612.                 function json_last_error_msg() {
  4613.  
  4614.                     // http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static
  4615.                     static $ERRORS = array(
  4616.                         JSON_ERROR_NONE => "No error.",
  4617.                         JSON_ERROR_DEPTH => "Maximum stack depth exceeded in the JSON file.",
  4618.                         JSON_ERROR_STATE_MISMATCH => "State mismatch (invalid or malformed JSON).",
  4619.                         JSON_ERROR_CTRL_CHAR => "Control character error, possibly incorrectly encoded JSON file.",
  4620.                         JSON_ERROR_SYNTAX => "Import failed. Syntax error in the JSON file.",
  4621.                         JSON_ERROR_UTF8 => "Malformed UTF-8 characters, possibly incorrectly encoded JSON file."
  4622.                     );
  4623.  
  4624.                     $error = json_last_error();
  4625.  
  4626.                     return isset( $ERRORS[$error] ) ? $ERRORS[$error] : "Unknown error.";
  4627.  
  4628.                 }
  4629.  
  4630.             }
  4631.  
  4632.             return json_last_error_msg();
  4633.  
  4634.         }
  4635.  
  4636.         switch ( $error_code ) {
  4637.             case UPLOAD_ERR_INI_SIZE:
  4638.                 $message = "The uploaded file exceeds the upload_max_filesize directive in php.ini.";
  4639.                 break;
  4640.             case UPLOAD_ERR_FORM_SIZE:
  4641.                 $message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.";
  4642.                 break;
  4643.             case UPLOAD_ERR_PARTIAL:
  4644.                 $message = "The uploaded file was only partially uploaded..";
  4645.                 break;
  4646.             case UPLOAD_ERR_NO_FILE:
  4647.                 $message = "No file was uploaded.";
  4648.                 break;
  4649.             case UPLOAD_ERR_NO_TMP_DIR:
  4650.                 $message = "Missing a temporary folder.";
  4651.                 break;
  4652.             case UPLOAD_ERR_CANT_WRITE:
  4653.                 $message = "Failed to write file to disk.";
  4654.                 break;
  4655.             case UPLOAD_ERR_EXTENSION:
  4656.                 $message = "File upload stopped by extension.";
  4657.                 break;
  4658.  
  4659.             default:
  4660.                 $message = "File upload stopped by an unrecognized error.";
  4661.                 break;
  4662.         }
  4663.  
  4664.         return $message;
  4665.  
  4666.     }
  4667.  
  4668. } // End class QuotesLlamaBackup
  4669.  
  4670.  
  4671. // Start the plugin.
  4672. $quotes_llama = new QuotesLlama;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement