Add upstream

This commit is contained in:
root
2019-10-24 00:12:05 +02:00
parent 85d41e4216
commit ac980f592c
3504 changed files with 1049983 additions and 29971 deletions

View File

@@ -0,0 +1,308 @@
<?php
/**
* Media Library Assistant Admin Columns Pro (plugin) Support
*
* @package Media Library Assistant
* @since 2.50
*/
defined( 'ABSPATH' ) or die();
/**
* Class Admin Columns Addon MLA (Media Library Assistant) List Screen supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.50
*/
class ACP_Addon_MLA_ListScreen extends AC_Addon_MLA_ListScreen {
/**
* Initializes some properties, installs filters and then
* calls the parent constructor to set some default configs.
*
* @since 2.50
*/
public function __construct() {
parent::__construct();
add_action( 'acp/column_types', 'ACP_Addon_MLA_ListScreen::inline_column_types', 10, 1 );
add_action( 'ac/column_types', 'ACP_Addon_MLA_ListScreen::inline_column_types', 10, 1 );
// add_filter( 'acp/editing/model', 'ACP_Addon_MLA_ListScreen::add_editing_strategy', 10, 2 );
add_filter( 'acp/editing/model', 'ACP_Addon_MLA_ListScreen::add_editing_strategy', 10, 1 );
}
/**
* Add inline editing columns to Media/Assistant submenu table
*
* @since 2.52
*
* @param AC_ListScreen $listscreen
*/
public static function inline_column_types( $listscreen ) {
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Title() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Parent() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_MenuOrder() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_AltText() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Caption() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Description() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_MimeType() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Date() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Author() );
}
/**
* Set MLA-specific inline editing strategy for Admin Columns Pro
*
* @since 2.50
*
* @param ACP_Editing_Model $model
*/
public static function add_editing_strategy( $model /*, $column */ ) {
// @ param AC_Column $column added after 4.0.3 and before 4.0.14 - not used by MLA
$model->set_strategy( new ACP_Addon_MLA_Editing_Strategy( $model ) );
return $model;
}
} // class ACP_Addon_MLA_ListScreen
/**
* Class Admin Columns Addon MLA (Media Library Assistant) Editing Strategy supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.50
*/
class ACP_Addon_MLA_Editing_Strategy extends ACP_Editing_Strategy_Post {
/**
* Get the available items on the current page for passing them to JS
*
* @since 2.50
*
* @return array Items on the current page ([entry_id] => (array) [entry_data])
*/
public function get_rows() {
$table = $this->column->get_list_screen()->get_list_table();
$table->prepare_items();
return $this->get_editable_rows( $table->items );
}
} // class ACP_Addon_MLA_Editing_Strategy
/**
* Provides view_settings for MLA's post_title
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Editing_Model_Media_Title extends ACP_Editing_Model_Media_Title {
/**
* Remove JavaScript selector settings
*/
public function get_view_settings() {
return array(
'type' => 'text',
'display_ajax' => false,
);
}
}
/**
* Provides inline-editing for post_title
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Title extends AC_Column_Media_Title
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
// Mark as an existing column
$this->set_original( true );
// Type of column
$this->set_type( 'post_title' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Media_Title
*/
public function editing() {
return new ACP_Addon_MLA_Editing_Model_Media_Title( $this );
}
}
/**
* Removes ACP defaults for parent
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Parent extends AC_Column_Media_Parent {
/**
* Remove default column width
*/
public function register_settings() {
}
}
/**
* Provides inline-editing for menu_order
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_MenuOrder extends AC_Column
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'menu_order' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Order
*/
public function editing() {
return new ACP_Editing_Model_Post_Order( $this );
}
}
/**
* Provides inline-editing for alt_text
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_AltText extends ACP_Column_Media_AlternateText
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'alt_text' );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Caption extends ACP_Column_Media_Caption
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'caption' );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Description extends AC_Column_Media_Description
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'description' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Post_Content( $this );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_MimeType extends AC_Column_Media_MimeType
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'post_mime_type' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Media_MimeType( $this );
}
}
/**
* Removes ACP defaults for date
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Date extends ACP_Column_Media_Date {
/**
* Remove default column width
*/
public function register_settings() {
}
}
/**
* Removes ACP defaults & provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Author extends AC_Column_Media_Author
implements ACP_Column_EditingInterface {
/**
* Remove default column width
*/
public function register_settings() {
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Post_Author( $this );
}
}

View File

@@ -0,0 +1,304 @@
<?php
/**
* Media Library Assistant Admin Columns Pro (plugin) Support
*
* @package Media Library Assistant
* @since 2.50
*/
defined( 'ABSPATH' ) or die();
/**
* Class Admin Columns Addon MLA (Media Library Assistant) List Screen supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.50
*/
class ACP_Addon_MLA_ListScreen extends AC_Addon_MLA_ListScreen
implements ACP_Editing_ListScreen {
/**
* Initializes some properties, installs filters and then
* calls the parent constructor to set some default configs.
*
* @since 2.50
*/
public function __construct() {
parent::__construct();
add_action( 'ac/column_types', 'ACP_Addon_MLA_ListScreen::inline_column_types', 10, 1 );
}
/**
* Add inline editing columns to Media/Assistant submenu table
*
* @since 2.52
*
* @param AC_ListScreen $listscreen
*/
public static function inline_column_types( $listscreen ) {
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Title() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Parent() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_MenuOrder() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_AltText() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Caption() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Description() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_MimeType() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Date() );
$listscreen->register_column_type( new ACP_Addon_MLA_Column_Author() );
}
/**
* Set MLA-specific inline editing strategy for Admin Columns Pro
*
* @since 2.71
*
* @param ACP_Editing_Model $model
*/
public function editing( $model ) {
return new ACP_Addon_MLA_Editing_Strategy( $model );
}
} // class ACP_Addon_MLA_ListScreen
/**
* Class Admin Columns Addon MLA (Media Library Assistant) Editing Strategy supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.50
*/
class ACP_Addon_MLA_Editing_Strategy extends ACP_Editing_Strategy_Post {
/**
* Get the available items on the current page for passing them to JS
*
* @since 2.50
*
* @return array Items on the current page ([entry_id] => (array) [entry_data])
*/
public function get_rows() {
$table = $this->get_column()->get_list_screen()->get_list_table();
$table->prepare_items();
return $this->get_editable_rows( $table->items );
}
} // class ACP_Addon_MLA_Editing_Strategy
/**
* Provides view_settings for MLA's post_title
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Editing_Model_Media_Title extends ACP_Editing_Model_Media_Title {
/**
* Remove JavaScript selector settings
*/
public function get_view_settings() {
return array(
'type' => 'text',
'display_ajax' => false,
);
}
}
/**
* Provides inline-editing for post_title
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Title extends AC_Column_Media_Title
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
// Mark as an existing column
$this->set_original( true );
// Type of column
$this->set_type( 'post_title' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Media_Title
*/
public function editing() {
return new ACP_Addon_MLA_Editing_Model_Media_Title( $this );
}
}
/**
* Removes ACP defaults for parent
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Parent extends AC_Column_Media_Parent {
/**
* Remove default column width
*/
public function register_settings() {
}
}
/**
* Provides inline-editing for menu_order
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_MenuOrder extends AC_Column
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'menu_order' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Order
*/
public function editing() {
return new ACP_Editing_Model_Post_Order( $this );
}
}
/**
* Provides inline-editing for alt_text
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_AltText extends ACP_Column_Media_AlternateText
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'alt_text' );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Caption extends ACP_Column_Media_Caption
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'caption' );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Description extends AC_Column_Media_Description
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'description' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Post_Content( $this );
}
}
/**
* Provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_MimeType extends AC_Column_Media_MimeType
implements ACP_Column_EditingInterface {
/**
* Define column properties
*/
public function __construct() {
$this->set_original( true );
$this->set_type( 'post_mime_type' );
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Media_MimeType( $this );
}
}
/**
* Removes ACP defaults for date
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Date extends ACP_Column_Media_Date {
/**
* Remove default column width
*/
public function register_settings() {
}
}
/**
* Removes ACP defaults & provides inline-editing for caption
*
* @package Media Library Assistant
* @since 2.52
*/
class ACP_Addon_MLA_Column_Author extends AC_Column_Media_Author
implements ACP_Column_EditingInterface {
/**
* Remove default column width
*/
public function register_settings() {
}
/**
* Add inline editing support
*
* @return ACP_Editing_Model_Post_Content
*/
public function editing() {
return new ACP_Editing_Model_Post_Author( $this );
}
}

View File

@@ -0,0 +1,224 @@
<?php
/**
* Media Library Assistant Admin Columns (plugin) Support
*
* @package Media Library Assistant
* @since 2.22
*/
defined( 'ABSPATH' ) or die();
/**
* Class CPAC Storage Model MLA (Media Library Assistant) supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.22
*/
class CPAC_Deprecated_Storage_Model_MLA extends CPAC_Storage_Model {
/**
* Identifies submenu entry in the Admin sidebar, e.g., Media/Assistant in Media
*
* @since 2.25
* @var string
*/
public $subpage;
/**
* Initializes some properties, installs filters and then
* calls the parent constructor to set some default configs.
*
* @since 2.22
*/
public function __construct() {
$this->key = 'mla-media-assistant';
$this->label = __( 'Media Library Assistant' );
$this->singular_label = __( 'Assistant' );
$this->type = 'media';
$this->meta_type = 'post';
$this->page = 'upload';
$this->subpage = MLACore::ADMIN_PAGE_SLUG;
$this->post_type = 'attachment';
$this->menu_type = 'other';
// Increased the priority to overrule 3th party plugins such as Media Tags
add_filter( 'manage_media_page_' . MLACore::ADMIN_PAGE_SLUG . '_columns', array( $this, 'add_headings' ), 100 );
add_filter( 'mla_list_table_column_default', array( $this, 'mla_manage_value' ), 100, 3 );
parent::__construct();
}
/**
* Added in Admin Columns update to v2.4.9
*
* @since 2.23
*/
public function init_manage_columns() {
//add_filter( "manage_{$this->page}_columns", array( $this, 'add_headings' ), 100 );
//add_action( 'manage_comments_custom_column', array( $this, 'manage_value' ), 100, 2 );
}
/**
* Returns the Media/Assistant submenu table column definitions
*
* @since 2.22
*
* @return array ( 'column_slug' => 'column_heading' )
*/
public function get_default_columns() {
if ( ! class_exists( 'MLAQuery' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
MLAQuery::initialize();
}
return apply_filters( 'mla_list_table_get_columns', MLAQuery::$default_columns );
}
/**
* Returns the Media/Assistant submenu table column slugs/keys
*
* @since 2.22
*
* @return array ( index => 'column_slug' )
*/
public function get_default_column_names() {
if ( ! class_exists( 'MLAQuery' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
MLAQuery::initialize();
}
return array_keys( apply_filters( 'mla_list_table_get_columns', MLAQuery::$default_columns ) );
}
/**
* Returns the custom fields assigned to Media Library items, removing those already present
* in the Media/Assistant submenu table
*
* @since 2.22
*
* @return array ( index => array( 0 => 'custom field name' ) )
*/
public function get_meta() {
global $wpdb;
/*
* Find all of the custom field names assigned to Media Library items
*/
$meta = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON pm.post_id = p.ID WHERE p.post_type = 'attachment' ORDER BY 1", ARRAY_N );
//error_log( __LINE__ . ' CPAC_Deprecated_Storage_Model_MLA::get_meta meta = ' . var_export( $meta, true ), 0 );
/*
* Find the fields already present in the submenu table
*/
$mla_columns = apply_filters( 'mla_list_table_get_columns', MLAQuery::$default_columns );
//error_log( __LINE__ . ' CPAC_Deprecated_Storage_Model_MLA::get_meta mla_columns = ' . var_export( $mla_columns, true ), 0 );
$mla_custom = array();
foreach ( $mla_columns as $slug => $heading ) {
if ( 'c_' === substr( $slug, 0, 2 ) ) {
$mla_custom[] = $heading;
}
}
//error_log( __LINE__ . ' CPAC_Deprecated_Storage_Model_MLA::get_meta mla_custom = ' . var_export( $mla_custom, true ), 0 );
/*
* Remove the fields already present in the submenu table
*/
foreach ( $meta as $index => $value ) {
if ( in_array( esc_html( current( $value ) ), $mla_custom ) ) {
unset( $meta[ $index ] );
}
}
//error_log( __LINE__ . ' CPAC_Deprecated_Storage_Model_MLA::get_meta meta = ' . var_export( $meta, true ), 0 );
return $meta;
}
/**
* Return the content of an Admin Columns custom column
*
* @since 2.22
*
* @param string $content Current column content (empty string)
* @param object $item Current Media Library item
* @param string $column_name Current column slug
*
* @return string Column value or NULL if not an Admin Columns custom column
*/
public function mla_manage_value( $content, $item, $column_name ) {
$media_id = $item->ID;
if ( ! ( $column = $this->get_column_by_name( $column_name ) ) ) {
return null;
}
$value = $column->get_value( $media_id );
// hooks
$value = apply_filters( "cac/column/value", $value, $media_id, $column, $this->key );
$value = apply_filters( "cac/column/value/{$this->type}", $value, $media_id, $column, $this->key );
return $value;
}
/**
* Test for current screen = the Media/Assistant submenu screen,
* For Admin Columns 2.4.9+
*
* @since 2.23
*
* @return boolean true if the Media/Assistant submenu is the current screen
*/
public function is_current_screen() {
$is_current_screen = parent::is_current_screen();
if ( ! $is_current_screen ) {
if ( ! empty( $_REQUEST['page'] ) && MLACore::ADMIN_PAGE_SLUG == $_REQUEST['page'] ) {
$is_current_screen = true;
}
}
return $is_current_screen;
}
/**
* Test for current screen = the Media/Assistant submenu screen
*
* @since 2.22
*
* @return boolean true if the Media/Assistant submenu is the current screen
*/
public function is_columns_screen() {
$is_columns_screen = parent::is_columns_screen();
if ( ! $is_columns_screen ) {
if ( ! empty( $_REQUEST['page'] ) && MLACore::ADMIN_PAGE_SLUG == $_REQUEST['page'] ) {
$is_columns_screen = true;
}
}
return $is_columns_screen;
}
/**
* Return a link to the Media/Assistant submenu screen
*
* @since 2.22
*
* @return string Link to the Media/Assistant submenu screen
*/
protected function get_screen_link() {
return is_network_admin() ? network_admin_url( $this->page . '.php?page=' . MLACore::ADMIN_PAGE_SLUG ) : admin_url( $this->page . '.php?page=' . MLACore::ADMIN_PAGE_SLUG );
}
/**
* Return a link to the Media/Assistant submenu Edit columns screen
*
* @since 2.22
*
* @return string Link to the Media/Assistant submenu Edit columns screen
*/
public function get_edit_link() {
return add_query_arg( array(
'page' => 'codepress-admin-columns',
'cpac_key' => $this->key,
), admin_url( 'options-general.php' ) );
}
} // class CPAC_Storage_Model_MLA

View File

@@ -0,0 +1,243 @@
<?php
/**
* Media Library Assistant Admin Columns (plugin) Support
*
* @package Media Library Assistant
* @since 2.50
*/
defined( 'ABSPATH' ) or die();
// Accomodate class namespace introduction in Admin Columns 3.2.x
if ( class_exists( 'AC\ListScreen\Media' ) ) {
/**
* Class Admin Columns List Screen Stub for Admin Columns 3.2.x+
*/
class AC_Addon_MLA_ListScreen_Stub extends AC\ListScreen\Media {
}
} else {
/**
* Class Admin Columns List Screen Stub for Admin Columns 3.1.x-
*/
class AC_Addon_MLA_ListScreen_Stub extends AC_ListScreen_Media {
}
}
/**
* Class Admin Columns Addon MLA (Media Library Assistant) List Screen supports the Admin Columns plugin
*
* @package Media Library Assistant
* @since 2.50
*/
class AC_Addon_MLA_ListScreen extends AC_Addon_MLA_ListScreen_Stub {
/**
* Initializes some properties, installs filters and then
* calls the parent constructor to set some default configs.
*
* @since 2.50
*/
public function __construct() {
parent::__construct();
$this->set_key( 'mla-media-assistant' );
$this->set_label( __( 'Media Library Assistant' ) );
$this->set_singular_label( __( 'Assistant' ) );
$this->set_screen_id( 'media_page_' . MLACore::ADMIN_PAGE_SLUG );
$this->set_page( MLACore::ADMIN_PAGE_SLUG );
add_filter( 'ac/column/custom_field/meta_keys', 'AC_Addon_MLA_ListScreen::remove_custom_columns', 10, 1 );
}
/**
* Contains the hook that contains the manage_value callback
*
* @since 2.50
*/
public function set_manage_value_callback() {
add_filter( 'mla_list_table_column_default', array( $this, 'column_default_value' ), 100, 3 );
}
/**
* Create and return a new MLA List Table object
*
* @param array $args
*
* @return WP_List_Table|false
*/
public function get_list_table( $args = array() ) {
global $wp_list_table;
if ( ! class_exists( 'MLA_List_Table' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-list-table.php' );
MLA_List_Table::mla_admin_init_action();
}
if ( $wp_list_table instanceof MLA_List_Table ) {
return $wp_list_table;
}
$list_table = new MLA_List_Table();
$list_table->prepare_items();
// Don't show the Export button before 4.2.3
if ( function_exists( 'ACP' ) && version_compare( ACP()->get_version(), '4.2.3', '<' ) ) {
$wp_list_table = NULL;
}
return $list_table;
}
/**
* Test for current screen = the Media/Assistant submenu screen,
* For Admin Columns 2.4.9+
*
* @since 2.23
*
* @param object $wp_screen
*
* @return boolean true if the Media/Assistant submenu is the current screen
*/
public function is_current_screen( $wp_screen ) {
return $wp_screen && $wp_screen->id === $this->get_screen_id();
}
/**
* Remove duplicate columns from the Admin Columns "Custom" section
*
* @since 2.50
*
* @param AC_ListScreen $listscreen
*/
public function register_column_types() {
parent::register_column_types();
//error_log( __LINE__ . ' AC_Addon_MLA_ListScreen::register_column_types ' . var_export( array_keys( $this->get_column_types() ), true ), 0 );
$exclude = array(
'comments',
'title',
'column-actions',
'column-alternate_text',
'column-attached_to',
'column-author_name',
'column-caption',
'column-description',
'column-file_name',
'column-full_path',
'column-mediaid',
'column-mime_type',
'column-taxonomy',
/*
'column-meta',
'column-available_sizes',
'column-dimensions',
'column-exif_data',
'column-file_size',
'column-height',
'column-image',
'column-used_by_menu',
'column-width',
*/
);
foreach ( $exclude as $column_type ) {
$this->deregister_column_type( $column_type );
}
}
/**
* Remove duplicate columns from the Admin Columns "Custom" section
*
* @since 2.52
*
* @param array $keys Distinct meta keys from DB
*/
public static function remove_custom_columns( $keys ) {
// Find the fields already present in the submenu table
$mla_columns = apply_filters( 'mla_list_table_get_columns', MLAQuery::$default_columns );
$mla_custom = array();
foreach ( $mla_columns as $slug => $heading ) {
if ( 'c_' === substr( $slug, 0, 2 ) ) {
$mla_custom[] = $heading;
}
}
// Remove the fields already present in the submenu table
foreach ( $keys as $index => $value ) {
if ( in_array( esc_html( $value ), $mla_custom ) ) {
unset( $keys[ $index ] );
}
}
return $keys;
}
/**
* Default column headers
*
* @since 2.50
*
* @return array
*/
public function get_column_headers() {
if ( ! class_exists( 'MLAQuery' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
MLAQuery::initialize();
}
return apply_filters( 'mla_list_table_get_columns', MLAQuery::$default_columns );
}
/**
* Return the column value for AC/ACP custom columns, e.g., EXIF values
*
* @param string|null $content
* @param WP_Post $post
* @param string $column_name
*
* @return string|false
*/
public function column_default_value( $content, $post, $column_name ) {
if ( is_null( $content ) ) {
$content = $this->get_display_value_by_column_name( $column_name, $post->ID );
}
return $content;
}
/**
* Return an MLA version of a Media Library item
*
* @since 2.71
*
* @param integer $post_id
*
* @return object attachment object
*/
public function get_object( $post_id ) {
// Author column depends on this global to be set.
global $authordata;
$authordata = get_userdata( get_post_field( 'post_author', $post_id ) );
if ( ! class_exists( 'MLAData' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
MLAData::initialize();
}
return (object) MLAData::mla_get_attachment_by_id( $post_id );
}
/**
* Return an MLA version of a Media Library item for older Admin Columns versions
*
* @since 2.52
*
* @param integer $post_id
*
* @return object attachment object
*/
protected function get_object_by_id( $post_id ) {
return $this->get_object( $post_id );
}
} // class AC_Addon_MLA_ListScreen

View File

@@ -0,0 +1,349 @@
<?php
/**
* Media Library Assistant Ajax Handlers
*
* @package Media Library Assistant
* @since 2.20
*/
/**
* Class MLA (Media Library Assistant) Ajax contains handlers for simple Ajax requests
*
* @package Media Library Assistant
* @since 2.20
*/
class MLA_Ajax {
/**
* True if limiting MLA to AJAX support, false if loading all of MLA
*
* Recorded here for debug logging purposes; set in mla-plugin-loader.php.
*
* @since 2.50
*
* @var boolean
*/
public static $ajax_only = NULL;
/**
* Initialization function, similar to __construct()
*
* @since 2.20
*
* @return void
*/
public static function initialize() {
if ( ! ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'heartbeat' ) ) {
$ajax_only = var_export( self::$ajax_only, true );
MLACore::mla_debug_add( __LINE__ . " MLA_Ajax::initialize( {$ajax_only} ) \$_REQUEST = " . var_export( $_REQUEST, true ), MLACore::MLA_DEBUG_CATEGORY_AJAX );
}
// If there's no action variable, we have nothing more to do
if ( ! isset( $_REQUEST['action'] ) ) {
return;
}
// Defined here because the "admin_init" action is not called for item transfers
if ( 'mla_named_transfer' == $_REQUEST['action'] ) {
add_action( 'wp_ajax_' . 'mla_named_transfer', 'MLA_Ajax::mla_named_transfer_ajax_action' );
add_action( 'wp_ajax_nopriv_' . 'mla_named_transfer', 'MLA_Ajax::mla_named_transfer_ajax_action' );
} else {
add_action( 'admin_init', 'MLA_Ajax::mla_admin_init_action' );
}
}
/**
* Adds flat checklist taxonomy support to the Media Manager Modal Window.
* Declared public because it is an action.
*
* @since 2.20
*/
public static function mla_admin_init_action( ) {
/*
* For flat taxonomies that use the checklist meta box, substitute our own handler
* for /wp-admin/includes/ajax-actions.php function _wp_ajax_add_hierarchical_term().
*/
if ( ( defined('DOING_AJAX') && DOING_AJAX ) && ( 'add-' == substr( $_REQUEST['action'], 0, 4 ) ) ) {
$key = substr( $_REQUEST['action'], 4 );
if ( MLACore::mla_taxonomy_support( $key, 'flat-checklist' ) ) {
self::_mla_ajax_add_flat_term( $key );
/* note: this function sends an Ajax response and then dies; no return */
}
}
add_action( 'wp_ajax_' . 'mla_find_posts', 'MLA_Ajax::mla_find_posts_ajax_action' );
add_action( 'wp_ajax_' . MLACore::JAVASCRIPT_INLINE_EDIT_SLUG . '-set-parent', 'MLA_Ajax::mla_set_parent_ajax_action' );
}
/**
* Add flat taxonomy term from "checklist" meta box on the Media Manager Modal Window
*
* Adapted from the WordPress post_categories_meta_box() in /wp-admin/includes/meta-boxes.php.
*
* @since 2.20
*
* @param string The taxonomy name, from $_REQUEST['action']
*
* @return void Sends JSON response with updated HTML for the checklist
*/
private static function _mla_ajax_add_flat_term( $key ) {
$taxonomy = get_taxonomy( $key );
check_ajax_referer( $_REQUEST['action'], '_ajax_nonce-add-' . $key, true );
if ( !current_user_can( $taxonomy->cap->edit_terms ) ) {
wp_die( -1 );
}
$new_names = explode( ',', $_POST[ 'new' . $key ] );
$new_terms_markup = '';
foreach( $new_names as $name ) {
if ( '' === sanitize_title( $name ) ) {
continue;
}
if ( ! $id = term_exists( $name, $key ) ) {
$id = wp_insert_term( $name, $key );
}
if ( is_wp_error( $id ) ) {
continue;
}
if ( is_array( $id ) ) {
$id = absint( $id['term_id'] );
} else {
continue;
}
$term = get_term( $id, $key );
$name = $term->name;
$new_terms_markup .= "<li id='{$key}-{$id}'><label class='selectit'><input value='{$name}' type='checkbox' name='tax_input[{$key}][]' id='in-{$key}-{$id}' checked='checked' />{$name}</label></li>\n";
} // foreach new_name
$input_new_parent_name = "new{$key}_parent";
$supplemental = "<input type='hidden' name='{$input_new_parent_name}' id='{$input_new_parent_name}' value='-1' />";
$add = array(
'what' => $key,
'id' => $id,
'data' => $new_terms_markup,
'position' => -1,
'supplemental' => array( 'newcat_parent' => $supplemental )
);
$x = new WP_Ajax_Response( $add );
$x->send();
} // _mla_ajax_add_flat_term
/**
* Ajax handler to stream/view or download a Media Library item
*
* @since 2.63
*
* @return void echo HTML for file streaming or download, then exit()
*/
public static function mla_named_transfer_ajax_action() {
if ( !class_exists( 'MLAFileDownloader' ) ) {
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-file-downloader.php' );
}
$download_args = array();
if ( empty( $_REQUEST['mla_item'] ) ) {
$download_args['error'] = 'ERROR: mla_item argument not set.';
} else {
$item_name = $_REQUEST['mla_item'];
$args = array(
'name' => $item_name,
'post_type' => 'attachment',
'post_status' => 'inherit',
'posts_per_page' => 1
);
$items = get_posts( $args );
if( $items ) {
$file = get_attached_file( $items[0]->ID );
if ( !empty( $file ) ) {
$download_args['mla_download_file'] = $file;
$download_args['mla_download_type'] = $items[0]->post_mime_type;
if ( !empty( $_REQUEST['mla_disposition'] ) ) {
$download_args['mla_disposition'] = $_REQUEST['mla_disposition'];
}
} else {
$download_args['error'] = 'ERROR: mla_item no attached file.';
}
} else {
$download_args['error'] = 'ERROR: mla_item not found.';
}
}
MLAFileDownloader::$mla_debug = isset( $_REQUEST['mla_debug'] ) && 'log' == $_REQUEST['mla_debug'];
MLAFileDownloader::mla_process_download_file( $download_args );
MLACore::mla_debug_add( __LINE__ . " MLA_Ajax::mla_named_transfer_ajax_action failed. \$_REQUEST = " . var_export( $_REQUEST, true ), MLACore::MLA_DEBUG_CATEGORY_AJAX );
echo "MLA_Ajax::mla_named_transfer_ajax_action failed.";
die();
} // mla_named_transfer_ajax_action
/**
* Ajax handler to fetch candidates for the "Set Parent" popup window
*
* Adapted from wp_ajax_find_posts in /wp-admin/includes/ajax-actions.php.
* Adds filters for post type and pagination.
*
* @since 1.90
*
* @return void passes results to wp_send_json_success() for JSON encoding and transmission
*/
public static function mla_find_posts_ajax_action() {
global $wpdb;
check_ajax_referer( 'mla_find_posts', MLACore::MLA_ADMIN_NONCE_NAME );
$post_types = get_post_types( array( 'public' => true ), 'objects' );
unset( $post_types['attachment'] );
$s = stripslashes( $_REQUEST['mla_set_parent_search_text'] );
$count = isset( $_REQUEST['mla_set_parent_count'] ) ? $_REQUEST['mla_set_parent_count'] : 50;
$paged = isset( $_REQUEST['mla_set_parent_paged'] ) ? $_REQUEST['mla_set_parent_paged'] : 1;
$args = array(
'post_type' => ( 'all' == $_REQUEST['mla_set_parent_post_type'] ) ? array_keys( $post_types ) : $_REQUEST['mla_set_parent_post_type'],
'post_status' => 'any',
'posts_per_page' => $count,
'paged' => $paged,
);
if ( '' !== $s )
$args['s'] = $s;
$posts = get_posts( $args );
if ( ( ! $posts ) && $paged > 1 ) {
$args['paged'] = $paged = 1;
$posts = get_posts( $args );
}
$found = count( $posts );
$html = '<input name="mla_set_parent_count" id="mla-set-parent-count" type="hidden" value="' . $count . "\">\n";
$html .= '<input name="mla_set_parent_paged" id="mla-set-parent-paged" type="hidden" value="' . $paged . "\">\n";
$html .= '<input name="mla_set_parent_found" id="mla-set-parent-found" type="hidden" value="' . $found . "\">\n";
$html .= '<table class="widefat"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th class="no-break">'.__('Type').'</th><th class="no-break">'.__('Date').'</th><th class="no-break">'.__('Status').'</th></tr></thead><tbody>' . "\n";
if ( $found ) {
$alt = '';
foreach ( $posts as $post ) {
$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
$alt = ( 'alternate' == $alt ) ? '' : 'alternate';
switch ( $post->post_status ) {
case 'publish' :
case 'private' :
$stat = __('Published');
break;
case 'future' :
$stat = __('Scheduled');
break;
case 'pending' :
$stat = __('Pending Review');
break;
case 'draft' :
$stat = __('Draft');
break;
default:
$stat = sanitize_text_field( $post->post_status );
}
if ( '0000-00-00 00:00:00' == $post->post_date ) {
$time = '';
} else {
/* translators: date format in table columns, see http://php.net/date */
$time = mysql2date(__('Y/m/d'), $post->post_date);
}
$html .= '<tr class="' . trim( 'found-posts ' . $alt ) . '"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>';
$html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n";
} // foreach post
} else {
$html .= '<tr class="' . trim( 'found-posts ' ) . '"><td class="found-radio">&nbsp;</td>';
$html .= '<td colspan="4">No results found.</td></tr>' . "\n";
}
$html .= "</tbody></table>\n";
wp_send_json_success( $html );
}
/**
* Ajax handler to set post_parent for a single attachment
*
* Adapted from wp_ajax_inline_save in /wp-admin/includes/ajax-actions.php
*
* @since 0.20
*
* @return void echo HTML <td> innerHTML for updated call or error message, then die()
*/
public static function mla_set_parent_ajax_action() {
check_ajax_referer( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME );
if ( empty( $_REQUEST['post_ID'] ) ) {
echo __( 'ERROR', 'media-library-assistant' ) . ': ' . __( 'No post ID found', 'media-library-assistant' );
die();
} else {
$post_id = $_REQUEST['post_ID'];
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( __( 'ERROR', 'media-library-assistant' ) . ': ' . __( 'You are not allowed to edit this Attachment.', 'media-library-assistant' ) );
}
if ( ! class_exists( 'MLAData' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
MLAData::initialize();
}
$results = MLAData::mla_update_single_item( $post_id, $_REQUEST );
if ( false !== strpos( $results['message'], __( 'ERROR', 'media-library-assistant' ) ) ) {
wp_die( $results['message'] );
}
$new_item = (object) MLAData::mla_get_attachment_by_id( $post_id );
if ( ! class_exists( 'MLA_List_Table' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-list-table.php' );
MLA_List_Table::mla_admin_init_action();
// Check for multi-language table column support
global $sitepress, $polylang;
if ( is_object( $sitepress ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-wpml-support.php' );
MLA_WPML::initialize();
MLA_WPML::admin_init(); // This action has already passed.
} elseif ( is_object( $polylang ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-polylang-support.php' );
MLA_Polylang::initialize();
MLA_Polylang::admin_init();
}
}
// Create an instance of our package class and echo the new HTML
$MLAListTable = apply_filters( 'mla_list_table_new_instance', NULL );
if ( is_null( $MLAListTable ) ) {
$MLAListTable = new MLA_List_Table();
}
$MLAListTable->single_row( $new_item );
die(); // this is required to return a proper result
}
} // Class MLA_Ajax
/*
* Check for Media Manager Enhancements
*/
if ( ( ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TOOLBAR ) ) || ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_GRID_TOOLBAR ) ) ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-media-modal-ajax.php' );
add_action( 'init', 'MLAModal_Ajax::initialize', 0x7FFFFFFF );
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,857 @@
<?php
/**
* Meta data parsing functions for PDF documents
*
* @package Media Library Assistant
* @since 2.10
*/
/**
* Class MLA (Media Library Assistant) PDF extracts legacy and XMP meta data from PDF files
*
* @package Media Library Assistant
* @since 2.10
*/
class MLAPDF {
/**
* Array of PDF indirect objects
*
* This array contains all of the indirect object offsets and lengths.
* The array key is ( object ID * 1000 ) + object generation.
* The array value is array( number, generation, start, optional /length )
*
* @since 2.10
*
* @var array
*/
private static $pdf_indirect_objects = NULL;
/**
* Parse a cross-reference table subsection into the array of indirect object definitions
*
* A cross-reference subsection is a sequence of 20-byte entries, each with offset and generation values.
* @since 2.10
*
* @param string buffer containing the subsection
* @param integer offset within the buffer of the first entry
* @param integer number of the first object in the subsection
* @param integer number of entries in the subsection
*
* @return void
*/
private static function _parse_pdf_xref_subsection( &$xref_section, $offset, $object_id, $count ) {
while ( $count-- ) {
$match_count = preg_match( '/(\d+) (\d+) (.)/', $xref_section, $matches, 0, $offset);
if ( $match_count ) {
if ( 'n' == $matches[3] ) {
$key = ( $object_id * 1000 ) + $matches[2];
if ( ! isset( self::$pdf_indirect_objects[ $key ] ) ) {
self::$pdf_indirect_objects[ $key ] = array( 'number' => $object_id, 'generation' => (integer) $matches[2], 'start' => (integer) $matches[1] );
}
}
$object_id++;
$offset += 20;
} else {
break;
}
}
}
/**
* Parse a cross-reference table section into the array of indirect object definitions
*
* Creates the array of indirect object offsets and lengths
* @since 2.10
*
* @param string full path and file name
* @param integer offset within the file of the xref id and count entry
*
* @return integer length of the section
*/
private static function _parse_pdf_xref_section( $file_name, $file_offset ) {
$xref_max = $chunksize = 16384;
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$xref_length = 0;
while ( preg_match( '/^[\x00-\x20]*(\d+) (\d+)[\x00-\x20]*/', substr($xref_section, $xref_length), $matches, 0 ) ) {
$object_id = $matches[1];
$count = $matches[2];
$offset = $xref_length + strlen( $matches[0] );
$xref_length = $offset + ( 20 * $count );
if ( $xref_max < $xref_length ) {
$xref_max += $chunksize;
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $xref_max );
}
self::_parse_pdf_xref_subsection( $xref_section, $offset, $object_id, $count );
} // while preg_match subsection header
return $xref_length;
}
/**
* Parse a cross-reference steam into the array of indirect object definitions
*
* Creates the array of indirect object offsets and lengths
* @since 2.10
*
* @param string full path and file name
* @param integer offset within the file of the xref id and count entry
* @param string "/W" entry, representing the size of the fields in a single entry
*
* @return integer length of the stream
*/
private static function _parse_pdf_xref_stream( $file_name, $file_offset, $entry_parms_string ) {
$chunksize = 16384;
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
if ( 'stream' == substr( $xref_section, 0, 6 ) ) {
$tag_length = 7;
if ( chr(0x0D) == $xref_section[6] ) {
$tag_length++;
}
} else {
return 0;
}
/*
* If necessary and possible, expand the $xref_section until it contains the end tag
*/
$new_chunksize = $chunksize;
if ( false === ( $end_tag = strpos( $xref_section, 'endstream', $tag_length ) ) && ( $chunksize == strlen( $xref_section ) ) ) {
$new_chunksize = $chunksize + $chunksize;
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $new_chunksize );
while ( false === ( $end_tag = strpos( $xref_section, 'endstream' ) ) && ( $new_chunksize == strlen( $xref_section ) ) ) {
$new_chunksize = $new_chunksize + $chunksize;
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $new_chunksize );
} // while not found
} // if not found
if ( false == $end_tag ) {
$length = 0;
} else {
$length = $end_tag - $tag_length;
}
if ( false == $end_tag ) {
return 0;
}
return $length;
$entry_parms = explode( ' ', $entry_parms_string );
$object_id = $matches[1];
$count = $matches[2];
$offset = strlen( $matches[0] );
$length = $offset + ( 20 * $count );
if ( $chunksize < $length ) {
$xref_section = file_get_contents( $file_name, true, NULL, $file_offset, $length );
$offset = 0;
}
while ( $count-- ) {
$match_count = preg_match( '/(\d+) (\d+) (.)/', $xref_section, $matches, 0, $offset);
if ( $match_count ) {
if ( 'n' == $matches[3] ) {
$key = ( $object_id * 1000 ) + $matches[2];
if ( ! isset( self::$pdf_indirect_objects[ $key ] ) ) {
self::$pdf_indirect_objects[ $key ] = array( 'number' => $object_id, 'generation' => (integer) $matches[2], 'start' => (integer) $matches[1] );
}
}
$object_id++;
$offset += 20;
} else {
break;
}
}
return $length;
}
/**
* Build an array of indirect object definitions
*
* Creates the array of indirect object offsets and lengths
* @since 2.10
*
* @param string The entire PDF document, passsed by reference
*
* @return void
*/
private static function _build_pdf_indirect_objects( &$string ) {
if ( ! is_null( self::$pdf_indirect_objects ) ) {
return;
}
$match_count = preg_match_all( '!(\d+)\\h+(\d+)\\h+obj|endobj|stream(\x0D\x0A|\x0A)|endstream!', $string, $matches, PREG_OFFSET_CAPTURE );
self::$pdf_indirect_objects = array();
$object_level = 0;
$is_stream = false;
for ( $index = 0; $index < $match_count; $index++ ) {
if ( $is_stream ) {
if ( 'endstream' == substr( $matches[0][ $index ][0], 0, 9 ) ) {
$is_stream = false;
}
} elseif ( 'endobj' == substr( $matches[0][ $index ][0], 0, 6 ) ) {
$object_level--;
$object_entry['/length'] = $matches[0][ $index ][1] - $object_entry['start'];
self::$pdf_indirect_objects[ ($object_entry['number'] * 1000) + $object_entry['generation'] ] = $object_entry;
} elseif ( 'obj' == substr( $matches[0][ $index ][0], -3 ) ) {
$object_level++;
$object_entry = array(
'number' => $matches[1][ $index ][0],
'generation' => $matches[2][ $index ][0],
'start' => $matches[0][ $index ][1] + strlen( $matches[0][ $index ][0] )
);
} elseif ( 'stream' == substr( $matches[0][ $index ][0], 0, 6 ) ) {
$is_stream = true;
} else {
/* translators: 1: ERROR tag 2: index */
MLACore::mla_debug_add( sprintf( _x( '%1$s: _build_pdf_indirect_objects bad value at $index = "%2$d".', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $index ), MLACore::MLA_DEBUG_CATEGORY_ANY );
}
} // for each match
}
/**
* Find the offset, length and contents of an indirect object containing a dictionary
*
* The function searches the entire file, if necessary, to find the last/most recent copy of the object.
* This is required because Adobe Acrobat does NOT increment the generation number when it reuses an object.
*
* @since 2.10
*
* @param string full path and file name
* @param integer The object number
* @param integer The object generation number; default zero (0)
* @param integer The desired object instance (when multiple instances are present); default "highest/latest"
*
* @return mixed NULL on failure else array( 'start' => offset in the file, 'length' => object length, 'content' => dictionary contents )
*/
private static function _find_pdf_indirect_dictionary( $file_name, $object, $generation = 0, $instance = NULL ) {
$chunksize = 16384;
$key = ( $object * 1000 ) + $generation;
if ( isset( self::$pdf_indirect_objects ) && isset( self::$pdf_indirect_objects[ $key ] ) ) {
$file_offset = self::$pdf_indirect_objects[ $key ]['start'];
} else { // found object location
$file_offset = 0;
}
$object_starts = array();
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$file_name}, {$file_offset} ) object_content = \r\n" . MLAData::mla_hex_dump( $object_content ), 0 );
/*
* Match the object header
*/
$pattern = sprintf( '!%1$d\\h+%2$d\\h+obj[\\x00-\\x20]*(<<)!', $object, $generation );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$object}, {$generation} ) pattern = " . var_export( $pattern, true ), 0 );
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$match_count} ) matches = " . var_export( $matches, true ), 0 );
if ( $match_count ) {
$object_starts[] = array( 'offset' => $file_offset, 'start' => $matches[1][1]);
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$file_offset}, {$matches[1][1]} ) object_content = \r\n" . MLAData::mla_hex_dump( substr( $object_content, $matches[1][1] ), 512 ), 0 );
$match_count = 0;
}
/*
* If necessary and possible, advance the $object_content through the file until it contains the start tag
*/
if ( 0 == $match_count && ( $chunksize == strlen( $object_content ) ) ) {
$file_offset += ( $chunksize - 16 );
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$match_count} ) matches = " . var_export( $matches, true ), 0 );
if ( $match_count ) {
$object_starts[] = array( 'offset' => $file_offset, 'start' => $matches[1][1]);
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$file_offset}, {$matches[1][1]} ) object_content = \r\n" . MLAData::mla_hex_dump( substr( $object_content, $matches[1][1] ), 512 ), 0 );
$match_count = 0;
}
while ( 0 == $match_count && ( $chunksize == strlen( $object_content ) ) ) {
$file_offset += ( $chunksize - 16 );
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$match_count} ) matches = " . var_export( $matches, true ), 0 );
if ( $match_count ) {
$object_starts[] = array( 'offset' => $file_offset, 'start' => $matches[1][1]);
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary( {$file_offset}, {$matches[1][1]} ) object_content = \r\n" . MLAData::mla_hex_dump( substr( $object_content, $matches[1][1] ), 512 ), 0 );
$match_count = 0;
}
} // while not found
} // if not found
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary object_starts = " . var_export( $object_starts, true ), 0 );
/*
* Return the highest/latest instance unless a specific instance is requested
*/
$object_count = count( $object_starts );
if ( is_null( $instance ) ) {
$object_start = array_pop( $object_starts );
} else {
$instance = absint( $instance );
$object_start = isset( $object_starts[ $instance ] ) ? $object_starts[ $instance ] : NULL;
}
if ( is_null( $object_start ) ) {
return NULL;
} else {
$file_offset = $object_start['offset'];
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$start = $object_start['start'];
}
/*
* If necessary and possible, expand the $object_content until it contains the end tag
*/
$pattern = '!>>[\\x00-\\x20]*[endobj|stream]!';
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE, $start );
if ( 0 == $match_count && ( $chunksize == strlen( $object_content ) ) ) {
$file_offset = $file_offset + $start;
$start = 0;
$new_chunksize = $chunksize + $chunksize;
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $new_chunksize );
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE, $start );
while ( 0 == $match_count && ( $new_chunksize == strlen( $object_content ) ) ) {
$new_chunksize = $new_chunksize + $chunksize;
$object_content = file_get_contents( $file_name, true, NULL, $file_offset, $new_chunksize );
$match_count = preg_match( $pattern, $object_content, $matches, PREG_OFFSET_CAPTURE, $start );
} // while not found
} // if not found
if ( 0 == $match_count ) {
return NULL;
}
if ($match_count) {
$results = array( 'count' => $object_count, 'start' => $file_offset + $start, 'length' => ($matches[0][1] + 2) - $start );
$results['content'] = substr( $object_content, $start, $results['length'] );
//error_log( __LINE__ . " MLAPDF::_find_pdf_indirect_dictionary results = " . var_export( $results, true ), 0 );
return $results;
} // found trailer
return NULL;
}
/**
* Parse a PDF Unicode (16-bit Big Endian) object
*
* @since 2.10
*
* @param string PDF string of 16-bit characters
*
* @return string UTF-8 encoded string
*/
private static function _parse_pdf_UTF16BE( &$source_string ) {
$output = '';
for ($index = 2; $index < strlen( $source_string ); ) {
$value = ( ord( $source_string[ $index++ ] ) << 8 ) + ord( $source_string[ $index++ ] );
if ( $value < 0x80 ) {
$output .= chr( $value );
} elseif ( $value < 0x100 ) {
$output .= MLAData::$utf8_chars[ $value - 0x80 ];
} else {
$output .= '.'; // TODO encode the rest
}
}
return $output;
}
/**
* Parse a PDF string object
*
* Returns an array with one dictionary entry. The array also has a '/length' element containing
* the number of bytes occupied by the string in the source string, including the enclosing parentheses.
*
* @since 2.10
*
* @param string data within which the string occurs
* @param integer offset within the source string of the opening '(' character.
*
* @return array ( key => array( 'type' => type, 'value' => value, '/length' => length ) ) for the string
*/
private static function _parse_pdf_string( &$source_string, $offset ) {
if ( '(' != $source_string[ $offset ] ) {
return array( 'type' => 'unknown', 'value' => '', '/length' => 0 );
}
/*
* Brute force, here we come...
*/
$output = '';
$level = 0;
$in_string = true;
$index = $offset + 1;
while ( $in_string ) {
$byte = $source_string[ $index++ ];
if ( '\\' == $byte ) {
switch ( $source_string[ $index ] ) {
case chr( 0x0A ):
if ( chr( 0x0D ) == $source_string[ $index + 1 ] ) {
$index++;
}
break;
case chr( 0x0D ):
if ( chr( 0x0A ) == $source_string[ $index + 1 ] ) {
$index++;
}
break;
case 'n':
$output .= chr( 0x0A );
break;
case 'r':
$output .= chr( 0x0D );
break;
case 't':
$output .= chr( 0x09 );
break;
case 'b':
$output .= chr( 0x08 );
break;
case 'f':
$output .= chr( 0x0C );
break;
default: // could be a 1- to 3-digit octal value
$digit_limit = $index + 3;
$digit_index = $index;
while ( $digit_index < $digit_limit ) {
if ( ! ctype_digit( $source_string[ $digit_index ] ) ) {
break;
} else {
$digit_index++;
}
}
if ( $digit_count = $digit_index - $index ) {
$output .= chr( octdec( substr( $source_string, $index, $digit_count ) ) );
$index += $digit_count - 1;
} else { // accept the character following the backslash
$output .= $source_string[ $index ];
}
} // switch
$index++;
} else { // REVERSE SOLIDUS
if ( '(' == $byte ) {
$level++;
} elseif ( ')' == $byte ) {
if ( 0 == $level-- ) {
$in_string = false;
continue;
}
}
$output .= $byte;
} // just another 8-bit value, but check for balanced parentheses
} // $in_string
return array( 'type' => 'string', 'value' => $output, '/length' => $index - $offset );
}
/**
* Parse a PDF Linearization Parameter Dictionary object
*
* Returns an array of dictionary contents, classified by object type: boolean, numeric, string, hex (string),
* indirect (object), name, array, dictionary, stream, and null.
* The array also has a '/length' element containing the number of bytes occupied by the
* dictionary in the source string, excluding the enclosing delimiters, if passed in.
* @since 2.10
*
* @param string data within which the object occurs, typically the start of a PDF document
* @param integer filesize of the PDF document, for validation purposes, or zero (0) to ignore filesize
*
* @return mixed array of dictionary objects on success, false on failure
*/
private static function _parse_pdf_LPD_dictionary( &$source_string, $filesize ) {
$header = substr( $source_string, 0, 1024 );
$match_count = preg_match( '!obj[\x00-\x20]*<<(/Linearized).*(>>)[\x00-\x20]*endobj!', $header, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count ) {
$LPD = self::_parse_pdf_dictionary( $header, $matches[1][1] );
}
return false;
}
/**
* Parse a PDF dictionary object
*
* Returns an array of dictionary contents, classified by object type: boolean, numeric, string, hex (string),
* indirect (object), name, array, dictionary, stream, and null.
* The array also has a '/length' element containing the number of bytes occupied by the
* dictionary in the source string, excluding the enclosing delimiters.
*
* @since 2.10
*
* @param string data within which the string occurs
* @param integer offset within the source string of the opening '<<' characters or the first content character.
*
* @return array ( '/length' => length, key => array( 'type' => type, 'value' => value ) ) for each dictionary field
*/
private static function _parse_pdf_dictionary( &$source_string, $offset ) {
/*
* Find the end of the dictionary
*/
if ( '<<' == substr( $source_string, $offset, 2 ) ) {
$nest = $offset + 2;
} else {
$nest = $offset;
}
$level = 1;
do {
$dictionary_end = strpos( $source_string, '>>', $nest );
if ( false === $dictionary_end ) {
/* translators: 1: ERROR tag 2: source offset 3: nest level */
MLACore::mla_debug_add( sprintf( _x( '%1$s: _parse_pdf_dictionary offset = %2$d, nest = %3$d.', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $offset, $nest ), MLACore::MLA_DEBUG_CATEGORY_ANY );
/* translators: 1: ERROR tag 2: dictionary excerpt */
MLACore::mla_debug_add( sprintf( _x( '%1$s: _parse_pdf_dictionary no end delimiter dump = %2$s.', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), MLAData::mla_hex_dump( substr( $source_string, $offset, 128 ), 128, 16 ) ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return array( '/length' => 0 );
}
$nest = strpos( $source_string, '<<', $nest );
if ( false === $nest ) {
$nest = $dictionary_end + 2;
$level--;
} elseif ( $nest < $dictionary_end ) {
$nest += 2;
$level++;
} else {
$nest = $dictionary_end + 2;
$level--;
}
} while ( $level );
$dictionary_length = $dictionary_end + 2 - $offset;
$dictionary = array();
// \x00-\x20 for whitespace
// \(|\)|\<|\>|\[|\]|\{|\}|\/|\% for delimiters
$match_count = preg_match_all( '!/([^\x00-\x20|\(|\)|\<|\>|\[|\]|\{|\}|\/|\%]*)([\x00-\x20]*)!', substr( $source_string, $offset, $dictionary_length ), $matches, PREG_OFFSET_CAPTURE );
$end_data = -1;
for ( $match_index = 0; $match_index < $match_count; $match_index++ ) {
$name = $matches[1][ $match_index ][0];
$value_start = $offset + $matches[2][ $match_index ][1] + strlen( $matches[2][ $match_index ][0] );
/*
* Skip over false matches within a string or nested dictionary
*/
if ( $value_start < $end_data ) {
continue;
}
$end_data = -1;
$value_count = preg_match(
'!(\/?[^\/\x0D\x0A]*)!',
substr( $source_string, $value_start, ($dictionary_end - $value_start ) ), $value_matches, PREG_OFFSET_CAPTURE );
if ( 1 == $value_count ) {
$value = trim( $value_matches[0][0] );
$length = strlen( $value );
$dictionary[ $name ]['value'] = $value;
if ( ! isset( $value[0] ) ) {
/* translators: 1: ERROR tag 2: entry name 3: value excerpt */
MLACore::mla_debug_add( sprintf( _x( '%1$s: _parse_pdf_dictionary bad value [ %2$s ] dump = %3$s', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $name, MLAData::mla_hex_dump( $value, 32, 16 ) ), MLACore::MLA_DEBUG_CATEGORY_ANY );
continue;
}
if ( in_array( $value, array( 'true', 'false' ) ) ) {
$dictionary[ $name ]['type'] = 'boolean';
} elseif ( is_numeric( $value ) ) {
$dictionary[ $name ]['type'] = 'numeric';
} elseif ( '(' == $value[0] ) {
$dictionary[ $name ] = self::_parse_pdf_string( $source_string, $value_start );
$end_data = $value_start + $dictionary[ $name ]['/length'];
unset( $dictionary[ $name ]['/length'] );
} elseif ( '<' == $value[0] ) {
if ( '<' == $value[1] ) {
$dictionary[ $name ]['value'] = self::_parse_pdf_dictionary( $source_string, $value_start );
$dictionary[ $name ]['type'] = 'dictionary';
$end_data = $value_start + 4 + $dictionary[ $name ]['value']['/length'];
unset( $dictionary[ $name ]['value']['/length'] );
} else {
$dictionary[ $name ]['type'] = 'hex';
}
} elseif ( '/' == $value[0] ) {
$dictionary[ $name ]['value'] = substr( $value, 1 );
$dictionary[ $name ]['type'] = 'name';
$match_index++; // Skip to the next key
} elseif ( '[' == $value[0] ) {
$dictionary[ $name ]['type'] = 'array';
$array_length = strpos( $source_string, ']', $value_start ) - ($value_start + 1);
$dictionary[ $name ]['value'] = substr( $source_string, $value_start + 1, $array_length );
$end_data = 2 + $value_start + $array_length;
} elseif ( 'null' == $value ) {
$dictionary[ $name ]['type'] = 'null';
} elseif ( 'stream' == substr( $value, 0, 6 ) ) {
$dictionary[ $name ]['type'] = 'stream';
} else {
$object_count = preg_match( '!(\d+)\h+(\d+)\h+R!', $value, $object_matches );
if ( 1 == $object_count ) {
$dictionary[ $name ]['type'] = 'indirect';
$dictionary[ $name ]['object'] = $object_matches[1];
$dictionary[ $name ]['generation'] = $object_matches[2];
} else {
$dictionary[ $name ]['type'] = 'unknown';
}
}
} else {
$dictionary[ $matches[1][ $match_index ][0] ] = array( 'value' => '' );
$dictionary[ $matches[1][ $match_index ][0] ]['type'] = 'nomatch';
}
} // foreach match
$dictionary['/length'] = $dictionary_length;
return $dictionary;
}
/**
* Extract dictionary from traditional cross-reference + trailer documents
*
* @since 2.10
*
* @param string full path to the desired file
* @param integer offset within file of the cross-reference table
*
* @return mixed array of "PDF dictionary arrays", newest first, or NULL on failure
*/
private static function _extract_pdf_trailer( $file_name, $file_offset ) {
$chunksize = 16384;
$tail = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$chunk_offset = 0;
/*
* look for traditional xref and trailer
*/
if ( 'xref' == substr( $tail, $chunk_offset, 4 ) ) {
$xref_length = self::_parse_pdf_xref_section( $file_name, $file_offset + $chunk_offset + 4 );
//error_log( __LINE__ . " MLAPDF::_extract_pdf_trailer xref_length = " . var_export( $xref_length, true ), 0 );
$chunk_offset += 4 + $xref_length;
if ( $chunk_offset > ( $chunksize - 1024 ) ) {
$file_offset += $chunk_offset;
$tail = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );
$chunk_offset = 0;
}
//error_log( __LINE__ . " MLAPDF::_extract_pdf_trailer( {$file_offset} ) tail = \r\n" . MLAData::mla_hex_dump( $tail, 0, 16, 0 ), 0 );
$match_count = preg_match( '/[\x00-\x20]*trailer[\x00-\x20]+/', $tail, $matches, PREG_OFFSET_CAPTURE, $chunk_offset );
//error_log( __LINE__ . " MLAPDF::_extract_pdf_trailer( {$match_count} ) matches = " . var_export( $matches, true ), 0 );
if ( $match_count ) {
$chunk_offset = $matches[0][1] + strlen( $matches[0][0] );
$dictionary = self::_parse_pdf_dictionary( $tail, $chunk_offset );
//error_log( __LINE__ . " MLAPDF::_extract_pdf_trailer dictionary = " . var_export( $dictionary, true ), 0 );
if ( isset( $dictionary['Prev'] ) ) {
$other_trailers = self::_extract_pdf_trailer( $file_name, $dictionary['Prev']['value'] );
} else {
$other_trailers = NULL;
}
if ( is_array( $other_trailers ) ) {
$other_trailers = array_merge( $other_trailers, array( $dictionary ) );
return $other_trailers;
} else {
return array( $dictionary );
}
} // found 'trailer'
} else { // found 'xref'
/*
* Look for a cross-reference stream
*/
$match_count = preg_match( '!(\d+)\\h+(\d+)\\h+obj[\x00-\x20]*!', $tail, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count ) {
$chunk_offset = $matches[0][1] + strlen( $matches[0][0] );
if ( '<<' == substr( $tail, $chunk_offset, 2) ) {
$dictionary = self::_parse_pdf_dictionary( $tail, $chunk_offset );
/*
* Parse the cross-reference stream following the dictionary, if present
*/
if ( isset( $dictionary['Type'] ) && 'XRef' == $dictionary['Type']['value'] ) {
$xref_length = self::_parse_pdf_xref_stream( $file_name, $file_offset + $chunk_offset + (integer) $dictionary['/length'], $dictionary['W']['value'] );
}
if ( isset( $dictionary['Prev'] ) ) {
$other_trailers = self::_extract_pdf_trailer( $file_name, $dictionary['Prev']['value'] );
} else {
$other_trailers = NULL;
}
if ( is_array( $other_trailers ) ) {
$other_trailers = array_merge( array( $dictionary ), $other_trailers );
return $other_trailers;
} else {
return array( $dictionary );
}
} // found cross-reference stream dictionary
} // found cross-reference stream object
}
return NULL;
}
/**
* Extract Metadata from a PDF file
*
* @since 2.10
*
* @param string full path to the desired file
*
* @return array ( 'xmp' => array( key => value ), 'pdf' => array( key => value ) ) for each metadata field, in string format
*/
public static function mla_extract_pdf_metadata( $file_name ) {
$xmp = array();
$metadata = array();
self::$pdf_indirect_objects = NULL;
$chunksize = 16384;
if ( ! file_exists( $file_name ) ) {
return array( 'xmp' => $xmp, 'pdf' => $metadata );
}
$filesize = filesize( $file_name );
$file_offset = ( $chunksize < $filesize ) ? ( $filesize - $chunksize ) : 0;
$tail = file_get_contents( $file_name, false, NULL, $file_offset );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata( {$file_name}, {$file_offset} ) tail = \r\n" . MLAData::mla_hex_dump( $tail ), 0 );
if ( 0 == $file_offset ) {
$header = substr( $tail, 0, 128 );
} else {
$header = file_get_contents( $file_name, false, NULL, 0, 128 );
}
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata( {$file_name}, {$file_offset} ) header = \r\n" . MLAData::mla_hex_dump( $header ), 0 );
if ( '%PDF-' == substr( $header, 0, 5 ) ) {
$metadata['PDF_Version'] = substr( $header, 1, 7 );
$metadata['PDF_VersionNumber'] = substr( $header, 5, 3 );
}
/*
* Find the xref and (optional) trailer
*/
$match_count = preg_match_all( '/startxref[\x00-\x20]+(\d+)[\x00-\x20]+\%\%EOF/', $tail, $matches, PREG_OFFSET_CAPTURE );
if ( 0 == $match_count ) {
/* translators: 1: ERROR tag 2: path and file */
MLACore::mla_debug_add( sprintf( _x( '%1$s: File "%2$s", startxref not found.', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $path ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return array( 'xmp' => $xmp, 'pdf' => $metadata );
}
$startxref = (integer) $matches[1][ $match_count - 1 ][0];
$trailer_dictionaries = self::_extract_pdf_trailer( $file_name, $startxref );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata trailer_dictionaries = " . var_export( $trailer_dictionaries, true ), 0 );
if ( is_array( $trailer_dictionaries ) ) {
$info_reference = NULL;
foreach ( $trailer_dictionaries as $trailer_dictionary ) {
if ( isset( $trailer_dictionary['Info'] ) ) {
$info_reference = $trailer_dictionary['Info'];
break;
}
}
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata info_reference = " . var_export( $info_reference, true ), 0 );
if ( isset( $info_reference ) ) {
$info_object = self::_find_pdf_indirect_dictionary( $file_name, $info_reference['object'], $info_reference['generation'] );
/*
* Handle single or multiple Info instances
*/
$info_objects = array();
if ( $info_object ) {
if ( 1 == $info_object['count'] ) {
$info_objects[] = $info_object;
} else {
for ( $index = 0; $index < $info_object['count']; $index++ ) {
$info_objects[] = self::_find_pdf_indirect_dictionary( $file_name, $info_reference['object'], $info_reference['generation'], $index );
}
}
}
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata info_objects = " . var_export( $info_objects, true ), 0 );
foreach( $info_objects as $info_object ) {
$info_dictionary = self::_parse_pdf_dictionary( $info_object['content'], 0 );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata info_dictionary = " . var_export( $info_dictionary, true ), 0 );
unset( $info_dictionary['/length'] );
foreach ( $info_dictionary as $name => $value ) {
if ( 'string' == $value['type'] ) {
$prefix = substr( $value['value'], 0, 2 );
if ( 'D:' == $prefix ) {
$metadata[ $name ] = MLAData::mla_parse_pdf_date( $value['value'] );
} elseif ( ( chr(0xFE) . chr(0xFF) ) == $prefix ) {
$metadata[ $name ] = self::_parse_pdf_UTF16BE( $value['value'] );
} else {
$metadata[ $name ] = $value['value'];
}
} else {
$metadata[ $name ] = $value['value'];
}
} // each info entry
} // foreach Info object
/*
* Remove spurious "Filter" dictionaries
*/
unset( $metadata['Filter'] );
unset( $metadata['Length'] );
unset( $metadata['Length1'] );
} // found Info reference
//error_log( __LINE__ . ' MLAPDF::mla_extract_pdf_metadata pdf metadata = ' . var_export( $metadata, true ), 0 );
/*
* Look for XMP Metadata
*/
$root_reference = NULL;
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata info_dictionary = " . var_export( $info_dictionary, true ), 0 );
foreach ( $trailer_dictionaries as $trailer_dictionary ) {
if ( isset( $trailer_dictionary['Root'] ) ) {
$root_reference = $trailer_dictionary['Root'];
break;
}
}
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata root_reference = " . var_export( $root_reference, true ), 0 );
if ( isset( $root_reference ) ) {
$root_object = self::_find_pdf_indirect_dictionary( $file_name, $root_reference['object'], $root_reference['generation'] );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata root_object = " . var_export( $root_object, true ), 0 );
if ( $root_object ) {
$root_dictionary = self::_parse_pdf_dictionary( $root_object['content'], 0 );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata root_dictionary = " . var_export( $root_dictionary, true ), 0 );
unset( $root_dictionary['/length'] );
if ( isset( $root_dictionary['Metadata'] ) ) {
$xmp_object = self::_find_pdf_indirect_dictionary( $file_name, $root_dictionary['Metadata']['object'], $root_dictionary['Metadata']['generation'] );
//error_log( __LINE__ . " MLAPDF::mla_extract_pdf_metadata xmp_object = " . var_export( $xmp_object, true ), 0 );
$xmp = MLAData::mla_parse_xmp_metadata( $file_name, $xmp_object['start'] + $xmp_object['length'] );
if ( is_array( $xmp ) ) {
$metadata = array_merge( $metadata, $xmp );
} else {
$xmp = array();
$xmp = MLAData::mla_parse_xmp_metadata( $file_name, 0 );
//error_log( __LINE__ . ' MLAPDF::mla_extract_pdf_metadata recovered xmp = ' . var_export( $xmp, true ), 0 );
}
} // found Metadata reference
} // found Root object
} // found Root reference
} // found trailer_dictionaries
//error_log( __LINE__ . ' MLAPDF::mla_extract_pdf_metadata pdf = ' . var_export( $metadata, true ), 0 );
//error_log( __LINE__ . ' MLAPDF::mla_extract_pdf_metadata xmp = ' . var_export( $xmp, true ), 0 );
return array( 'xmp' => $xmp, 'pdf' => $metadata );
}
} // class MLAPDF
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,893 @@
<?php
/**
* Database query support for "where-used" reporting
*
* @package Media Library Assistant
* @since 2.20
*/
/**
* Class MLA (Media Library Assistant) Query provides database query support
* for "where-used" reporting needs
*
* @package Media Library Assistant
* @since 2.20
*/
class MLAReferences {
/**
* Find Featured Image and inserted image/link references to an attachment
*
* Called from MLAQuery::mla_fetch_attachment_references, which handles conditional
* loading of this file.
*
* @since 0.1
*
* @param int post ID of attachment
* @param int post ID of attachment's parent, if any
* @param boolean True to compute references, false to return empty values
*
* @return array Reference information; see $references array comments
*/
public static function mla_fetch_attachment_references_handler( $ID, $parent, $add_references = true ) {
global $wpdb;
static $save_id = -1, $references, $inserted_in_option = NULL;
if ( $save_id == $ID ) {
return $references;
} elseif ( $ID == -1 ) {
$save_id = -1;
return NULL;
}
/*
* inserted_option 'enabled', 'base' or 'disabled'
* tested_reference true if any of the four where-used types was processed
* found_reference true if any where-used array is not empty()
* found_parent true if $parent matches a where-used post ID
* is_unattached true if $parent is zero (0)
* base_file relative path and name of the uploaded file, e.g., 2012/04/image.jpg
* path path to the file, relative to the "uploads/" directory, e.g., 2012/04/
* file The name portion of the base file, e.g., image.jpg
* files base file and any other image size files. Array key is path and file name.
* Non-image file value is a string containing file name without path
* Image file value is an array with file name, width and height
* features Array of objects with the post_type and post_title of each post
* that has the attachment as a "Featured Image"
* inserts Array of specific files (i.e., sizes) found in one or more posts/pages
* as an image (<img>) or link (<a href>). The array key is the path and file name.
* The array value is an array with the ID, post_type and post_title of each reference
* mla_galleries Array of objects with the post_type and post_title of each post
* that was returned by an [mla_gallery] shortcode
* galleries Array of objects with the post_type and post_title of each post
* that was returned by a [gallery] shortcode
* parent_type 'post' or 'page' or the custom post type of the attachment's parent
* parent_status 'publish', 'private', 'future', 'pending', 'draft'
* parent_title post_title of the attachment's parent
* parent_errors UNATTACHED, ORPHAN, BAD/INVALID PARENT
*/
$references = array(
'inserted_option' => '',
'tested_reference' => false,
'found_reference' => false,
'found_parent' => false,
'is_unattached' => ( ( (int) $parent ) === 0 ),
'base_file' => '',
'path' => '',
'file' => '',
'files' => array(),
'features' => array(),
'inserts' => array(),
'mla_galleries' => array(),
'galleries' => array(),
'parent_type' => '',
'parent_status' => '',
'parent_title' => '',
'parent_errors' => ''
);
if ( ! $add_references ) {
return $references;
}
// Fill in Parent data
$parent_data = MLAQuery::mla_fetch_attachment_parent_data( $parent );
if ( isset( $parent_data['parent_type'] ) ) {
$references['parent_type'] = $parent_data['parent_type'];
}
if ( isset( $parent_data['parent_status'] ) ) {
$references['parent_status'] = $parent_data['parent_status'];
}
if ( isset( $parent_data['parent_title'] ) ) {
$references['parent_title'] = $parent_data['parent_title'];
}
$references['base_file'] = get_post_meta( $ID, '_wp_attached_file', true );
$pathinfo = pathinfo($references['base_file']);
$references['file'] = $pathinfo['basename'];
if ( ( ! isset( $pathinfo['dirname'] ) ) || '.' == $pathinfo['dirname'] ) {
$references['path'] = '/';
} else {
$references['path'] = $pathinfo['dirname'] . '/';
}
$attachment_metadata = get_post_meta( $ID, '_wp_attachment_metadata', true );
$sizes = isset( $attachment_metadata['sizes'] ) ? $attachment_metadata['sizes'] : NULL;
if ( is_array( $sizes ) ) {
// Using the name as the array key ensures each name is added only once
foreach ( $sizes as $size => $size_info ) {
$size_info['size'] = $size;
$references['files'][ $references['path'] . $size_info['file'] ] = $size_info;
}
}
$base_type = wp_check_filetype( $references['file'] );
$base_reference = array(
'file' => $references['file'],
'width' => isset( $attachment_metadata['width'] ) ? $attachment_metadata['width'] : 0,
'height' => isset( $attachment_metadata['height'] ) ? $attachment_metadata['height'] : 0,
'mime_type' => isset( $base_type['type'] ) ? $base_type['type'] : 'unknown',
'size' => 'full',
);
$references['files'][ $references['base_file'] ] = $base_reference;
// Process the where-used settings option
if ('checked' == MLACore::mla_get_option( MLACoreOptions::MLA_EXCLUDE_REVISIONS ) ) {
$exclude_revisions = "(post_type <> 'revision') AND ";
} else {
$exclude_revisions = '';
}
// Accumulate reference test types, e.g., 0 = no tests, 4 = all tests
$reference_tests = 0;
// Look for the "Featured Image(s)", if enabled
if ( MLACore::$process_featured_in ) {
$reference_tests++;
$features = $wpdb->get_results(
"
SELECT post_id
FROM {$wpdb->postmeta}
WHERE meta_key = '_thumbnail_id' AND meta_value = {$ID}
"
);
if ( ! empty( $features ) ) {
foreach ( $features as $feature ) {
$feature_results = $wpdb->get_results(
"
SELECT ID, post_type, post_status, post_title
FROM {$wpdb->posts}
WHERE {$exclude_revisions}(ID = {$feature->post_id})
"
);
if ( ! empty( $feature_results ) ) {
$references['found_reference'] = true;
$references['features'][ $feature->post_id ] = $feature_results[0];
if ( $feature->post_id == $parent ) {
$references['found_parent'] = true;
}
} // ! empty
} // foreach $feature
}
} // $process_featured_in
// Look for item(s) inserted in post_content
$references['inserted_option'] = $inserted_in_option;
if ( MLACore::$process_inserted_in ) {
$reference_tests++;
if ( NULL == $inserted_in_option ) {
$inserted_in_option = MLACore::mla_get_option( MLACoreOptions::MLA_INSERTED_IN_TUNING );
$references['inserted_option'] = $inserted_in_option;
}
if ( 'base' == $inserted_in_option ) {
$query_parameters = array();
$query = array();
$query[] = "SELECT ID, post_type, post_status, post_title, CONVERT(`post_content` USING utf8 ) AS POST_CONTENT FROM {$wpdb->posts} WHERE {$exclude_revisions} ( %s=%s";
$query_parameters[] = '1'; // for empty file name array
$query_parameters[] = '0'; // for empty file name array
foreach ( $references['files'] as $file => $file_data ) {
if ( empty( $file ) ) {
continue;
}
$query[] = 'OR ( POST_CONTENT LIKE %s)';
if ( MLAQuery::$wp_4dot0_plus ) {
$query_parameters[] = '%' . $wpdb->esc_like( $file ) . '%';
} else {
$query_parameters[] = '%' . like_escape( $file ) . '%';
}
}
$query[] = ')';
$query = join(' ', $query);
MLACore::mla_debug_add( __LINE__ . " MLAReferences::mla_fetch_attachment_references_handler( {$ID}, {$parent}, {$add_references} ) inserts base query = " . var_export( $query, true ), MLACore::MLA_DEBUG_CATEGORY_WHERE_USED );
MLACore::mla_debug_add( __LINE__ . " MLAReferences::mla_fetch_attachment_references_handler( {$ID}, {$parent}, {$add_references} ) inserts base parms = " . var_export( $query_parameters, true ), MLACore::MLA_DEBUG_CATEGORY_WHERE_USED );
$inserts = $wpdb->get_results(
$wpdb->prepare( $query, $query_parameters )
);
if ( ! empty( $inserts ) ) {
$references['found_reference'] = true;
$references['inserts'][ $pathinfo['filename'] ] = $inserts;
foreach ( $inserts as $index => $insert ) {
unset( $references['inserts'][ $pathinfo['filename'] ][ $index ]->POST_CONTENT );
if ( $insert->ID == $parent ) {
$references['found_parent'] = true;
}
} // foreach $insert
} // ! empty
} else { // process base names
foreach ( $references['files'] as $file => $file_data ) {
if ( empty( $file ) ) {
continue;
}
if ( MLAQuery::$wp_4dot0_plus ) {
$like = $wpdb->esc_like( $file );
} else {
$like = like_escape( $file );
}
MLACore::mla_debug_add( __LINE__ . " MLAReferences::mla_fetch_attachment_references_handler( {$ID}, {$file}, {$like} ) inserts enabled", MLACore::MLA_DEBUG_CATEGORY_WHERE_USED );
$inserts = $wpdb->get_results(
$wpdb->prepare(
"SELECT ID, post_type, post_status, post_title FROM {$wpdb->posts}
WHERE {$exclude_revisions}(CONVERT(`post_content` USING utf8 ) LIKE %s)", "%{$like}%"
)
);
if ( ! empty( $inserts ) ) {
$references['found_reference'] = true;
$references['inserts'][ $file_data['file'] ] = $inserts;
foreach ( $inserts as $insert ) {
if ( $insert->ID == $parent ) {
$references['found_parent'] = true;
}
} // foreach $insert
} // ! empty
} // foreach $file
} // process intermediate sizes
} // $process_inserted_in
// Look for [mla_gallery] references
if ( MLACore::$process_mla_gallery_in ) {
$reference_tests++;
if ( self::_build_mla_galleries( MLACoreOptions::MLA_MLA_GALLERY_IN_TUNING, self::$mla_galleries, '[mla_gallery', $exclude_revisions ) ) {
$galleries = self::_search_mla_galleries( self::$mla_galleries, $ID );
if ( ! empty( $galleries ) ) {
$references['found_reference'] = true;
$references['mla_galleries'] = $galleries;
foreach ( $galleries as $post_id => $gallery ) {
if ( $post_id == $parent ) {
$references['found_parent'] = true;
}
} // foreach $gallery
} else { // ! empty
$references['mla_galleries'] = array();
}
}
} // $process_mla_gallery_in
// Look for [gallery] references
if ( MLACore::$process_gallery_in ) {
$reference_tests++;
if ( self::_build_mla_galleries( MLACoreOptions::MLA_GALLERY_IN_TUNING, self::$galleries, '[gallery', $exclude_revisions ) ) {
$galleries = self::_search_mla_galleries( self::$galleries, $ID );
if ( ! empty( $galleries ) ) {
$references['found_reference'] = true;
$references['galleries'] = $galleries;
foreach ( $galleries as $post_id => $gallery ) {
if ( $post_id == $parent ) {
$references['found_parent'] = true;
}
} // foreach $gallery
} else { // ! empty
$references['galleries'] = array();
}
}
} // $process_gallery_in
// Evaluate and summarize reference tests
$errors = '';
if ( 0 == $reference_tests ) {
$references['tested_reference'] = false;
$errors .= '(' . __( 'NO REFERENCE TESTS', 'media-library-assistant' ) . ')';
} else {
$references['tested_reference'] = true;
$suffix = ( 4 == $reference_tests ) ? '' : '?';
if ( !$references['found_reference'] ) {
$errors .= '(' . sprintf( __( 'ORPHAN', 'media-library-assistant' ) . '%1$s) ', $suffix );
}
if ( !$references['found_parent'] && ! empty( $references['parent_title'] ) ) {
$errors .= '(' . sprintf( __( 'UNUSED', 'media-library-assistant' ) . '%1$s) ', $suffix );
}
}
if ( $references['is_unattached'] ) {
$errors .= '(' . __( 'UNATTACHED', 'media-library-assistant' ) . ')';
} elseif ( empty( $references['parent_title'] ) ) {
$errors .= '(' . __( 'INVALID PARENT', 'media-library-assistant' ) . ')';
}
$references['parent_errors'] = trim( $errors );
$save_id = $ID;
$references = apply_filters( 'mla_fetch_attachment_references', $references, $ID, $parent );
MLACore::mla_debug_add( __LINE__ . " MLAReferences::mla_fetch_attachment_references_handler( {$ID}, {$parent}, {$add_references} ) references = " . var_export( $references, true ), MLACore::MLA_DEBUG_CATEGORY_WHERE_USED );
return $references;
}
/**
* Add Featured Image and inserted image/link references to an array of attachments
*
* Called from MLAQuery::mla_fetch_attachment_references, which handles conditional
* loading of this file.
*
* @since 1.94
*
* @param array WP_Post objects, passed by reference
*
* @return void updates WP_Post objects with new mla_references property
*/
public static function mla_attachment_array_fetch_references_handler( &$attachments ) {
global $wpdb;
/*
* See element definitions above
*/
$initial_references = array(
'inserted_option' => '',
'tested_reference' => false,
'found_reference' => false,
'found_parent' => false,
'is_unattached' => true,
'base_file' => '',
'path' => '',
'file' => '',
'files' => array(),
'features' => array(),
'inserts' => array(),
'mla_galleries' => array(),
'galleries' => array(),
'parent_type' => '',
'parent_status' => '',
'parent_title' => '',
'parent_errors' => ''
);
$inserted_in_option = MLACore::mla_get_option( MLACoreOptions::MLA_INSERTED_IN_TUNING );
$initial_references['inserted_option'] = $inserted_in_option;
/*
* Make sure there's work to do; otherwise initialize the attachment data and return
*/
if ( false == ( MLACore::$process_featured_in || MLACore::$process_inserted_in || MLACore::$process_gallery_in || MLACore::$process_mla_gallery_in ) ) {
foreach ( $attachments as $attachment_index => $attachment ) {
$attachments[ $attachment_index ]->mla_references = $initial_references;
}
return;
}
/*
* Collect the raw data for where-used analysis
*/
$attachment_ids = array();
$files = array();
foreach ( $attachments as $index => $attachment ) {
$attachment_ids[ $index ] = $attachment->ID;
$references = array( 'files' => array() );
if ( isset( $attachment->mla_wp_attached_file ) ) {
$references['base_file'] = $attachment->mla_wp_attached_file;
} else {
$references['base_file'] = '';
}
$pathinfo = pathinfo($references['base_file']);
if ( ( ! isset( $pathinfo['dirname'] ) ) || '.' == $pathinfo['dirname'] ) {
$references['path'] = '/';
} else {
$references['path'] = $pathinfo['dirname'] . '/';
}
$references['file'] = $pathinfo['basename'];
if ( isset( $attachment->mla_wp_attachment_metadata ) ) {
$attachment_metadata = $attachment->mla_wp_attachment_metadata;
} else {
$attachment_metadata = '';
}
$sizes = isset( $attachment_metadata['sizes'] ) ? $attachment_metadata['sizes'] : NULL;
if ( ! empty( $sizes ) && is_array( $sizes ) ) {
/* Using the path and name as the array key ensures each name is added only once */
foreach ( $sizes as $size => $size_info ) {
$size_info['size'] = $size;
$references['files'][ $references['path'] . $size_info['file'] ] = $size_info;
}
}
if ( ! empty( $references['base_file'] ) ) {
$base_type = wp_check_filetype( $references['file'] );
$base_reference = array(
'file' => $references['file'],
'width' => isset( $attachment_metadata['width'] ) ? $attachment_metadata['width'] : 0,
'height' => isset( $attachment_metadata['height'] ) ? $attachment_metadata['height'] : 0,
'mime_type' => ( isset( $base_type['type'] ) && false !== $base_type['type'] ) ? $base_type['type'] : 'unknown',
'size' => 'full',
);
$references['files'][ $references['base_file'] ] = $base_reference;
}
$files[ $index ] = $references;
}
if ('checked' == MLACore::mla_get_option( MLACoreOptions::MLA_EXCLUDE_REVISIONS ) ) {
$exclude_revisions = " AND (p.post_type <> 'revision')";
} else {
$exclude_revisions = '';
}
$features = array();
if ( MLACore::$process_featured_in && ! empty( $attachment_ids ) ) {
$attachment_ids = implode( ',', $attachment_ids );
$results = $wpdb->get_results(
"
SELECT m.meta_value, p.ID, p.post_type, p.post_status, p.post_title
FROM {$wpdb->postmeta} AS m INNER JOIN {$wpdb->posts} AS p ON m.post_id = p.ID
WHERE ( m.meta_key = '_thumbnail_id' )
AND ( m.meta_value IN ( {$attachment_ids} ) ){$exclude_revisions}
"
);
foreach ( $results as $result ) {
$features[ $result->meta_value ][ $result->ID ] = (object) array( 'ID' => $result->ID, 'post_title' => $result->post_title, 'post_type' => $result->post_type, 'post_status' => $result->post_status );
}
} // $process_featured_in
if ( ! empty( $exclude_revisions ) ) {
$exclude_revisions = " AND (post_type <> 'revision')";
}
if ( MLACore::$process_inserted_in ) {
$query_parameters = array();
$query = array();
$query[] = "SELECT ID, post_type, post_status, post_title, CONVERT(`post_content` USING utf8 ) AS POST_CONTENT FROM {$wpdb->posts} WHERE ( %s=%s";
// for empty file name array
$query_parameters[] = '1';
$query_parameters[] = '0';
foreach ( $files as $file ) {
foreach ( $file['files'] as $base_name => $file_data ) {
$query[] = 'OR ( POST_CONTENT LIKE %s)';
if ( MLAQuery::$wp_4dot0_plus ) {
$query_parameters[] = '%' . $wpdb->esc_like( $base_name ) . '%';
} else {
$query_parameters[] = '%' . like_escape( $base_name ) . '%';
}
}
}
$query[] = "){$exclude_revisions}";
$query = join(' ', $query);
$results = $wpdb->get_results(
$wpdb->prepare( $query, $query_parameters )
);
/*
* Match each post with inserts back to the attachments
*/
$inserts = array();
if ( ! empty( $results ) ) {
foreach ( $files as $index => $file ) {
foreach ( $file['files'] as $base_name => $file_data ) {
foreach ( $results as $result ) {
if ( false !== strpos( $result->POST_CONTENT, $base_name ) ) {
$insert = clone $result;
unset( $insert->POST_CONTENT);
$insert->file_name = $file_data['file'];
$inserts[ $index ][] = $insert;
}
} // foreach post with inserts
} // foreach base_name
} // foreach attachment
} // results
} // process_inserted_in
if ( MLACore::$process_mla_gallery_in ) {
$have_mla_galleries = self::_build_mla_galleries( MLACoreOptions::MLA_MLA_GALLERY_IN_TUNING, self::$mla_galleries, '[mla_gallery', $exclude_revisions );
} else {
$have_mla_galleries = false;
}
if ( MLACore::$process_gallery_in ) {
$have_galleries = self::_build_mla_galleries( MLACoreOptions::MLA_GALLERY_IN_TUNING, self::$galleries, '[gallery', $exclude_revisions );
} else {
$have_mla_galleries = false;
}
foreach ( $attachments as $attachment_index => $attachment ) {
$references = array_merge( $initial_references, $files[ $attachment_index ] );
/*
* Fill in Parent data
*/
if ( ( (int) $attachment->post_parent ) === 0 ) {
$references['is_unattached'] = true;
} else {
$references['is_unattached'] = false;
if ( isset( $attachment->parent_type ) ) {
$references['parent_type'] = $attachment->parent_type;
}
if ( isset( $attachment->parent_status ) ) {
$references['parent_status'] = $attachment->parent_status;
}
if ( isset( $attachment->parent_title ) ) {
$references['parent_title'] = $attachment->parent_title;
}
}
/*
* Accumulate reference test types, e.g., 0 = no tests, 4 = all tests
*/
$reference_tests = 0;
/*
* Look for the "Featured Image(s)", if enabled
*/
if ( MLACore::$process_featured_in ) {
$reference_tests++;
if ( isset( $features[ $attachment->ID ] ) ) {
foreach ( $features[ $attachment->ID ] as $id => $feature ) {
$references['found_reference'] = true;
$references['features'][ $id ] = $feature;
if ( $id == $attachment->post_parent ) {
$references['found_parent'] = true;
}
} // foreach $feature
}
} // $process_featured_in
/*
* Look for item(s) inserted in post_content
*/
if ( MLACore::$process_inserted_in ) {
$reference_tests++;
if ( isset( $inserts[ $attachment_index ] ) ) {
$references['found_reference'] = true;
foreach( $inserts[ $attachment_index ] as $insert ) {
$ref_insert = clone $insert;
unset( $ref_insert->file_name );
if ( 'base' == $inserted_in_option ) {
$ref_key = pathinfo( $references['base_file'], PATHINFO_FILENAME );
} else {
$ref_key = $insert->file_name;
}
$references['inserts'][ $ref_key ][ $insert->ID ] = $ref_insert;
if ( $insert->ID == $attachment->post_parent ) {
$references['found_parent'] = true;
}
} // each insert
} else {
$references['inserts'] = array();
}
} // $process_inserted_in
/*
* Look for [mla_gallery] references
*/
if ( MLACore::$process_mla_gallery_in ) {
$reference_tests++;
if ( self::_build_mla_galleries( MLACoreOptions::MLA_MLA_GALLERY_IN_TUNING, self::$mla_galleries, '[mla_gallery', $exclude_revisions ) ) {
$galleries = self::_search_mla_galleries( self::$mla_galleries, $attachment->ID );
if ( ! empty( $galleries ) ) {
$references['found_reference'] = true;
$references['mla_galleries'] = $galleries;
foreach ( $galleries as $post_id => $gallery ) {
if ( $post_id == $attachment->post_parent ) {
$references['found_parent'] = true;
}
} // foreach $gallery
} else { // ! empty
$references['mla_galleries'] = array();
}
}
} // $process_mla_gallery_in
/*
* Look for [gallery] references
*/
if ( MLACore::$process_gallery_in ) {
$reference_tests++;
if ( self::_build_mla_galleries( MLACoreOptions::MLA_GALLERY_IN_TUNING, self::$galleries, '[gallery', $exclude_revisions ) ) {
$galleries = self::_search_mla_galleries( self::$galleries, $attachment->ID );
if ( ! empty( $galleries ) ) {
$references['found_reference'] = true;
$references['galleries'] = $galleries;
foreach ( $galleries as $post_id => $gallery ) {
if ( $post_id == $attachment->post_parent ) {
$references['found_parent'] = true;
}
} // foreach $gallery
} else { // ! empty
$references['galleries'] = array();
}
}
} // $process_gallery_in
/*
* Evaluate and summarize reference tests
*/
$errors = '';
if ( 0 == $reference_tests ) {
$references['tested_reference'] = false;
$errors .= '(' . __( 'NO REFERENCE TESTS', 'media-library-assistant' ) . ')';
} else {
$references['tested_reference'] = true;
$suffix = ( 4 == $reference_tests ) ? '' : '?';
if ( !$references['found_reference'] ) {
$errors .= '(' . sprintf( __( 'ORPHAN', 'media-library-assistant' ) . '%1$s) ', $suffix );
}
if ( !$references['found_parent'] && ! empty( $references['parent_title'] ) ) {
$errors .= '(' . sprintf( __( 'UNUSED', 'media-library-assistant' ) . '%1$s) ', $suffix );
}
}
if ( $references['is_unattached'] ) {
$errors .= '(' . __( 'UNATTACHED', 'media-library-assistant' ) . ')';
} elseif ( empty( $references['parent_title'] ) ) {
$errors .= '(' . __( 'INVALID PARENT', 'media-library-assistant' ) . ')';
}
$references['parent_errors'] = trim( $errors );
$attachments[ $attachment_index ]->mla_references = apply_filters( 'mla_fetch_attachment_references', $references, $attachment->ID, (int) $attachment->post_parent );
} // foreach $attachment
}
/**
* Objects containing [gallery] shortcodes
*
* This array contains all of the objects containing one or more [gallery] shortcodes
* and array(s) of which attachments each [gallery] contains. The arrays are built once
* each page load and cached for subsequent calls.
*
* The outer array is keyed by post_id. It contains an associative array with:
* ['parent_title'] post_title of the gallery parent,
* ['parent_type'] 'post' or 'page' or the custom post_type of the gallery parent,
* ['parent_status'] 'publish', 'private', 'future', 'pending', 'draft'
* ['results'] array ( ID => ID ) of attachments appearing in ANY of the parent's galleries.
* ['galleries'] array of [gallery] entries numbered from one (1), containing:
* galleries[X]['query'] contains a string with the arguments of the [gallery],
* galleries[X]['results'] contains an array ( ID ) of post_ids for the objects in the gallery.
*
* @since 0.70
*
* @var array
*/
private static $galleries = NULL;
/**
* Objects containing [mla_gallery] shortcodes
*
* This array contains all of the objects containing one or more [mla_gallery] shortcodes
* and array(s) of which attachments each [mla_gallery] contains. The arrays are built once
* each page load and cached for subsequent calls.
*
* @since 0.70
*
* @var array
*/
private static $mla_galleries = NULL;
/**
* Invalidates the $mla_galleries or $galleries array and cached values
*
* Called from MLAQuery::mla_flush_mla_galleries, which handles conditional
* loading of this file.
*
* @since 1.00
*
* @param string name of the gallery's cache/option variable
*
* @return void
*/
public static function mla_flush_mla_galleries_handler( $option_name ) {
switch ( $option_name ) {
case MLACoreOptions::MLA_GALLERY_IN_TUNING:
self::$galleries = NULL;
break;
case MLACoreOptions::MLA_MLA_GALLERY_IN_TUNING:
self::$mla_galleries = NULL;
break;
default:
// ignore everything else
} // switch
}
/**
* Builds the $mla_galleries or $galleries array
*
* @since 0.70
*
* @param string name of the gallery's cache/option variable
* @param array by reference to the private static galleries array variable
* @param string the shortcode to be searched for and processed
* @param boolean true to exclude revisions from the search
*
* @return boolean true if the galleries array is not empty
*/
private static function _build_mla_galleries( $option_name, &$galleries_array, $shortcode, $exclude_revisions ) {
global $wpdb, $post;
if ( is_array( $galleries_array ) ) {
if ( ! empty( $galleries_array ) ) {
return true;
} else {
return false;
}
}
$option_value = MLACore::mla_get_option( $option_name );
if ( 'disabled' == $option_value ) {
return false;
} elseif ( 'cached' == $option_value ) {
$galleries_array = get_transient( MLA_OPTION_PREFIX . 't_' . $option_name );
if ( is_array( $galleries_array ) ) {
if ( ! empty( $galleries_array ) ) {
return true;
} else {
return false;
}
} else {
$galleries_array = NULL;
}
} // cached
/*
* The MLAShortcodes class is only loaded when needed.
*/
if ( !class_exists( 'MLAShortcodes' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
}
/*
* $galleries_array is null, so build the array
*/
$galleries_array = array();
if ( $exclude_revisions ) {
$exclude_revisions = "(post_type <> 'revision') AND ";
} else {
$exclude_revisions = '';
}
if ( MLAQuery::$wp_4dot0_plus ) {
$like = $wpdb->esc_like( $shortcode );
} else {
$like = like_escape( $shortcode );
}
$results = $wpdb->get_results(
$wpdb->prepare(
"
SELECT ID, post_type, post_status, post_title, post_content
FROM {$wpdb->posts}
WHERE {$exclude_revisions}(
CONVERT(`post_content` USING utf8 )
LIKE %s)
", "%{$like}%"
)
);
if ( empty( $results ) ) {
return false;
}
foreach ( $results as $result ) {
$count = preg_match_all( "/\\{$shortcode}([^\\]]*)\\]/", $result->post_content, $matches, PREG_PATTERN_ORDER );
if ( $count ) {
$result_id = $result->ID;
$galleries_array[ $result_id ]['parent_title'] = $result->post_title;
$galleries_array[ $result_id ]['parent_type'] = $result->post_type;
$galleries_array[ $result_id ]['parent_status'] = $result->post_status;
$galleries_array[ $result_id ]['results'] = array();
$galleries_array[ $result_id ]['galleries'] = array();
$instance = 0;
foreach ( $matches[1] as $index => $match ) {
/*
* Filter out shortcodes that are not an exact match
*/
if ( empty( $match ) || ( ' ' == substr( $match, 0, 1 ) ) ) {
$instance++;
/*
* Remove trailing "/" from XHTML-style self-closing shortcodes
*/
$galleries_array[ $result_id ]['galleries'][ $instance ]['query'] = trim( rtrim( $matches[1][$index], '/' ) );
$galleries_array[ $result_id ]['galleries'][ $instance ]['results'] = array();
$post = $result; // set global variable for mla_gallery_shortcode
$attachments = MLAShortcodes::mla_get_shortcode_attachments( $result_id, $galleries_array[ $result_id ]['galleries'][ $instance ]['query'] . ' cache_results=false update_post_meta_cache=false update_post_term_cache=false where_used_query=this-is-a-where-used-query' );
if ( is_string( $attachments ) ) {
/* translators: 1: post_type, 2: post_title, 3: post ID, 4: query string, 5: error message */
trigger_error( htmlentities( sprintf( __( '(%1$s) %2$s (ID %3$d) query "%4$s" failed, returning "%5$s"', 'media-library-assistant' ), $result->post_type, $result->post_title, $result->ID, $galleries_array[ $result_id ]['galleries'][ $instance ]['query'], $attachments) ), E_USER_WARNING );
} elseif ( ! empty( $attachments ) ) {
foreach ( $attachments as $attachment ) {
$galleries_array[ $result_id ]['results'][ $attachment->ID ] = $attachment->ID;
$galleries_array[ $result_id ]['galleries'][ $instance ]['results'][] = $attachment->ID;
}
}
} // exact match
} // foreach $match
} // if $count
} // foreach $result
/*
* Maybe cache the results
*/
if ( 'cached' == $option_value ) {
set_transient( MLA_OPTION_PREFIX . 't_' . $option_name, $galleries_array, 900 ); // fifteen minutes
}
return true;
}
/**
* Search the $mla_galleries or $galleries array
*
* @since 0.70
*
* @param array by reference to the private static galleries array variable
* @param int the attachment ID to be searched for and processed
*
* @return array All posts/pages with one or more galleries that include the attachment.
* The array key is the parent_post ID; each entry contains post_title and post_type.
*/
private static function _search_mla_galleries( &$galleries_array, $attachment_id ) {
$gallery_refs = array();
if ( ! empty( $galleries_array ) ) {
foreach ( $galleries_array as $parent_id => $gallery ) {
if ( in_array( $attachment_id, $gallery['results'] ) ) {
$gallery_refs[ $parent_id ] = array ( 'ID' => $parent_id, 'post_title' => $gallery['parent_title'], 'post_type' => $gallery['parent_type'], 'post_status' => $gallery['parent_status'] );
}
} // foreach gallery
} // ! empty
return $gallery_refs;
}
} // class MLAReferences
?>

View File

@@ -0,0 +1,833 @@
<?php
/**
* Manages access to data sources for custom field mapping and shortcode execution
*
* @package Media Library Assistant
* @since 2.20
*/
/**
* Class MLA (Media Library Assistant) Data Source manages data sources for
* custom field mapping and shortcode execution
*
* @package Media Library Assistant
* @since 2.20
*/
class MLAData_Source {
/**
* Array of Data Source names for custom field mapping
*
* @since 2.20
*
* @var array
*/
public static $custom_field_data_sources = array (
'post_id',
'post_author',
'post_date',
'post_date_gmt',
'post_content',
'post_title',
'post_excerpt',
'post_status',
'comment_status',
'ping_status',
'post_name',
'post_modified',
'post_modified_gmt',
'post_content_filtered',
'parent',
'post_parent',
'guid',
'menu_order',
'mime_type',
'post_mime_type',
'comment_count',
'alt_text',
'absolute_path',
'absolute_file_name',
'base_file',
'path',
'file_name',
'name_only',
'extension',
'file_size',
'upload_date',
'dimensions',
'pixels',
'width',
'height',
'orientation',
'hwstring_small',
'size_keys',
'size_names',
'size_bytes',
'size_pixels',
'size_dimensions',
'size_name[size]',
'size_bytes[size]',
'size_pixels[size]',
'size_dimensions[size]',
'parent_date',
'parent_type',
'parent_title',
'parent_issues',
'reference_issues',
'featured_in',
'featured_in_title',
'inserted_in',
'inserted_in_title',
'gallery_in',
'gallery_in_title',
'mla_gallery_in',
'mla_gallery_in_title',
'aperture',
'credit',
'camera',
'caption',
'created_timestamp',
'copyright',
'focal_length',
'iso',
'shutter_speed',
'title'
);
/**
* Identify custom field mapping data source
*
* Determines whether a name matches any of the element-level data source dropdown options, i.e.,
* excludes "template:" and "meta:" values.
*
* @since 2.20
*
* @param string candidate data source name
*
* @return boolean true if candidate name matches a data source
*/
public static function mla_is_data_source( $candidate_name ) {
static $intermediate_sizes = NULL;
/*
* The [size] elements are expanded with available image sizes;
* convert valid sizes back to the generic [size] value to match the list.
*/
$match_count = preg_match( '/(.+)\[(.+)\]/', $candidate_name, $matches );
if ( 1 == $match_count ) {
if ( NULL === $intermediate_sizes ) {
$intermediate_sizes = get_intermediate_image_sizes();
}
if ( in_array( $matches[2], $intermediate_sizes ) ) {
$candidate_name = $matches[1] . '[size]';
} else {
return false;
}
}
return in_array( $candidate_name, MLAData_Source::$custom_field_data_sources );
} // mla_is_data_source
/**
* Get IPTC/EXIF or custom field mapping data source
*
* Defined as public so MLA Mapping Hooks clients can call it.
* Isolates clients from changes to _evaluate_data_source().
*
* @since 2.20
*
* @param integer post->ID of attachment
* @param string category/scope to evaluate against: custom_field_mapping or single_attachment_mapping
* @param array data source specification ( name, *data_source, *keep_existing, *format, mla_column, quick_edit, bulk_edit, *meta_name, *option, no_null )
* @param array (optional) _wp_attachment_metadata, default NULL (use current postmeta database value)
*
* @return string|array data source value
*/
public static function mla_get_data_source( $post_id, $category, $data_value, $attachment_metadata = NULL ) {
if ( !class_exists( 'MLAQuery' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
MLAQuery::initialize();
}
if ( !class_exists( 'MLAData' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
MLAData::initialize();
}
$default_arguments = array(
'data_source' => 'none',
'keep_existing' => true,
'format' => 'native',
'meta_name' => '',
'option' => 'text',
);
$data_value = shortcode_atts( $default_arguments, $data_value );
return MLAData_Source::_evaluate_data_source( $post_id, $category, $data_value, $attachment_metadata );
} // mla_get_data_source
/**
* Evaluate file information for custom field mapping
*
* @since 2.20
*
* @param string absolute path the the uploads base directory
* @param array _wp_attached_file meta_value array, indexed by post_id
* @param array _wp_attachment_metadata meta_value array, indexed by post_id
* @param integer post->ID of attachment
*
* @return array absolute_path_raw, absolute_path, absolute_file_name_raw, absolute_file_name, absolute_file, base_file, path, file_name, extension, dimensions, width, height, hwstring_small, array of intermediate sizes
*/
private static function _evaluate_file_information( $upload_dir, &$wp_attached_files, &$wp_attachment_metadata, $post_id ) {
$results = array(
'absolute_path_raw' => '',
'absolute_path' => '',
'absolute_file_name_raw' => '',
'absolute_file_name' => '',
'base_file' => '',
'path' => '',
'file_name' => '',
'name_only' => '',
'extension' => '',
'width' => '',
'height' => '',
'orientation' => '',
'hwstring_small' => '',
'sizes' => array()
);
$base_file = isset( $wp_attached_files[ $post_id ]->meta_value ) ? $wp_attached_files[ $post_id ]->meta_value : '';
$sizes = array();
if ( isset( $wp_attachment_metadata[ $post_id ]->meta_value ) ) {
$attachment_metadata = @unserialize( $wp_attachment_metadata[ $post_id ]->meta_value );
if ( ! is_array( $attachment_metadata ) ) {
$attachment_metadata = array();
}
} else {
$attachment_metadata = array();
}
if ( !empty( $attachment_metadata ) ) {
if ( isset( $attachment_metadata['image_meta'] ) ) {
foreach ( $attachment_metadata['image_meta'] as $key => $value )
$results[ $key ] = $value;
}
$sizes = isset( $attachment_metadata['sizes'] ) ? $attachment_metadata['sizes'] : array();
if ( isset( $attachment_metadata['width'] ) ) {
$results['width'] = $attachment_metadata['width'];
$width = absint( $results['width'] );
} else {
$width = 0;
}
if ( isset( $attachment_metadata['height'] ) ) {
$results['height'] = $attachment_metadata['height'];
$height = absint( $results['height'] );
} else {
$height = 0;
}
if ( $width && $height ) {
$results['orientation'] = ( $height > $width ) ? 'portrait' : 'landscape';
}
$results['hwstring_small'] = isset( $attachment_metadata['hwstring_small'] ) ? $attachment_metadata['hwstring_small'] : '';
}
if ( ! empty( $base_file ) ) {
$pathinfo = pathinfo( $base_file );
$results['base_file'] = $base_file;
if ( '.' == $pathinfo['dirname'] ) {
$results['absolute_path_raw'] = $upload_dir;
$results['absolute_path'] = wptexturize( str_replace( '\\', '/', $upload_dir ) );
$results['path'] = '';
} else {
$results['absolute_path_raw'] = $upload_dir . $pathinfo['dirname'] . '/';
$results['absolute_path'] = wptexturize( str_replace( '\\', '/', $results['absolute_path_raw'] ) );
$results['path'] = wptexturize( $pathinfo['dirname'] . '/' );
}
$results['absolute_file_name_raw'] = $results['absolute_path_raw'] . $pathinfo['basename'];
$results['absolute_file_name'] = wptexturize( str_replace( '\\', '/', $results['absolute_file_name_raw'] ) );
$results['file_name'] = wptexturize( $pathinfo['basename'] );
$results['name_only'] = wptexturize( $pathinfo['filename'] );
$results['extension'] = wptexturize( $pathinfo['extension'] );
}
$results['sizes'] = $sizes;
return $results;
} // _evaluate_file_information
/**
* Evaluate post information for custom field mapping
*
* @since 2.20
*
* @param integer post->ID of attachment
* @param string category/scope to evaluate against: custom_field_mapping or single_attachment_mapping
* @param string data source name ( post_date or post_parent )
*
* @return mixed (string)/'' or (integer)/0 depending on $data_source type
*/
private static function _evaluate_post_information( $post_id, $category, $data_source ) {
global $wpdb;
static $post_info = NULL;
if ( 0 == $post_id ) {
$value = NULL;
} else {
/*
* Check for $post_id match
*/
if ( 'single_attachment_mapping' == $category && ! isset( $post_info[$post_id] ) ) {
$post_info = NULL;
}
if ( NULL == $post_info ) {
if ( 'custom_field_mapping' == $category ) {
$post_info = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE post_type = 'attachment'", OBJECT_K );
} else {
$post_info = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE ID = '{$post_id}'", OBJECT_K );
}
}
if ( 'post_id' == $data_source ) {
$data_source = 'ID';
}
if ( isset( $post_info[$post_id] ) && property_exists( $post_info[$post_id], $data_source ) ) {
$post_array = (array) $post_info[$post_id];
$value = $post_array[ $data_source ];
} else {
$value = NULL;
}
}
switch ( $data_source ) {
case 'ID':
case 'post_id':
case 'post_author':
case 'post_parent':
case 'menu_order':
case 'comment_count':
return ( NULL !== $value ) ? $value : 0;
default:
return ( NULL !== $value ) ? $value : '';
}
return false;
} // _evaluate_post_information
/**
* Evaluate post information for custom field mapping
*
* @since 2.20
*
* @param array field value(s)
* @param string format option text|single|export|array|multi
* @param boolean keep existing value(s) - for 'multi' option
*
* @return mixed array for option = array|multi else string
*/
private static function _evaluate_array_result( $value, $option, $keep_existing ) {
if ( empty( $value ) ) {
return '';
}
if ( is_array( $value ) ) {
if ( 'single' == $option || 1 == count( $value ) ) {
return current( $value );
} elseif ( 'export' == $option ) {
return var_export( $value, true );
} elseif ( 'text' == $option ) {
return implode( ',', $value );
} elseif ( 'multi' == $option ) {
$value[0x80000000] = $option;
$value[0x80000001] = $keep_existing;
return $value;
}
}
/*
* $option = array returns the array
*/
return $value;
} // _evaluate_array_result
/**
* Evaluate custom field mapping data source
*
* @since 2.20
*
* @param integer post->ID of attachment
* @param string category/scope to evaluate against: custom_field_mapping or single_attachment_mapping
* @param array data source specification ( name, *data_source, *keep_existing, *format, mla_column, quick_edit, bulk_edit, *meta_name, *option, no_null )
* @param array (optional) _wp_attachment_metadata, default NULL (use current postmeta database value)
*
* @return string|array data source value
*/
private static function _evaluate_data_source( $post_id, $category, $data_value, $attachment_metadata = NULL ) {
global $wpdb;
static $upload_dir, $intermediate_sizes = NULL, $wp_attached_files = NULL, $wp_attachment_metadata = NULL;
static $current_id = 0, $file_info = NULL, $parent_info = NULL, $references = NULL, $alt_text = NULL;
if ( 'none' == $data_value['data_source'] ) {
return '';
}
$data_source = $data_value['data_source'];
// Do this once per page load; cache attachment metadata if mapping all attachments
if ( NULL == $intermediate_sizes ) {
$upload_dir = wp_upload_dir();
$upload_dir = $upload_dir['basedir'] . '/';
$intermediate_sizes = get_intermediate_image_sizes();
if ( 'custom_field_mapping' == $category ) {
if ( ! $table = _get_meta_table('post') ) {
$wp_attached_files = array();
$wp_attachment_metadata = array();
} else {
$wp_attachment_metadata = $wpdb->get_results( "SELECT post_id, meta_value FROM {$table} WHERE meta_key = '_wp_attachment_metadata'", OBJECT_K );
$wp_attached_files = $wpdb->get_results( "SELECT post_id, meta_value FROM {$table} WHERE meta_key = '_wp_attached_file'", OBJECT_K );
}
} // custom_field_mapping, i.e., mapping all attachments
} // first call after page load
// Do this once per post. Simulate SQL results for $wp_attached_files and $wp_attachment_metadata.
if ( $current_id != $post_id ) {
$current_id = $post_id;
$parent_info = NULL;
$references = NULL;
$alt_text = NULL;
MLAData::mla_reset_regex_matches( $post_id );
if ( 'single_attachment_mapping' == $category ) {
$metadata = get_metadata( 'post', $post_id, '_wp_attached_file' );
if ( isset( $metadata[0] ) ) {
$wp_attached_files = array( $post_id => (object) array( 'post_id' => $post_id, 'meta_value' => $metadata[0] ) );
} else {
$wp_attached_files = array();
}
if ( NULL == $attachment_metadata ) {
$metadata = get_metadata( 'post', $post_id, '_wp_attachment_metadata' );
if ( isset( $metadata[0] ) ) {
$attachment_metadata = $metadata[0];
}
}
if ( empty( $attachment_metadata ) ) {
$attachment_metadata = array();
}
$wp_attachment_metadata = array( $post_id => (object) array( 'post_id' => $post_id, 'meta_value' => serialize( $attachment_metadata ) ) );
}
$file_info = MLAData_Source::_evaluate_file_information( $upload_dir, $wp_attached_files, $wp_attachment_metadata, $post_id );
}
$size_info = array( 'file' => '', 'width' => '', 'height' => '' );
$match_count = preg_match( '/(.+)\[(.+)\]/', $data_source, $matches );
if ( 1 == $match_count ) {
$data_source = $matches[1] . '[size]';
if ( isset( $file_info['sizes'][ $matches[2] ] ) ) {
$size_info = $file_info['sizes'][ $matches[2] ];
}
}
$result = '';
switch( $data_source ) {
case 'meta':
$attachment_metadata = isset( $wp_attachment_metadata[ $post_id ]->meta_value ) ? maybe_unserialize( $wp_attachment_metadata[ $post_id ]->meta_value ) : array();
$result = MLAData::mla_find_array_element( $data_value['meta_name'], $attachment_metadata, $data_value['option'], $data_value['keep_existing'] );
break;
case 'template':
if ( in_array( $data_value['option'], array ( 'single', 'export', 'array', 'multi' ) ) ) {
$default_option = 'array';
} else {
$default_option = 'text';
}
// Go through the template and expand the non-prefixed elements as Data Sources
$item_values = array();
$placeholders = MLAData::mla_get_template_placeholders( $data_value['meta_name'], $default_option );
foreach ( $placeholders as $key => $placeholder ) {
if ( empty( $placeholder['prefix'] ) ) {
$field_value = $data_value;
$field_value['data_source'] = $placeholder['value'];
$field_value['meta_name'] = '';
$field_value['option'] = $placeholder['option'];
$field_value['format'] = $placeholder['format'];
if ( isset( $placeholder['args'] ) ) {
$field_value['args'] = $placeholder['args'];
}
$field_value = MLAData_Source::_evaluate_data_source( $post_id, $category, $field_value, $attachment_metadata );
$item_values[ $key ] = MLAData::mla_apply_field_level_format( $field_value, $placeholder );
} // Data Source
} // foreach placeholder
// Now expand the template using the above Data Source values
$template = '[+template:' . $data_value['meta_name'] . '+]';
$item_values = MLAData::mla_expand_field_level_parameters( $template, NULL, $item_values, $post_id, $data_value['keep_existing'], $default_option, $attachment_metadata );
if ( 'array' == $default_option ) {
$result = MLAData::mla_parse_array_template( $template, $item_values );
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
} else {
$result = MLAData::mla_parse_template( $template, $item_values );
}
break;
case 'parent':
$data_source = 'post_parent';
/* fallthru */
case 'ID':
case 'post_id':
case 'post_author':
case 'post_parent':
case 'menu_order':
case 'comment_count':
$result = absint( MLAData_Source::_evaluate_post_information( $post_id, $category, $data_source ) );
break;
case 'alt_text':
if ( NULL == $alt_text ) {
$metadata = get_metadata( 'post', $post_id, '_wp_attachment_image_alt' );
if ( is_array( $metadata ) ) {
if ( count( $metadata ) == 1 ) {
$alt_text = maybe_unserialize( $metadata[0] );
} else {
$alt_text = array();
foreach ( $metadata as $single_key => $single_value ) {
$alt_text[ $single_key ] = maybe_unserialize( $single_value );
}
}
}
}
if ( ! empty( $alt_text ) ) {
$result = MLAData_Source::_evaluate_array_result( $alt_text, $data_value['option'], $data_value['keep_existing'] );
}
break;
case 'mime_type':
$data_source = 'post_mime_type';
/* fallthru */
case 'post_date':
case 'post_date_gmt':
case 'post_content':
case 'post_title':
case 'post_excerpt':
case 'post_status':
case 'comment_status':
case 'ping_status':
case 'post_name':
case 'post_modified':
case 'post_modified_gmt':
case 'post_content_filtered':
case 'guid':
case 'post_mime_type':
$result = MLAData_Source::_evaluate_post_information( $post_id, $category, $data_source );
break;
case 'absolute_path':
case 'absolute_file_name':
case 'base_file':
case 'path':
case 'file_name':
case 'name_only':
case 'extension':
case 'width':
case 'height':
case 'orientation':
case 'hwstring_small':
case 'aperture':
case 'credit':
case 'camera':
case 'caption':
case 'created_timestamp':
case 'copyright':
case 'focal_length':
case 'iso':
case 'shutter_speed':
case 'title':
if ( isset( $file_info[ $data_source ] ) ) {
$result = $file_info[ $data_source ];
}
break;
case 'file_size':
$filesize = @ filesize( $file_info['absolute_file_name_raw'] );
if ( ! (false === $filesize ) ) {
$result = $filesize;
}
break;
case 'upload_date':
$result = MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_date' );
break;
case 'dimensions':
$result = $file_info['width'] . 'x' . $file_info['height'];
if ( 'x' == $result ) {
$result = '';
}
break;
case 'pixels':
$result = absint( (int) $file_info['width'] * (int) $file_info['height'] );
if ( 0 == $result ) {
$result = '';
} else {
$result = (string) $result;
}
break;
case 'size_keys':
$result = array();
foreach ( $file_info['sizes'] as $key => $value )
$result[] = $key;
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
break;
case 'size_names':
$result = array();
foreach ( $file_info['sizes'] as $key => $value )
$result[] = $value['file'];
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
break;
case 'size_bytes':
$result = array();
foreach ( $file_info['sizes'] as $key => $value ) {
$filesize = @ filesize( $file_info['absolute_path_raw'] . $value['file'] );
if ( false === $filesize ) {
$result[] = '?';
} else {
switch( $data_value['format'] ) {
case 'commas':
if ( is_numeric( $filesize ) ) {
$filesize = number_format( (float)$filesize );
}
break;
default:
// no change
} // format
$result[] = $filesize;
}
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
break;
case 'size_pixels':
$result = array();
foreach ( $file_info['sizes'] as $key => $value ) {
$pixels = absint( (int) $value['width'] * (int) $value['height'] );
switch( $data_value['format'] ) {
case 'commas':
if ( is_numeric( $pixels ) ) {
$pixels = number_format( (float)$pixels );
}
break;
default:
// no change
} // format
$result[] = $pixels;
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
break;
case 'size_dimensions':
$result = array();
foreach ( $file_info['sizes'] as $key => $value ) {
$result[] = $value['width'] . 'x' . $value['height'];
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
break;
case 'size_name[size]':
$result = $size_info['file'];
break;
case 'size_bytes[size]':
$result = @ filesize( $file_info['absolute_path_raw'] . $size_info['file'] );
if ( false === $result ) {
$result = '?';
}
break;
case 'size_pixels[size]':
$result = absint( (int) $size_info['width'] * (int) $size_info['height'] );
break;
case 'size_dimensions[size]':
$result = $size_info['width'] . 'x' . $size_info['height'];
if ( 'x' == $result ) {
$result = '';
}
break;
case 'parent_date':
case 'parent_type':
case 'parent_title':
if ( is_null( $parent_info ) ) {
$parent_info = MLAQuery::mla_fetch_attachment_parent_data( MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( isset( $parent_info[ $data_source ] ) ) {
$result = $parent_info[ $data_source ];
}
break;
case 'parent_issues':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['parent_errors'] ) ) {
$result = $references['parent_errors'];
// Remove (ORPHAN...
$orphan_certain = '(' . __( 'ORPHAN', 'media-library-assistant' ) . ')';
$orphan_possible = '(' . __( 'ORPHAN', 'media-library-assistant' ) . '?)';
if ( false !== strpos( $result, $orphan_certain ) ) {
$result = trim( substr( $result, strlen( $orphan_certain ) ) );
} elseif ( false !== strpos( $result, $orphan_possible ) ) {
$result = trim( substr( $result, strlen( $orphan_possible ) ) );
}
}
break;
case 'reference_issues':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['parent_errors'] ) ) {
$result = $references['parent_errors'];
}
break;
case 'featured_in':
case 'featured_in_title':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['features'] ) ) {
$result = array();
foreach ( $references['features'] as $ID => $value )
if ( 'featured_in' == $data_source ) {
$result[] = sprintf( '%1$s (%2$s %3$d)', $value->post_title, $value->post_type, $ID );
} else {
$result[] = $value->post_title;
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
} else {
$result = '';
}
break;
case 'inserted_in':
case 'inserted_in_title':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['inserts'] ) ) {
$result = array();
foreach ( $references['inserts'] as $base_file => $inserts )
foreach ( $inserts as $value )
if ( 'inserted_in' == $data_source ) {
$result[] = sprintf( '%1$s (%2$s %3$d)', $value->post_title, $value->post_type, $value->ID );
} else {
$result[] = $value->post_title;
}
ksort( $result );
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
} else {
$result = '';
}
break;
case 'gallery_in':
case 'gallery_in_title':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['galleries'] ) ) {
$result = array();
foreach ( $references['galleries'] as $ID => $value )
if ( 'gallery_in' == $data_source ) {
$result[] = sprintf( '%1$s (%2$s %3$d)', $value['post_title'], $value['post_type'], $ID );
} else {
$result[] = $value['post_title'];
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
} else {
$result = '';
}
break;
case 'mla_gallery_in':
case 'mla_gallery_in_title':
if ( is_null( $references ) ) {
$references = MLAQuery::mla_fetch_attachment_references( $post_id, MLAData_Source::_evaluate_post_information( $post_id, $category, 'post_parent' ) );
}
if ( !empty( $references['mla_galleries'] ) ) {
$result = array();
foreach ( $references['mla_galleries'] as $ID => $value )
if ( 'mla_gallery_in' == $data_source ) {
$result[] = sprintf( '%1$s (%2$s %3$d)', $value['post_title'], $value['post_type'], $ID );
} else {
$result[] = $value['post_title'];
}
$result = MLAData_Source::_evaluate_array_result( $result, $data_value['option'], $data_value['keep_existing'] );
} else {
$result = '';
}
break;
case 'index':
if ( class_exists( 'MLA' ) && !empty( MLA::$bulk_edit_data_source['cb_index'] ) ) {
$result = MLA::$bulk_edit_data_source['cb_index'];
if ( !empty( $data_value['format'] ) ) {
$result += absint( $data_value['format'] );
}
}
break;
case 'found_rows':
if ( class_exists( 'MLA' ) && !empty( MLA::$bulk_edit_data_source['cb_count'] ) ) {
$result = MLA::$bulk_edit_data_source['cb_count'];
}
break;
default:
$custom_value = apply_filters( 'mla_evaluate_custom_data_source', NULL, $post_id, $category, $data_value, $attachment_metadata );
if ( !is_null( $custom_value ) ) {
return $custom_value;
}
return '';
} // switch $data_source
switch( $data_value['format'] ) {
case 'raw':
return $result;
case 'commas':
if ( is_numeric( $result ) ) {
$result = str_pad( number_format( (float)$result ), 15, ' ', STR_PAD_LEFT );
}
break;
case 'native':
default:
// Make some numeric values sortable as strings, make all value non-empty
if ( in_array( $data_source, array( 'file_size', 'pixels', 'width', 'height' ) ) ) {
$result = str_pad( $result, 15, ' ', STR_PAD_LEFT );
} elseif ( empty( $result ) ) {
$result = ' ';
}
} // format
return $result;
} // _evaluate_data_source
} // class MLAData_Source
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
<?php
/**
* File download support for [mla_gallery]
*
* @package Media Library Assistant
* @since 2.32
*/
/**
* Class MLA (Media Library Assistant) File Downloader provides file streaming to client.
*
* @package Media Library Assistant
* @since 2.32
*/
class MLAFileDownloader {
/**
* Log debug information if true
*
* @since 2.32
*
* @var boolean
*/
public static $mla_debug = false;
/**
* Process secure file download
*
* Requires mla_download_file and mla_download_type in $_REQUEST.
*
* @since 2.32
*
* @param array $args ( mla_download_file, mla_download_type, optional content_disposition )
* @return void echos file contents and calls exit();
*/
public static function mla_process_download_file( $args = NULL ) {
if ( empty( $args ) ) {
$args = $_REQUEST;
}
self::_mla_debug_add( 'MLAFileDownloader::mla_process_download_file, args = ' . var_export( $args, true ) );
if ( !empty( $args['error'] ) ) {
$message = $args['error'];
} else {
$message = '';
if ( isset( $args['mla_download_file'] ) && isset( $args['mla_download_type'] ) ) {
if( ini_get( 'zlib.output_compression' ) ) {
ini_set( 'zlib.output_compression', 'Off' );
}
$disposition = 'attachment';
if ( !empty( $args['mla_disposition'] ) ) {
$disposition = trim( strtolower( $args['mla_disposition'] ) );
switch ( $disposition ) {
case 'attachment':
case 'download':
$disposition = 'attachment';
break;
case 'inline':
case 'view':
case 'file':
$disposition = 'inline';
break;
default:
$message = 'ERROR: content disposition invalid.';
}
}
$file_name = $args['mla_download_file'];
$match_name = str_replace( '\\', '/', $file_name );
$base_dir = pathinfo( __FILE__, PATHINFO_DIRNAME );
$match_dir = str_replace( '\\', '/', $base_dir );
$allowed_path = substr( $match_dir, 0, strpos( $match_dir, 'plugins' ) );
if ( 0 !== strpos( $match_name, $allowed_path ) ) {
$message = 'ERROR: download path out of bounds.';
} elseif ( false !== strpos( $match_name, '..' ) ) {
$message = 'ERROR: download path invalid.';
}
} else {
$message = 'ERROR: download argument(s) not set.';
}
}
if ( empty( $message ) ) {
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ( 'D, d M Y H:i:s', filemtime ( $file_name ) ).' GMT');
header('Cache-Control: private',false);
header('Content-Type: '.$args['mla_download_type']);
if ( 'attachment' === $disposition ) {
header('Content-Disposition: attachment; filename="'.basename( $file_name ).'"');
header('Content-Transfer-Encoding: binary');
}
header('Content-Length: '.filesize( $file_name )); // provide file size
header('Connection: close');
readfile( $file_name );
} else {
self::_mla_debug_add( $message );
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
echo '<html xmlns="http://www.w3.org/1999/xhtml">';
echo '<head>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
echo '<title>Download Error</title>';
echo '</head>';
echo '';
echo '<body>';
echo $message;
echo '</body>';
echo '</html> ';
}
exit();
}
/**
* Log debug information
*
* @since 2.32
*
* @param string $message Error message.
*/
private static function _mla_debug_add( $message ) {
if ( self::$mla_debug ) {
if ( class_exists( 'MLACore' ) ) {
MLACore::mla_debug_mode( 'log' );
MLACore::mla_debug_add( $message );
} else {
error_log( $message, 0);
}
}
}
/**
* Abort the operation and exit
*
* @since 2.32
*
* @param string $message Error message.
* @param string $title Optional. Error title. Default empty.
* @param integer $response Optional. HTML response code. Default 500.
* @return void echos page content and calls exit();
*/
public static function mla_die( $message, $title = '', $response = 500 ) {
self::_mla_debug_add( __LINE__ . " mla_die( '{$message}', '{$title}', '{$response}' )" );
exit();
}
/**
* Log the message and return error message array
*
* @since 2.32
*
* @param string $message Error message.
* @param string $line Optional. Line number in the caller.
*
* @return array( 'error' => message )
*/
private static function _mla_error_return( $message, $line = '' ) {
self::_mla_debug_add( $line . " MLAFileDownloader::_mla_error_return '{$message}'" );
return array( 'error' => $message );
}
} // Class MLAFileDownloader
?>

View File

@@ -0,0 +1,760 @@
<?php
/**
* Image processing support for mla_viewer and thumbnail generation
*
* @package Media Library Assistant
* @since 2.13
*/
/**
* Class MLA (Media Library Assistant) Image Processor provides PDF thumbnails
* for the [mla_gallery] mla_viewer
* and Media/Assistant thumbnail generator.
*
* @package Media Library Assistant
* @since 2.10
*/
class MLAImageProcessor {
/**
* Log debug information if true
*
* @since 2.12
*
* @var boolean
*/
public static $mla_debug = false;
/**
* Generate a unique, writable file in the temporary directory
*
* @since 2.10
*
* @param string $extension File extension for the temporary file
*
* @return string Writable path and file name.
*/
private static function _get_temp_file( $extension = '.tmp' ) {
static $temp = NULL;
/*
* Find a temp directory
*/
if ( NULL == $temp ) {
if ( function_exists('sys_get_temp_dir') ) {
$temp = sys_get_temp_dir();
if ( @is_dir( $temp ) ) {
$temp = rtrim( $temp, '/\\' ) . '/';
}
} else {
$temp = ini_get('upload_tmp_dir');
if ( @is_dir( $temp ) ) {
$temp = rtrim( $temp, '/\\' ) . '/';
} else {
$temp = '/tmp/';
if ( false == @is_dir( $temp ) ) {
self::_mla_debug_add( 'MLAImageProcessor::_get_temp_file Temp directory failure' );
return false;
}
}
}
}
/*
* Create a unique file
*/
$path = $temp . uniqid( mt_rand() ) . $extension;
$f = @fopen( $path, 'a' );
if ( $f === false ) {
self::_mla_debug_add( 'MLAImageProcessor::_get_temp_file Temp file failure' );
return false;
}
fclose( $f );
return $path;
}
/**
* Imagick object for the image to be streamed
*
* @since 2.10
*
* @var Imagick
*/
protected static $image;
/**
* Direct Ghostscript file conversion
*
* @since 2.10
* @uses self::$image loads the converted file to this Imagick object
*
* @param string $file Input file, e.g., a PDF document
* @param string $frame Page/frame within the file, zero-based
* @param string $resolution Output file DPI. Default 72.
* @param string $output_type Output MIME type; 'image/jpeg' or 'image/png'.
* @param string $explicit_path Optional. Non-standard location to override default search, e.g., 'C:\Program Files (x86)\gs\gs9.15\bin\gswin32c.exe'
*
* @return boolean true if conversion succeeds else false
*/
private static function _ghostscript_convert( $file, $frame, $resolution, $output_type, $explicit_path = '' ) {
/*
* Look for exec() - from http://stackoverflow.com/a/12980534/866618
*/
$blacklist = preg_split( '/,\s*/', ini_get('disable_functions') . ',' . ini_get('suhosin.executor.func.blacklist') );
if ( in_array('exec', $blacklist) ) {
self::_mla_debug_add( 'MLAImageProcessor::_ghostscript_convert blacklist failure' );
return false;
}
/*
* Look for the Ghostscript executable
*/
$ghostscript_path = NULL;
do {
if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3) ) ) {
if ( ! empty( $explicit_path ) ) {
$ghostscript_path = exec( 'dir /o:n/s/b "' . $explicit_path . '"' );
if ( ! empty( $ghostscript_path ) ) {
break;
} else {
$ghostscript_path = NULL;
break;
}
}
if ( $ghostscript_path = getenv('GSC') ) {
break;
}
$ghostscript_path = exec('where gswin*c.exe');
if ( ! empty( $ghostscript_path ) ) {
break;
}
$ghostscript_path = exec('dir /o:n/s/b "C:\Program Files\gs\*gswin*c.exe"');
if ( ! empty( $ghostscript_path ) ) {
break;
}
$ghostscript_path = exec('dir /o:n/s/b "C:\Program Files (x86)\gs\*gswin32c.exe"');
if ( ! empty( $ghostscript_path ) ) {
break;
}
$ghostscript_path = NULL;
break;
} // Windows platform
if ( ! empty( $explicit_path ) ) {
exec( 'test -e ' . $explicit_path, $dummy, $ghostscript_path );
if ( $explicit_path !== $ghostscript_path ) {
$ghostscript_path = NULL;
}
break;
}
$ghostscript_path = exec('which gs');
if ( ! empty( $ghostscript_path ) ) {
break;
}
$test_path = '/usr/bin/gs';
exec('test -e ' . $test_path, $dummy, $ghostscript_path);
if ( $test_path !== $ghostscript_path ) {
$ghostscript_path = NULL;
}
} while ( false );
self::_mla_debug_add( 'MLAImageProcessor::_ghostscript_convert ghostscript_path = ' . var_export( $ghostscript_path, true ) );
if ( isset( $ghostscript_path ) ) {
if ( 'image/jpeg' == $output_type ) {
$device = 'jpeg';
$extension = '.jpg';
} else {
$device = 'png16m';
$extension = '.png';
}
/*
* Generate a unique temporary file
*/
$output_file = self::_get_temp_file( $extension );
$cmd = escapeshellarg( $ghostscript_path ) . ' -sDEVICE=%1$s -r%2$dx%2$d -dFirstPage=%3$d -dLastPage=%3$d -dFitPage -o %4$s %5$s 2>&1';
$cmd = sprintf( $cmd, $device, $resolution, ( $frame + 1 ), escapeshellarg( $output_file ), escapeshellarg( $file ) );
exec( $cmd, $stdout, $return );
if ( 0 != $return ) {
self::_mla_debug_add( "ERROR: _ghostscript_convert exec returned '{$return}, cmd = " . var_export( $cmd, true ) );
self::_mla_debug_add( "ERROR: _ghostscript_convert exec returned '{$return}, details = " . var_export( $stdout, true ) );
return false;
}
try {
self::$image->readImage( $output_file );
}
catch ( Exception $e ) {
self::_mla_debug_add( "ERROR: _ghostscript_convert readImage Exception = " . var_export( $e->getMessage(), true ) );
return false;
}
@unlink( $output_file );
return true;
} // found Ghostscript
self::_mla_debug_add( 'MLAImageProcessor::_ghostscript_convert Ghostscript detection failure' );
return false;
} // _ghostscript_convert
/**
* Prepare the image for output, scaling and flattening as required
*
* @since 2.10
* @uses self::$image updates the image in this Imagick object
*
* @param integer zero or new width
* @param integer zero or new height
* @param boolean proportional fit (true) or exact fit (false)
* @param string output MIME type
* @param integer compression quality; 1 - 100
*
* @return void
*/
private static function _prepare_image( $width, $height, $best_fit, $type, $quality ) {
//error_log( __LINE__ . " MLAImageProcessor::_prepare_image( {$width}, {$height}, {$best_fit}, {$type}, {$quality} )", 0 );
if ( 'WordPress' == $type ) {
$default_width = 0;
$type = 'image/jpeg';
} else {
$default_width = 150;
}
if ( is_callable( array( self::$image, 'scaleImage' ) ) ) {
if ( 0 < $width && 0 < $height ) {
// Both are set; use them as-is
self::$image->scaleImage( $width, $height, $best_fit );
} elseif ( 0 < $width || 0 < $height ) {
// One is set; scale the other one proportionally if reducing
$image_size = self::$image->getImageGeometry();
if ( $width && isset( $image_size['width'] ) && $width < $image_size['width'] ) {
self::$image->scaleImage( $width, 0 );
} elseif ( $height && isset( $image_size['height'] ) && $height < $image_size['height'] ) {
self::$image->scaleImage( 0, $height );
}
} else {
// Neither is specified, apply defaults; ( 0, 0 ) is invalid.
if ( $default_width ) {
self::$image->scaleImage( $default_width, 0 );
}
}
}
if ( 0 < $quality && 101 > $quality ) {
if ( 'image/jpeg' == $type ) {
self::$image->setImageCompressionQuality( $quality );
self::$image->setImageCompression( imagick::COMPRESSION_JPEG );
}
else {
self::$image->setImageCompressionQuality( $quality );
}
}
if ( 'image/jpeg' == $type ) {
if ( is_callable( array( self::$image, 'setImageBackgroundColor' ) ) ) {
self::$image->setImageBackgroundColor('white');
}
if ( is_callable( array( self::$image, 'mergeImageLayers' ) ) ) {
self::$image = self::$image->mergeImageLayers( imagick::LAYERMETHOD_FLATTEN );
} elseif ( is_callable( array( self::$image, 'flattenImages' ) ) ) {
self::$image = self::$image->flattenImages();
}
}
} // _prepare_image
/**
* Log debug information
*
* @since 2.12
*
* @param string $message Error message.
*/
private static function _mla_debug_add( $message ) {
if ( self::$mla_debug ) {
if ( class_exists( 'MLACore' ) ) {
MLACore::mla_debug_add( $message );
} else {
error_log( $message, 0);
}
}
}
/**
* Abort the operation and exit
*
* @since 2.10
*
* @param string $message Error message.
* @param string $title Optional. Error title. Default empty.
* @param integer $response Optional. HTML response code. Default 500.
* @return void echos page content and calls exit();
*/
private static function _mla_die( $message, $title = '', $response = 500 ) {
self::_mla_debug_add( __LINE__ . " _mla_die( '{$message}', '{$title}', '{$response}' )" );
exit();
}
/**
* Log the message and return error message array
*
* @since 2.10
*
* @param string $message Error message.
* @param string $line Optional. Line number in the caller.
*
* @return array( 'error' => message )
*/
private static function _mla_error_return( $message, $line = '' ) {
self::_mla_debug_add( $line . " MLAImageProcessor::_mla_error_return '{$message}'" );
return array( 'error' => $message );
}
/**
* Process Imagick thumbnail conversion request, e.g., for a PDF thumbnail
*
* Replaces download_url() in the Codex "Function Reference/wp handle sideload" example.
*
* @since 2.13
*
* @param string $input_file Path and name of the source file relative to upload directory
* @param array $args Generation parameters
*
* @return array file attributes ( 'file', 'url', 'type' ) on success, ( 'error' ) on failure
*/
public static function mla_handle_thumbnail_sideload( $input_file, $args ) {
MLACore::mla_debug_add( __LINE__ . " MLAImageProcessor::mla_handle_thumbnail_sideload( {$input_file} ) args = " . var_export( $args, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
if ( ! class_exists( 'Imagick' ) ) {
return self::_mla_error_return( 'Imagick not installed', __LINE__ );
}
if( ini_get( 'zlib.output_compression' ) ) {
ini_set( 'zlib.output_compression', 'Off' );
}
if ( ! is_file( $input_file ) ) {
return self::_mla_error_return( 'File not found: ' . $input_file, __LINE__ );
}
// Process generation parameters and supply defaults
$width = isset( $args['width'] ) ? abs( intval( $args['width'] ) ) : 0;
$height = isset( $args['height'] ) ? abs( intval( $args['height'] ) ) : 0;
$type = isset( $args['type'] ) ? $args['type'] : 'image/jpeg';
$quality = isset( $args['quality'] ) ? abs( intval( $args['quality'] ) ) : 0;
$frame = isset( $args['frame'] ) ? abs( intval( $args['frame'] ) ) : 0;
$resolution = isset( $args['resolution'] ) ? abs( intval( $args['resolution'] ) ) : 72;
$best_fit = isset( $args['best_fit'] ) ? (boolean) $args['best_fit'] : false;
$ghostscript_path = isset( $args['ghostscript_path'] ) ? $args['ghostscript_path'] : '';
// Retain WordPress type for _prepare_image and adjust defaults
if ( 'WordPress' === $type ) {
$mime_type = 'image/jpeg';
$resolution = isset( $args['resolution'] ) ? abs( intval( $args['resolution'] ) ) : 128;
} else {
$mime_type = $type;
}
// Convert the file to an image format and load it
try {
$try_step = __LINE__ . ' new Imagick()';
self::$image = new Imagick();
/*
* this must be called before reading the image, otherwise has no effect -
* "-density {$x_resolution}x{$y_resolution}"
* this is important to give good quality output, otherwise text might be unclear
* default resolution is 72,72 or 128,128 for WordPress thumbnails
*/
$try_step = __LINE__ . ' setResolution';
self::$image->setResolution( $resolution, $resolution );
$try_step = __LINE__ . ' _ghostscript_convert';
$result = self::_ghostscript_convert( $input_file, $frame, $resolution, $mime_type, $ghostscript_path );
if ( false === $result ) {
try {
$try_step = __LINE__ . " readImage [{$frame}]";
self::$image->readImage( $input_file . '[' . $frame . ']' );
}
catch ( Exception $e ) {
$try_step = __LINE__ . ' readImage [0]';
self::$image->readImage( $input_file . '[0]' );
}
if ( 'image/jpeg' == $mime_type ) {
$extension = 'JPG';
} else {
$extension = 'PNG';
}
$try_step = __LINE__ . " setImageFormat( {$extension} )";
self::$image->setImageFormat( $extension );
}
if ( ! self::$image->valid() ) {
self::_mla_die( 'File not loaded', __LINE__, 404 );
}
} catch ( Throwable $e ) { // PHP 7
return self::_mla_error_return( 'Image load Throwable: ' . $e->getMessage() . ' from step ' . $try_step, __LINE__ );
} catch ( Exception $e ) { // PHP 5
return self::_mla_error_return( 'Image load Exception: ' . $e->getMessage() . ' from step ' . $try_step, __LINE__ );
}
/*
* Prepare the output image; resize and flatten, if necessary.
* $type retains "WordPress" selection
*/
try {
self::_prepare_image( $width, $height, $best_fit, $type, $quality );
} catch ( Throwable $e ) { // PHP 7
return self::_mla_error_return( '_prepare_image Throwable: ' . $e->getMessage(), __LINE__ );
} catch ( Exception $e ) { // PHP 5
return self::_mla_error_return( '_prepare_image Exception: ' . $e->getMessage(), __LINE__ );
}
// Write the image to an appropriately-named file
try {
$output_file = wp_tempnam( $input_file );
self::$image->writeImage( $output_file );
$dimensions = self::$image->getImageGeometry();
} catch ( Throwable $e ) { // PHP 7
return self::_mla_error_return( 'Image write Throwable: ' . $e->getMessage(), __LINE__ );
} catch ( Exception $e ) { // PHP 5
@unlink( $output_file );
return self::_mla_error_return( 'Image write Exception: ' . $e->getMessage(), __LINE__ );
}
// array based on $_FILE as seen in PHP file uploads
$results = array(
'name' => basename( $input_file ),
'type' => $mime_type,
'tmp_name' => $output_file,
'error' => 0,
'size' => filesize( $output_file ),
'width' => $dimensions['width'],
'height' => $dimensions['height'],
);
MLACore::mla_debug_add( __LINE__ . " MLAImageProcessor::mla_handle_thumbnail_sideload( {$input_file} ) results = " . var_export( $results, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
return $results;
}
/**
* Process Imagick image stream request, e.g., for a PDF thumbnail
*
* Requires mla_stream_file (relative to wp_upload_dir ) in $_REQUEST;
* optional $_REQUEST parameters are:
* mla_stream_width, mla_stream_height, mla_stream_frame, mla_stream_resolution,
* mla_stream_quality, mla_stream_type, mla_stream_fit, mla_ghostscript_path
*
* @since 2.10
*
* @return void echos image content and calls exit();
*/
public static function mla_process_stream_image() {
self::_mla_debug_add( 'MLAImageProcessor::mla_process_stream_image REQUEST = ' . var_export( $_REQUEST, true ) );
if ( ! class_exists( 'Imagick' ) ) {
self::_mla_die( 'Imagick not installed', __LINE__, 500 );
}
if( ini_get( 'zlib.output_compression' ) ) {
ini_set( 'zlib.output_compression', 'Off' );
}
$file = $_REQUEST['mla_stream_file'];
if ( ! is_file( $file ) ) {
self::_mla_die( 'File not found', __LINE__, 404 );
}
$use_mutex = isset( $_REQUEST['mla_single_thread'] );
$width = isset( $_REQUEST['mla_stream_width'] ) ? abs( intval( $_REQUEST['mla_stream_width'] ) ) : 0;
$height = isset( $_REQUEST['mla_stream_height'] ) ? abs( intval( $_REQUEST['mla_stream_height'] ) ) : 0;
$type = isset( $_REQUEST['mla_stream_type'] ) ? $_REQUEST['mla_stream_type'] : 'image/jpeg';
$quality = isset( $_REQUEST['mla_stream_quality'] ) ? abs( intval( $_REQUEST['mla_stream_quality'] ) ) : 0;
$frame = isset( $_REQUEST['mla_stream_frame'] ) ? abs( intval( $_REQUEST['mla_stream_frame'] ) ) : 0;
$resolution = isset( $_REQUEST['mla_stream_resolution'] ) ? abs( intval( $_REQUEST['mla_stream_resolution'] ) ) : 72;
/*
* If mla_ghostscript_path is present, a non-standard GS location can be found in a file written by
* the [mla_gallery] shortcode processor.
*/
$ghostscript_path = isset( $_REQUEST['mla_ghostscript_path'] ) ? $_REQUEST['mla_ghostscript_path'] : '';
if ( ! empty( $ghostscript_path ) ) {
$ghostscript_path = @file_get_contents( dirname( __FILE__ ) . '/' . 'mla-ghostscript-path.txt' );
}
if ( $use_mutex ) {
$temp_file = self::_get_temp_file();
@unlink( $temp_file );
$temp_file = pathinfo( $temp_file, PATHINFO_DIRNAME ) . '/mla-mutex.txt';
$mutex = new MLAMutex();
$mutex->init( 1, $temp_file );
$mutex->acquire();
self::_mla_debug_add( 'MLAImageProcessor::mla_process_stream_image begin file = ' . var_export( $file, true ) );
}
/*
* Convert the file to an image format and load it
*/
try {
self::$image = new Imagick();
/*
* this must be called before reading the image, otherwise has no effect -
* "-density {$x_resolution}x{$y_resolution}"
* this is important to give good quality output, otherwise text might be unclear
* default resolution is 72,72
*/
self::$image->setResolution( $resolution, $resolution );
//$result = false;
$result = self::_ghostscript_convert( $file, $frame, $resolution, $type, $ghostscript_path );
if ( false === $result ) {
try {
self::$image->readImage( $file . '[' . $frame . ']' );
}
catch ( Exception $e ) {
self::$image->readImage( $file . '[0]' );
}
if ( 'image/jpeg' == $type ) {
$extension = 'JPG';
} else {
$extension = 'PNG';
}
self::$image->setImageFormat( $extension );
}
if ( ! self::$image->valid() ) {
self::_mla_die( 'File not loaded', __LINE__, 404 );
}
}
catch ( Exception $e ) {
self::_mla_die( 'Image load exception: ' . $e->getMessage(), __LINE__, 404 );
}
/*
* Prepare the output image; resize and flatten, if necessary
*/
try {
if ( isset( $_REQUEST['mla_stream_fit'] ) ) {
$best_fit = ( '1' == $_REQUEST['mla_stream_fit'] );
} else {
$best_fit = false;
}
self::_prepare_image( $width, $height, $best_fit, $type, $quality );
}
catch ( Exception $e ) {
self::_mla_die( '_prepare_image exception: ' . $e->getMessage(), __LINE__, 500 );
}
/*
* Stream the image back to the requestor
*/
try {
header( "Content-Type: $type" );
echo self::$image->getImageBlob();
}
catch ( Exception $e ) {
self::_mla_die( 'Image stream exception: ' . $e->getMessage(), __LINE__, 500 );
}
if ( $use_mutex ) {
$mutex->release();
}
exit();
} // mla_process_stream_image
} // Class MLAImageProcessor
/**
* Class MLA (Media Library Assistant) Mutex provides a simple "mutual exclusion" semaphore
* for the [mla_gallery] mla_viewer=single option
*
* Adapted from the example by mr.smaon@gmail.com in the PHP Manual "Semaphore Functions" page.
*
* @package Media Library Assistant
* @since 2.10
*/
class MLAMutex {
/**
* Semaphore identifier returned by sem_get()
*
* @since 2.10
*
* @var resource
*/
private $sem_id;
/**
* True if the semaphore has been acquired
*
* @since 2.10
*
* @var boolean
*/
private $is_acquired = false;
/**
* True if using a file lock instead of a semaphore
*
* @since 2.10
*
* @var boolean
*/
private $use_file_lock = false;
/**
* Name of the (locked) file used as a semaphore
*
* @since 2.10
*
* @var string
*/
private $filename = '';
/**
* File system pointer resource of the (locked) file used as a semaphore
*
* @since 2.10
*
* @var resource
*/
private $filepointer;
/**
* Initializes the choice of semaphore Vs file lock
*
* @since 2.10
*
* @param boolean $use_lock True to force use of file locking
*
* @return void
*/
function __construct( $use_lock = false ) {
/*
* If sem_ functions are not available require file locking
*/
if ( ! is_callable( 'sem_get' ) ) {
$use_lock = true;
}
if ( $use_lock || 'WIN' == substr( PHP_OS, 0, 3 ) ) {
$this->use_file_lock = true;
}
}
/**
* Creates the semaphore or sets the (lock) file name
*
* @since 2.10
*
* @param integer $id Key to identify the semaphore
* @param string $filename Absolute path and name of the file for locking
*
* @return boolean True if the initialization succeeded
*/
public function init( $id, $filename = '' ) {
if( $this->use_file_lock ) {
if( empty( $filename ) ) {
return false;
} else {
$this->filename = $filename;
}
} else {
if( ! ( $this->sem_id = sem_get( $id, 1) ) ) {
return false;
}
}
return true;
}
/**
* Acquires the semaphore or opens and locks the file
*
* @since 2.10
*
* @return boolean True if the acquisition succeeded
*/
public function acquire() {
if( $this->use_file_lock ) {
if ( empty( $this->filename ) ) {
return true;
}
if( false == ( $this->filepointer = @fopen( $this->filename, "w+" ) ) ) {
return false;
}
if( false == flock( $this->filepointer, LOCK_EX ) ) {
return false;
}
} else {
if ( ! sem_acquire( $this->sem_id ) ) {
return false;
}
}
$this->is_acquired = true;
return true;
}
/**
* Releases the semaphore or unlocks and closes (but does not unlink) the file
*
* @since 2.10
*
* @return boolean True if the release succeeded
*/
public function release() {
if( ! $this->is_acquired ) {
return true;
}
if( $this->use_file_lock ) {
if( false == flock( $this->filepointer, LOCK_UN ) ) {
return false;
}
fclose( $this->filepointer );
} else {
if ( ! sem_release( $this->sem_id ) ) {
return false;
}
}
$this->is_acquired = false;
return true;
}
/**
* Returns the semaphore identifier, if it exists, else NULL
*
* @since 2.10
*
* @return resource Semaphore identifier or NULL
*/
public function getId() {
return $this->sem_id;
}
} // MLAMutex
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,738 @@
<?php
/**
* Media Library Assistant Ajax Handlers for Media Manager enhancements
*
* @package Media Library Assistant
* @since 2.20
*/
/**
* Class MLA (Media Library Assistant) Modal Ajax contains handlers for the WordPress 3.5+ Media Manager
*
* @package Media Library Assistant
* @since 2.20
*/
class MLAModal_Ajax {
/**
* Initialization function, similar to __construct()
*
* @since 2.20
*
* @return void
*/
public static function initialize() {
add_action( 'admin_init', 'MLAModal_Ajax::mla_admin_init_action' );
add_action( 'wp_ajax_' . MLACore::JAVASCRIPT_QUERY_ATTACHMENTS_ACTION, 'MLAModal_Ajax::mla_query_attachments_action' );
add_action( 'wp_ajax_' . MLACore::JAVASCRIPT_FILL_COMPAT_ACTION, 'MLAModal_Ajax::mla_fill_compat_fields_action' );
add_action( 'wp_ajax_' . MLACore::JAVASCRIPT_UPDATE_COMPAT_ACTION, 'MLAModal_Ajax::mla_update_compat_fields_action' );
/*
* For each media item found by "query_attachments", these filters are called:
*
* In /wp-admin/includes/media.php, functions get_media_item() and get_compat_media_markup()
* contain "apply_filters( 'get_media_item_args', $args );", documented as:
* "Filter the arguments used to retrieve an image for the edit image form."
*
* In /wp-admin/includes/media.php, functions get_attachment_fields_to_edit()
* and get_compat_media_markup() contain
* "$form_fields = apply_filters( 'attachment_fields_to_edit', $form_fields, $post );",
* documented as: "Filter the attachment fields to edit."
*/
add_filter( 'get_media_item_args', 'MLAModal_Ajax::mla_get_media_item_args_filter', 10, 1 );
add_filter( 'attachment_fields_to_edit', 'MLAModal_Ajax::mla_attachment_fields_to_edit_filter', 0x7FFFFFFF, 2 );
}
/**
* Adjust ajax handler for Media Manager queries
*
* Replace 'query-attachments' with our own handler if the request is coming from the "Assistant" tab.
* Clean up the 'save-attachment-compat' values, removing the taxonomy updates MLS already handled.
*
* @since 2.20
*
* @return void
*/
public static function mla_admin_init_action() {
//error_log( __LINE__ . ' DEBUG: class MLAModal_Ajax::mla_admin_init_action $_POST = ' . var_export( $_POST, true ), 0 );
//cause_an_error();
//$cause_notice = $screen->bad_property;
//trigger_error( 'mla_print_media_templates_action', E_USER_WARNING );
//error_log( 'DEBUG: xdebug_get_function_stack = ' . var_export( xdebug_get_function_stack(), true), 0 );
// If there's no action variable, we have nothing to do
if ( ! isset( $_REQUEST['action'] ) ) {
return;
}
/*
* Build a list of enhanced taxonomies for later $_REQUEST/$_POST cleansing.
* Remove "Media Categories" instances, if present.
*/
$enhanced_taxonomies = array();
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( MLACore::mla_taxonomy_support( $key ) ) {
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
if ( $use_checklist ) {
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) ) {
$enhanced_taxonomies[] = $key;
if ( class_exists( 'Media_Categories' ) && is_array( Media_Categories::$instances ) ) {
foreach( Media_Categories::$instances as $index => $instance ) {
if ( $instance->taxonomy == $key ) {
// unset( Media_Categories::$instances[ $index ] );
Media_Categories::$instances[ $index ]->taxonomy = 'MLA-has-disabled-this-instance';
}
}
} // class_exists
} // checked
} // use_checklist
} // supported
} // foreach taxonomy
/*
* The 'query-attachments' action fills the Modal Window thumbnail pane with media items.
* If the 's' value is an array, the MLA Enhanced elements are present; unpack the arguments
* and substitute our handler for the WordPress default handler.
*/
if ( ( $_REQUEST['action'] == 'query-attachments' ) && isset( $_POST['query']['s'] ) && is_array( $_POST['query']['s'] ) ){
foreach ( $_POST['query']['s'] as $key => $value ) {
$_POST['query'][ $key ] = $value;
$_REQUEST['query'][ $key ] = $value;
}
unset( $_POST['query']['s'] );
unset( $_REQUEST['query']['s'] );
$_POST['action'] = MLACore::JAVASCRIPT_QUERY_ATTACHMENTS_ACTION;
$_REQUEST['action'] = MLACore::JAVASCRIPT_QUERY_ATTACHMENTS_ACTION;
return;
} // query-attachments
/*
* The 'save-attachment-compat' action updates taxonomy and custom field
* values for an item. Remove any MLA-enhanced taxonomy data from the
* incoming data. The other taxonomies will be processed by
* /wp-admin/includes/ajax-actions.php, function wp_ajax_save_attachment_compat().
*/
if ( ( $_REQUEST['action'] == 'save-attachment-compat' ) ){
if ( empty( $_REQUEST['id'] ) || ! $id = absint( $_REQUEST['id'] ) ) {
wp_send_json_error();
}
if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) ) {
wp_send_json_error();
}
// Media Categories uses this
if ( isset( $_REQUEST['category-filter'] ) ) {
unset( $_REQUEST['category-filter'] );
unset( $_POST['category-filter'] );
}
if ( isset( $_REQUEST['mla_attachments'] ) ) {
unset( $_REQUEST['mla_attachments'] );
unset( $_POST['mla_attachments'] );
}
if ( isset( $_REQUEST['tax_input'] ) ) {
unset( $_REQUEST['tax_input'] );
unset( $_POST['tax_input'] );
}
foreach( $enhanced_taxonomies as $taxonomy ) {
if ( isset( $_REQUEST['attachments'][ $id ][ $taxonomy ] ) ) {
unset( $_REQUEST['attachments'][ $id ][ $taxonomy ] );
unset( $_POST['attachments'][ $id ][ $taxonomy ] );
}
if ( isset( $_REQUEST[ $taxonomy ] ) ) {
unset( $_REQUEST[ $taxonomy ] );
unset( $_POST[ $taxonomy ] );
}
if ( ( 'category' == $taxonomy ) && isset( $_REQUEST['post_category'] ) ) {
unset( $_REQUEST['post_category'] );
unset( $_POST['post_category'] );
}
if ( isset( $_REQUEST[ 'new' . $taxonomy ] ) ) {
unset( $_REQUEST[ 'new' . $taxonomy ] );
unset( $_POST[ 'new' . $taxonomy ] );
unset( $_REQUEST[ 'new' . $taxonomy . '_parent' ] );
unset( $_POST[ 'new' . $taxonomy . '_parent' ] );
unset( $_REQUEST[ '_ajax_nonce-add-' . $taxonomy ] );
unset( $_POST[ '_ajax_nonce-add-' . $taxonomy ] );
}
if ( isset( $_REQUEST[ 'search-' . $taxonomy ] ) ) {
unset( $_REQUEST[ 'search-' . $taxonomy ] );
unset( $_POST[ 'search-' . $taxonomy ] );
unset( $_REQUEST[ '_ajax_nonce-search-' . $taxonomy ] );
unset( $_POST[ '_ajax_nonce-search-' . $taxonomy ] );
}
} // foreach taxonomy
} // save-attachment-compat
} // mla_admin_init_action
/**
* Saves the get_media_item_args array for the attachment_fields_to_edit filter
*
* Declared public because it is a filter.
*
* @since 1.71
*
* @param array arguments for the get_media_item function in /wp-admin/includes/media.php
*
* @return array arguments for the get_media_item function (unchanged)
*/
public static function mla_get_media_item_args_filter( $args ) {
self::$media_item_args = $args;
return $args;
} // mla_get_media_item_args_filter
/**
* The get_media_item_args array
*
* @since 1.71
*
* @var array ( 'errors' => array of strings, 'in_modal => boolean )
*/
private static $media_item_args = array( 'errors' => NULL, 'in_modal' => false );
/**
* Add/change custom fields to the Edit Media screen and Modal Window
*
* Called from /wp-admin/includes/media.php, function get_compat_media_markup();
* If "get_media_item_args"['in_modal'] => false ) its the Edit Media screen.
* If "get_media_item_args"['in_modal'] => true ) its the Media Manager Modal Window.
* For the Modal Window, $form_fields contains all the "compat-attachment-fields"
* including the taxonomies, which we want to enhance.
* Declared public because it is a filter.
*
* @since 1.71
*
* @param array descriptors for the "compat-attachment-fields"
* @param object the post to be edited
*
* @return array updated descriptors for the "compat-attachment-fields"
*/
public static function mla_attachment_fields_to_edit_filter( $form_fields, $post ) {
$id = $post->ID;
/*
* This logic is only required for the MLA-enhanced Media Manager Modal Window.
* For the non-Modal Media/Edit Media screen, the MLAEdit::mla_add_meta_boxes_action
* function changes the default meta box to the MLA searchable meta box.
*/
if ( isset( self::$media_item_args['in_modal'] ) && self::$media_item_args['in_modal'] ) {
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( MLACore::mla_taxonomy_support( $key ) ) {
if ( isset( $form_fields[ $key ] ) ) {
$field = $form_fields[ $key ];
} else {
continue;
}
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
// Make sure the appropriate MMMW Enhancement option has been checked
if ( $use_checklist ) {
if ( 'checked' !== MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) ) {
continue;
}
} else {
if ( 'checked' !== MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_TAG_METABOX ) ) {
continue;
}
}
// Remove "Media Categories" meta box, if present.
if ( isset( $form_fields[ $key . '_metabox' ] ) ) {
unset( $form_fields[ $key . '_metabox' ] );
}
/*
* Simulate the default MMMW text box with a hidden field;
* use term names for flat taxonomies and term_ids for hierarchical.
*/
$post_id = $post->ID;
$label = $field['labels']->name;
$terms = get_object_term_cache( $post_id, $key );
if ( false === $terms ) {
$terms = wp_get_object_terms( $post_id, $key );
wp_cache_add( $post_id, $terms, $key . '_relationships' );
}
if ( is_wp_error( $terms ) || empty( $terms ) ) {
$terms = array();
}
$list = array();
foreach ( $terms as $term ) {
if ( $value->hierarchical ) {
$list[] = $term->term_id;
} else {
$list[] = $term->name;
}
} // foreach $term
sort( $list );
$list = join( ',', $list );
$class = ( $value->hierarchical ) ? 'categorydiv' : 'tagsdiv';
$row = "\t\t<tr class='compat-field-{$key} mla-taxonomy-row' style='display: none'>\n";
$row .= "\t\t<th class='label' valign='top' scope='row'>\n";
$row .= "\t\t<label for='mla-attachments-{$post_id}-{$key}'>\n";
$row .= "\t\t<span title='" . __( 'Click to toggle', 'media-library-assistant' ) . "' class='alignleft'>{$label}</span><br class='clear'>\n";
$row .= "\t\t</label></th>\n";
$row .= "\t\t<td class='field'>\n";
$row .= "\t\t<div class='mla-taxonomy-field'>\n";
$row .= "\t\t<input name='mla_attachments[{$post_id}][{$key}]' class='text' id='mla-attachments-{$post_id}-{$key}' type='hidden' value='{$list}'>\n";
$row .= "\t\t<div id='mla-taxonomy-{$key}' class='{$class}'>\n";
$row .= '&lt;- ' . __( 'Click to toggle', 'media-library-assistant' ) . "\n";
$row .= "\t\t</div>\n";
$row .= "\t\t</div>\n";
$row .= "\t\t</td>\n";
$row .= "\t\t</tr>\n";
//$form_fields[ $key ] = array( 'tr' => $row );
$form_fields[ 'mla-' . $key ] = array( 'tr' => $row );
} // is supported
} // foreach
$form_fields = apply_filters( 'mla_media_modal_form_fields', $form_fields, $post );
} // in_modal
self::$media_item_args = array( 'errors' => NULL, 'in_modal' => false );
return $form_fields;
} // mla_attachment_fields_to_edit_filter
/**
* Ajax handler for Media Manager "fill compat-attachment-fields" queries
*
* Prepares an array of (HTML) taxonomy meta boxes with attachment-specific values.
*
* @since 2.20
*
* @return void passes array of results to wp_send_json_success() for JSON encoding and transmission
*/
public static function mla_fill_compat_fields_action() {
if ( empty( $_REQUEST['query'] ) || ! $requested = $_REQUEST['query'] ) {
wp_send_json_error();
}
if ( empty( $_REQUEST['id'] ) || ! $post_id = absint( $_REQUEST['id'] ) ) {
wp_send_json_error();
}
if ( NULL == ( $post = get_post( $post_id ) ) ) {
wp_send_json_error();
}
$results = apply_filters( 'mla_media_modal_begin_fill_compat_fields', array(), $requested, $post );
if ( ! empty( $results ) ) {
wp_send_json_success( $results );
}
// Flat taxonomy handling is WP version-specific
$wp_version = get_bloginfo('version');
$generate_tag_buttons = version_compare( $wp_version, '4.6.99', '>' );
$generate_tag_ul = version_compare( $wp_version, '4.8.99', '>' );
// Match all supported taxonomies against the requested list
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( MLACore::mla_taxonomy_support( $key ) ) {
if ( is_integer( $index = array_search( $key, $requested ) ) ) {
$request = $requested[ $index ];
} else {
continue;
}
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
if ( $use_checklist ) {
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) ) {
unset( $requested[ $index ] );
$label = $value->label;
$terms = get_object_term_cache( $post_id, $key );
if ( false === $terms ) {
$terms = wp_get_object_terms( $post_id, $key );
wp_cache_add( $post_id, $terms, $key . '_relationships' );
}
if ( is_wp_error( $terms ) || empty( $terms ) ) {
$terms = array();
}
$list = array();
foreach ( $terms as $term ) {
$list[] = $term->term_id;
} // foreach $term
sort( $list );
$list = join( ',', $list );
// Simulate the 'add_meta_boxes' callback
$box = array (
'id' => $key . 'div',
'title' => $label,
'callback' => 'MLACore::mla_checklist_meta_box',
'args' => array ( 'taxonomy' => $key, 'in_modal' => true ),
);
ob_start();
MLACore::mla_checklist_meta_box( $post, $box );
$row_content = ob_get_clean();
$row = "\t\t<th class='label' valign='top' scope='row' style='width: 99%;'>\n";
$row .= "\t\t<label for='mla-attachments-{$post_id}-{$key}'>\n";
$row .= "\t\t<span title='" . __( 'Click to toggle', 'media-library-assistant' ) . "' class='alignleft' style='width: 99%; text-align: left;'>{$label}</span><br class='clear'>\n";
$row .= "\t\t</label></th>\n";
$row .= "\t\t<td class='field' style='width: 99%; display: none'>\n";
$row .= "\t\t<div class='mla-taxonomy-field'>\n";
$row .= "\t\t<input name='attachments[{$post_id}][{$key}]' class='text' id='mla-attachments-{$post_id}-{$key}' type='hidden' value='{$list}'>\n";
$row .= $row_content;
$row .= "\t\t</div>\n";
$row .= "\t\t</td>\n";
$results[ $key ] = $row;
} // checked
} /* use_checklist */ else { // flat
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_TAG_METABOX ) ) {
unset( $requested[ $index ] );
$label = $value->label;
$terms = get_object_term_cache( $post_id, $key );
if ( false === $terms ) {
$terms = wp_get_object_terms( $post_id, $key );
wp_cache_add( $post_id, $terms, $key . '_relationships' );
}
if ( is_wp_error( $terms ) || empty( $terms ) ) {
$terms = array();
}
$list = array();
foreach ( $terms as $term ) {
$list[] = $term->name;
} // foreach $term
sort( $list );
$hidden_list = join( ',', $list );
$row = "\t\t<th class='label' valign='top' scope='row' style='width: 99%;'>\n";
$row .= "\t\t<label for='mla-attachments-{$post_id}-{$key}'>\n";
$row .= "\t\t<span title='" . __( 'Click to toggle', 'media-library-assistant' ) . "' class='alignleft' style='width: 99%; text-align: left;'>{$label}</span><br class='clear'>\n";
$row .= "\t\t</label></th>\n";
$row .= "\t\t<td class='field' style='width: 99%; display: none'>\n";
$row .= "\t\t<div class='mla-taxonomy-field'>\n";
$row .= "\t\t<div class='tagsdiv' id='mla-taxonomy-{$key}'>\n";
$row .= "\t\t<div class='jaxtag'>\n";
$row .= "\t\t<div class='nojs-tags hide-if-js'>\n";
$row .= "\t\t<input name='attachments[{$post_id}][{$key}]' class='the-tags' id='mla-attachments-{$post_id}-{$key}' type='hidden' value='{$hidden_list}'>\n";
$row .= "\t\t<input name='mla_tags[{$post_id}][{$key}]' class='server-tags' id='mla-tags-{$post_id}-{$key}' type='hidden' value='{$hidden_list}'>\n";
$row .= "\t\t</div>\n"; // nojs-tags
$row .= "\t\t<div class='ajaxtag'>\n";
$row .= "\t\t<label class='screen-reader-text' for='new-tag-{$key}'>" . __( 'Tags', 'media-library-assistant' ) . "</label>\n";
/* translators: %s: add new taxonomy label */
$row .= "\t\t<div class='taghint'>" . sprintf( __( 'Add New %1$s', 'media-library-assistant' ), $label ) . "</div>\n";
$row .= "\t\t<p>\n";
$row .= "\t\t<input name='newtag[{$key}]' class='newtag form-input-tip' id='new-tag-{$key}' type='text' size='16' value='' autocomplete='off'>\n";
$row .= "\t\t<input class='button tagadd' type='button' value='Add'>\n";
$row .= "\t\t</p>\n";
$row .= "\t\t</div>\n"; // ajaxtag
$row .= "\t\t<p class='howto'>Separate tags with commas</p>\n";
$row .= "\t\t</div>\n"; // jaxtag
// initiate tagchecklist
if ( $generate_tag_ul ) {
$row .= "\t\t<ul class='tagchecklist' role='list'>\n";
} else {
$row .= "\t\t<div class='tagchecklist'>\n";
}
foreach ( $list as $index => $term ) {
if ( $generate_tag_buttons ) {
if ( $generate_tag_ul ) {
$row .= "\t\t<li>";
} else {
$row .= "\t\t<span>";
}
$row .= "<button class='ntdelbutton' id='post_tag-check-num-{$index}' type='button'><span class='remove-tag-icon' aria-hidden='true'></span><span class='screen-reader-text'>" . __( 'Remove term', 'media-library-assistant' ) . ": {$term}</span></button>&nbsp;{$term}";
if ( $generate_tag_ul ) {
$row .= "</li>\n";
} else {
$row .= "</span>\n";
}
} else {
$row .= "\t\t<span><a class='ntdelbutton' id='post_tag-check-num-{$index}'>X</a>&nbsp;{$term}</span>\n";
}
}
// terminate tagchecklist
if ( $generate_tag_ul ) {
$row .= "\t\t</ul>\n";
} else {
$row .= "\t\t</div>\n";
}
$row .= "\t\t</div>\n"; // tagsdiv
$row .= "\t\t<p><a class='tagcloud-link' id='mla-link-{$key}' href='#titlediv'>" . __( 'Choose from the most used tags', 'media-library-assistant' ) . "</a></p>\n";
$row .= "\t\t</div>\n"; // mla-taxonomy-field
$row .= "\t\t</td>\n";
$results[ $key ] = $row;
} // checked
} // flat
} // is supported
} // foreach
/*
* Any left-over requests are for unsupported taxonomies
*/
foreach( $requested as $key ) {
$row = "\t\t<tr class='compat-field-{$key} mla-taxonomy-row'>\n";
$row .= "\t\t<th class='label' valign='top' scope='row'>\n";
$row .= "\t\t<label for='mla-attachments-{$post_id}-{$key}'>\n";
$row .= "\t\t<span title='" . __( 'Click to toggle', 'media-library-assistant' ) . "' class='alignleft'>{$label}</span><br class='clear'>\n";
$row .= "\t\t</label></th>\n";
$row .= "\t\t<td class='field' style='display: none'>\n";
$row .= "\t\t<div class='mla-taxonomy-field'>\n";
$row .= "\t\t<input name='attachments[{$post_id}][{$key}]' class='text' id='mla-attachments-{$post_id}-{$key}' type='hidden' value=''>\n";
$row .= "\t\t<div id='taxonomy-{$key}' class='categorydiv'>\n";
$row .= __( 'Not Supported', 'media-library-assistant' ) . ".\n";
$row .= "\t\t</div>\n";
$row .= "\t\t</div>\n";
$row .= "\t\t</td>\n";
$row .= "\t\t</tr>\n";
$results[ $key ] = $row;
}
wp_send_json_success( apply_filters( 'mla_media_modal_end_fill_compat_fields', $results, $_REQUEST['query'], $requested, $post ) );
} // mla_fill_compat_fields_action
/**
* Ajax handler for Media Manager "update compat-attachment-fields" queries
*
* Updates one (or more) supported taxonomy and returns updated checkbox or tag/term lists
*
* @since 2.20
*
* @return void passes array of results to wp_send_json_success() for JSON encoding and transmission
*/
public static function mla_update_compat_fields_action() {
global $post;
if ( empty( $_REQUEST['id'] ) || ! $post_id = absint( $_REQUEST['id'] ) ) {
wp_send_json_error();
}
if ( empty( $post ) ) {
$post = get_post( $post_id ); // for filters and wp_popular_terms_checklist
}
do_action( 'mla_media_modal_begin_update_compat_fields', $post );
$taxonomies = array();
$results = array();
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( isset( $_REQUEST[ $key ] ) && MLACore::mla_taxonomy_support( $key ) ) {
$taxonomies[ $key ] = $value;
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
if ( $value->hierarchical ) {
$terms = array_map( 'absint', preg_split( '/,+/', $_REQUEST[ $key ] ) );
} else {
$terms = array_map( 'trim', preg_split( '/,+/', $_REQUEST[ $key ] ) );
}
$terms = apply_filters( 'mla_media_modal_update_compat_fields_terms', $terms, $key, $value, $post_id );
if ( is_array( $terms ) ) {
wp_set_object_terms( $post_id, $terms, $key, false );
delete_transient( MLA_OPTION_PREFIX . 't_term_counts_' . $key );
}
if ( $use_checklist ) {
ob_start();
$popular_ids = wp_popular_terms_checklist( $key );
$results[$key]["mla-{$key}-checklist-pop"] = ob_get_clean();
ob_start();
if ( $value->hierarchical ) {
wp_terms_checklist( $post_id, array( 'taxonomy' => $key, 'popular_cats' => $popular_ids ) );
} else {
$checklist_walker = new MLA_Checklist_Walker;
wp_terms_checklist( $post_id, array( 'taxonomy' => $key, 'popular_cats' => $popular_ids, 'walker' => $checklist_walker ) );
}
$results[$key]["mla-{$key}-checklist"] = ob_get_clean();
} else {
$terms = get_object_term_cache( $post_id, $key );
if ( false === $terms ) {
$terms = wp_get_object_terms( $post_id, $key );
wp_cache_add( $post_id, $terms, $key . '_relationships' );
}
if ( is_wp_error( $terms ) || empty( $terms ) ) {
$terms = array();
}
$list = array();
$object_terms = array();
foreach ( $terms as $term ) {
$list[] = $term->name;
$object_terms[ $term->term_id ] = $term->name;
} // foreach $term
sort( $list );
$hidden_list = join( ',', $list );
$results[$key]["object-terms"] = $object_terms;
$results[$key]["mla-attachments-{$post_id}-{$key}"] = "\t\t<input name='attachments[{$post_id}][{$key}]' class='the-tags' id='mla-attachments-{$post_id}-{$key}' type='hidden' value='{$hidden_list}'>\n";
$results[$key]["mla-tags-{$post_id}-{$key}"] = "\t\t<input name='mla_tags[{$post_id}][{$key}]' class='server-tags' id='mla-tags-{$post_id}-{$key}' type='hidden' value='{$hidden_list}'>\n";
}
} // set and supported
} // foreach taxonomy
wp_send_json_success( apply_filters( 'mla_media_modal_end_update_compat_fields', $results, $taxonomies, $post ) );
} // mla_update_compat_fields_action
/**
* Ajax handler for Media Manager "Query Attachments" queries
*
* Adapted from wp_ajax_query_attachments in /wp-admin/includes/ajax-actions.php
*
* @since 2.20
*
* @return void passes array of post arrays to wp_send_json_success() for JSON encoding and transmission
*/
public static function mla_query_attachments_action() {
if ( ! current_user_can( 'upload_files' ) ) {
wp_send_json_error();
}
/*
* Pick out and clean up the query terms we can process
*/
$raw_query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
$query = array_intersect_key( $raw_query, array_flip( array(
'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
'post_parent', 'post__in', 'post__not_in',
'mla_filter_month', 'mla_filter_term', 'mla_terms_search',
'mla_search_value', 's', 'mla_search_fields', 'mla_search_connector'
) ) );
//error_log( __LINE__ . ' mla_query_attachments_action query = ' . var_export( $query, true ), 0 );
$query = apply_filters( 'mla_media_modal_query_initial_terms', $query, $raw_query );
if ( isset( $query['post_mime_type'] ) ) {
if ( 'detached' == $query['post_mime_type'] ) {
$query['detached'] = '1';
unset( $query['post_mime_type'] );
} elseif ( 'attached' == $query['post_mime_type'] ) {
$query['detached'] = '0';
unset( $query['post_mime_type'] );
} elseif ( 'trash' == $query['post_mime_type'] ) {
$query['status'] = 'trash';
unset( $query['post_mime_type'] );
} else {
$view = $query['post_mime_type'];
unset( $query['post_mime_type'] );
$query = array_merge( $query, MLACore::mla_prepare_view_query( 'view', $view ) );
}
}
/*
* Convert mla_filter_month back to the WordPress "m" parameter
*/
if ( isset( $query['mla_filter_month'] ) ) {
if ( '0' != $query['mla_filter_month'] ) {
$query['m'] = $query['mla_filter_month'];
}
unset( $query['mla_filter_month'] );
}
/*
* Process the enhanced search box OR fix up the default search box
*/
if ( isset( $query['mla_search_value'] ) ) {
if ( ! empty( $query['mla_search_value'] ) ) {
$query['s'] = $query['mla_search_value'];
}
unset( $query['mla_search_value'] );
}
if ( isset( $query['posts_per_page'] ) ) {
$count = $query['posts_per_page'];
$offset = $count * (isset( $query['paged'] ) ? $query['paged'] - 1 : 0);
} else {
$count = 0;
$offset = 0;
}
/*
* Check for sorting override
*/
$option = MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_ORDERBY );
if ( 'default' != $option ) {
/*
* Make sure the current orderby choice still exists or revert to default.
*/
$default_orderby = array_merge( array( 'none' => array('none',false) ), MLAQuery::mla_get_sortable_columns( ) );
$found_current = false;
foreach ($default_orderby as $key => $value ) {
if ( $option == $value[0] ) {
$found_current = true;
break;
}
}
if ( ! $found_current ) {
MLACore::mla_delete_option( MLACoreOptions::MLA_DEFAULT_ORDERBY );
$option = MLACore::mla_get_option( MLACoreOptions::MLA_DEFAULT_ORDERBY );
}
$query['orderby'] = $option;
}
$option = MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_ORDER );
if ( 'default' != $option ) {
$query['order'] = $option;
}
$query['post_type'] = 'attachment';
if ( empty( $query['status'] ) ) {
$query['post_status'] = 'inherit';
if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) ) {
$query['post_status'] .= ',private';
}
}
$query = apply_filters( 'mla_media_modal_query_filtered_terms', $query, $raw_query );
$query = MLAQuery::mla_query_media_modal_items( $query, $offset, $count );
$posts = array_map( 'wp_prepare_attachment_for_js', $query->posts );
$posts = array_filter( $posts );
wp_send_json_success( $posts );
}
} //Class MLAModal_Ajax
?>

View File

@@ -0,0 +1,674 @@
<?php
/**
* Media Library Assistant Media Manager enhancements
*
* @package Media Library Assistant
* @since 1.20
*/
/**
* Class MLA (Media Library Assistant) Modal contains enhancements for the WordPress 3.5+ Media Manager
*
* @package Media Library Assistant
* @since 1.20
*/
class MLAModal {
/**
* Slug for localizing and enqueueing CSS - Add Media and related dialogs
*
* @since 1.20
*
* @var string
*/
const JAVASCRIPT_MEDIA_MODAL_STYLES = 'mla-media-modal-style';
/**
* Slug for enqueueing JavaScript - Define ajaxurl if required
*
* @since 2.79
*
* @var string
*/
const JAVASCRIPT_DEFINE_AJAXURL_SLUG = 'mla-define-ajaxurl-scripts';
/**
* Slug for localizing and enqueueing JavaScript - Add Media and related dialogs
*
* @since 1.20
*
* @var string
*/
const JAVASCRIPT_MEDIA_MODAL_SLUG = 'mla-media-modal-scripts';
/**
* Object name for localizing JavaScript - Add Media and related dialogs
*
* @since 1.20
*
* @var string
*/
const JAVASCRIPT_MEDIA_MODAL_OBJECT = 'mla_media_modal_vars';
/**
* Object name for localizing JavaScript - Terms Search popup
*
* @since 1.90
*
* @var string
*/
const JAVASCRIPT_TERMS_SEARCH_OBJECT = 'mla_terms_search_vars';
/**
* Initialization function, similar to __construct()
*
* @since 1.20
*
* @return void
*/
public static function initialize() {
/*
* WordPress 3.5's Media Manager and 4.0's Media Grid are supported on the server
* by /wp-includes/media.php function wp_enqueue_media(), which contains:
*
* $settings = apply_filters( 'media_view_settings', $settings, $post );
* $strings = apply_filters( 'media_view_strings', $strings, $post );
*
* wp_enqueue_media() then contains a require_once for
* /wp-includes/media-template.php, which contains:
* do_action( 'print_media_templates' );
*
* Finally wp_enqueue_media() contains:
* do_action( 'wp_enqueue_media' );
*/
if ( ( ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TOOLBAR ) ) || ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_GRID_TOOLBAR ) ) ) ) {
add_filter( 'media_view_settings', 'MLAModal::mla_media_view_settings_filter', 10, 2 );
add_filter( 'media_view_strings', 'MLAModal::mla_media_view_strings_filter', 10, 2 );
add_action( 'wp_enqueue_media', 'MLAModal::mla_wp_enqueue_media_action', 10, 0 );
add_filter( 'media_library_months_with_files', 'MLAModal::mla_media_library_months_with_files_filter', 10, 1 );
add_action( 'print_media_templates', 'MLAModal::mla_print_media_templates_action', 10, 0 );
add_action( 'admin_init', 'MLAModal::mla_admin_init_action' );
} // Media Modal support enabled
}
/**
* Allows overriding the list of months displayed in the media library.
*
* Called from /wp-includes/media.php function wp_enqueue_media()
*
* @since 2.66
*
* @param array|null An array of objects with `month` and `year`
* properties, or `null` (or any other non-array value)
* for default behavior.
*
* @return array objects with `month` and `year` properties.
*/
public static function mla_media_library_months_with_files_filter( $months = NULL ) {
global $wpdb;
static $library_months_with_files = NULL;
if ( is_array( $library_months_with_files ) ) {
return $library_months_with_files;
}
$library_months_with_files = $wpdb->get_results( $wpdb->prepare( "
SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
FROM $wpdb->posts
WHERE post_type = %s
ORDER BY post_date DESC
", 'attachment' ) );
return $library_months_with_files;
}
/**
* Display a monthly dropdown for filtering items
*
* Adapted from /wp-admin/includes/class-wp-list-table.php function months_dropdown()
*
* @since 1.20
*
* @return array ( value => label ) pairs
*/
private static function _months_dropdown() {
global $wp_locale;
$months = self::mla_media_library_months_with_files_filter();
$month_count = count( $months );
$month_array = array( '0' => __( 'Show all dates', 'media-library-assistant' ) );
if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
return $month_array;
}
foreach ( $months as $arc_row ) {
if ( 0 == $arc_row->year ) {
continue;
}
$month = zeroise( $arc_row->month, 2 );
$year = $arc_row->year;
$month_array[ esc_attr( $arc_row->year . $month ) ] =
/* translators: 1: month name, 2: 4-digit year */
sprintf( __( '%1$s %2$d', 'media-library-assistant' ), $wp_locale->get_month( $month ), $year );
}
return apply_filters( 'mla_media_modal_months_dropdown', $month_array, 'attachment' );
}
/**
* Extract value and text elements from Dropdown HTML option tags
*
* @since 1.20
*
* @param string HTML markup for taxonomy terms dropdown <select> tag
*
* @return array ( 'class' => $class_array, 'value' => $value_array, 'text' => $text_array )
*/
public static function mla_terms_options( $markup ) {
$match_count = preg_match_all( "#\<option(( class=\"([^\"]+)\" )|( ))value=((\'([^\']+)\')|(\"([^\"]+)\"))([^\>]*)\>([^\<]*)\<.*#", $markup, $matches );
if ( ( $match_count == false ) || ( $match_count == 0 ) ) {
return array( 'class' => array( '' ), 'value' => array( '0' ), 'text' => array( 'Show all terms' ) );
}
$class_array = array();
$value_array = array();
$text_array = array();
foreach ( $matches[11] as $index => $text ) {
$class_array[ $index ] = $matches[3][ $index ];
$value_array[ $index ] = ( ! '' == $matches[6][ $index ] )? $matches[7][ $index ] : $matches[9][ $index ];
$current_version = get_bloginfo( 'version' );
if ( version_compare( $current_version, '3.9', '<' ) && version_compare( $current_version, '3.6', '>=' ) ) {
$text_array[ $index ] = str_replace( '&nbsp;', '-', $text);
} else {
$text_array[ $index ] = $text;
}
} // foreach
return apply_filters( 'mla_media_modal_terms_options', array( 'class' => $class_array, 'value' => $value_array, 'text' => $text_array ) );
}
/**
* Share the settings values between mla_media_view_settings_filter
* and mla_print_media_templates_action
*
* @since 1.20
*
* @var array
*/
private static $mla_media_modal_settings = array(
'screen' => 'modal',
'state' => 'initial',
'comma' => ',',
'ajaxNonce' => '',
'ajaxFillCompatAction' => MLACore::JAVASCRIPT_FILL_COMPAT_ACTION,
'ajaxQueryAttachmentsAction' => MLACore::JAVASCRIPT_QUERY_ATTACHMENTS_ACTION,
'ajaxUpdateCompatAction' => MLACore::JAVASCRIPT_UPDATE_COMPAT_ACTION,
'enableDetailsCategory' => false,
'enableDetailsTag' => false,
'enableMimeTypes' => false,
'enableMonthsDropdown' => false,
'enableSearchBox' => false,
'enableSearchBoxControls' => false,
'enableTermsDropdown' => false,
'enableTermsSearch' => false,
'enableTermsAutofill' => false,
'query' => array( 'initial' => array (
// NULL values replaced by filtered initial values in mla_media_view_settings_filter
'filterMime' => NULL,
'filterMonth' => NULL,
'filterTerm' => NULL,
'searchConnector' => NULL,
'searchFields' => NULL,
'searchValue' => NULL,
'searchClicks' => 0,
) ),
'allMimeTypes' => array(),
'uploadMimeTypes' => array(),
'months' => '',
'termsClass' => array(),
'termsIndent' => '&nbsp;',
'termsTaxonomy' => '',
'termsCustom' => false,
'termsText' => array(),
'termsValue' => array(),
'generateTagButtons' => false,
'generateTagUl' => false,
'removeTerm' => '',
);
/**
* Adds settings values to be passed to the Media Manager in /wp-includes/js/media-views.js.
* Declared public because it is a filter.
*
* @since 1.20
*
* @param array associative array with setting => value pairs
* @param object || NULL current post object, if available
*
* @return array updated $settings array
*/
public static function mla_media_view_settings_filter( $settings, $post ) {
// If we know what screen we're on we can test our enabling options
self::$mla_media_modal_settings['screen'] = 'modal';
if ( function_exists( 'get_current_screen' ) ) {
$screen = get_current_screen();
if ( is_object( $screen) && 'upload' == $screen->base ) {
self::$mla_media_modal_settings['screen'] = 'grid';
}
}
$default_types = MLACore::mla_get_option( MLACoreOptions::MLA_POST_MIME_TYPES, true );
self::$mla_media_modal_settings['comma'] = _x( ',', 'tag_delimiter', 'media-library-assistant' );
self::$mla_media_modal_settings['ajaxNonce'] = wp_create_nonce( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME );
self::$mla_media_modal_settings['allMimeTypes'] = MLAMime::mla_pluck_table_views();
self::$mla_media_modal_settings['allMimeTypes']['detached'] = $default_types['detached']['plural'];
self::$mla_media_modal_settings['allMimeTypes']['attached'] = $default_types['attached']['plural'];
// Trash items are allowed in the Media/Library Grid view
if ( EMPTY_TRASH_DAYS && MEDIA_TRASH ) {
self::$mla_media_modal_settings['allMimeTypes']['trash'] = $default_types['trash']['plural'];
}
self::$mla_media_modal_settings['months'] = self::_months_dropdown('attachment');
self::$mla_media_modal_settings['termsTaxonomy'] = MLACore::mla_taxonomy_support('', 'filter');
$terms_options = self::mla_terms_options( MLA_List_Table::mla_get_taxonomy_filter_dropdown() );
self::$mla_media_modal_settings['termsCustom'] = ( MLACoreOptions::MLA_FILTER_METAKEY == self::$mla_media_modal_settings['termsTaxonomy'] );
self::$mla_media_modal_settings['termsClass'] = $terms_options['class'];
self::$mla_media_modal_settings['termsValue'] = $terms_options['value'];
self::$mla_media_modal_settings['termsText'] = $terms_options['text'];
$current_version = get_bloginfo( 'version' );
if ( version_compare( $current_version, '3.9', '<' ) && version_compare( $current_version, '3.6', '>=' ) ) {
self::$mla_media_modal_settings['termsIndent'] = '-';
}
if ( version_compare( $current_version, '4.6.99', '>' ) ) {
self::$mla_media_modal_settings['generateTagButtons'] = true;
self::$mla_media_modal_settings['removeTerm'] = __( 'Remove term', 'media-library-assistant' );
}
if ( version_compare( $current_version, '4.8.99', '>' ) ) {
self::$mla_media_modal_settings['generateTagUl'] = true;
}
self::$mla_media_modal_settings['enableMediaGrid'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_GRID_TOOLBAR ) );
self::$mla_media_modal_settings['enableMediaModal'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TOOLBAR ) );
self::$mla_media_modal_settings['enableDetailsCategory'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) );
self::$mla_media_modal_settings['enableDetailsTag'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_TAG_METABOX ) );
self::$mla_media_modal_settings['enableMimeTypes'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_MIMETYPES ) );
self::$mla_media_modal_settings['enableMonthsDropdown'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_MONTHS ) );
self::$mla_media_modal_settings['enableSearchBox'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_SEARCHBOX ) );
self::$mla_media_modal_settings['enableSearchBoxControls'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_SEARCHBOX_CONTROLS ) );
$supported_taxonomies = MLACore::mla_supported_taxonomies('support');
self::$mla_media_modal_settings['enableTermsDropdown'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TERMS ) ) && ( ! empty( $supported_taxonomies ) );
self::$mla_media_modal_settings['enableTermsAutofill'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_AUTOFILL ) ) && ( ! empty( $supported_taxonomies ) );
$supported_taxonomies = MLACore::mla_supported_taxonomies('term-search');
self::$mla_media_modal_settings['enableTermsSearch'] = ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TERMS_SEARCH ) ) && ( ! empty( $supported_taxonomies ) );
// Compile a list of the enhanced taxonomies
self::$mla_media_modal_settings['enhancedTaxonomies'] = array();
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( MLACore::mla_taxonomy_support( $key ) ) {
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
/*
* Make sure the appropriate MMMW Enhancement option has been checked
*/
if ( $use_checklist ) {
if ( 'checked' === MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) ) {
self::$mla_media_modal_settings['enhancedTaxonomies'][] = $key;
}
} else {
if ( 'checked' === MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_TAG_METABOX ) ) {
self::$mla_media_modal_settings['enhancedTaxonomies'][] = $key;
}
}
} // taxonomy_support
} // each taxonomy
// Set and filter the initial values for toolbar controls
$search_defaults = MLACore::mla_get_option( MLACoreOptions::MLA_SEARCH_MEDIA_FILTER_DEFAULTS );
$initial_values = array(
'filterMime' => 'all',
'filterUploaded' => 'all',
'filterMonth' => 0,
'filterTerm' => self::$mla_media_modal_settings['termsCustom'] ? MLACoreOptions::ALL_MLA_FILTER_METAKEY : 0,
'searchConnector' => $search_defaults['search_connector'],
'searchFields' => $search_defaults['search_fields'],
'searchValue' => '',
//'termsSearch' => ''
);
$initial_values = apply_filters( 'mla_media_modal_initial_filters', $initial_values, $post );
// No supported taxonomies implies no "terms" search
$supported_taxonomies = MLACore::mla_supported_taxonomies('support');
if ( empty( $supported_taxonomies ) ) {
$index = array_search( 'terms', $initial_values['searchFields'] );
if ( false !== $index ) {
unset( $initial_values['searchFields'][ $index ] );
}
}
/*
* Except for filterMime/post_mime_type, these will be passed
* back to the server in the query['s'] field.
*/
self::$mla_media_modal_settings['query']['initial']['filterMime'] = $initial_values['filterMime']; // post_mime_type 'image'; //
self::$mla_media_modal_settings['query']['initial']['filterUploaded'] = $initial_values['filterUploaded']; // post_mime_type 'image'; //
self::$mla_media_modal_settings['query']['initial']['filterMonth'] = $initial_values['filterMonth']; // mla_filter_month '201404'; //
self::$mla_media_modal_settings['query']['initial']['filterTerm'] = $initial_values['filterTerm']; // mla_filter_term '175'; //
self::$mla_media_modal_settings['query']['initial']['searchConnector'] = $initial_values['searchConnector']; // mla_search_connector 'OR'; //
self::$mla_media_modal_settings['query']['initial']['searchFields'] = $initial_values['searchFields']; // mla_search_fields array( 'excerpt', 'title', 'content' ); //
self::$mla_media_modal_settings['query']['initial']['searchValue'] = $initial_values['searchValue']; // mla_search_value 'col'; //
//self::$mla_media_modal_settings['query']['initial']['termsSearch'] = $initial_values['termsSearch']; // mla_terms_search
self::$mla_media_modal_settings['query']['initial']['searchClicks'] = 0; // mla_search_clicks, to force transmission
$settings = array_merge( $settings, array( 'mla_settings' => self::$mla_media_modal_settings ) );
return apply_filters( 'mla_media_modal_settings', $settings, $post );
} // mla_mla_media_view_settings_filter
/**
* Adds string values to be passed to the Media Manager in /wp-includes/js/media-views.js.
* Declared public because it is a filter.
*
* @since 1.20
*
* @param array associative array with string => value pairs
* @param object || NULL current post object, if available
*
* @return array updated $strings array
*/
public static function mla_media_view_strings_filter( $strings, $post ) {
$mla_strings = array(
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
'searchBoxPlaceholder' => __( 'Search Box', 'media-library-assistant' ),
'loadingText' => __( 'Loading...', 'media-library-assistant' ),
'searchBoxControlsStyle' => ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_SEARCHBOX_CONTROLS ) ) ? 'display: inline;' : 'display: none;',
);
$strings = array_merge( $strings, array( 'mla_strings' => $mla_strings ) );
return apply_filters( 'mla_media_modal_strings', $strings, $post );
} // mla_mla_media_view_strings_filter
/**
* Enqueues the mla-media-modal-scripts.js file, adding it to the Media Manager scripts.
* Declared public because it is an action.
*
* @since 1.20
*
* @return void
*/
public static function mla_wp_enqueue_media_action( ) {
global $wp_locale;
// If we know what screen we're on we can test our enabling options
if ( function_exists( 'get_current_screen' ) ) {
$screen = get_current_screen();
if ( is_object( $screen ) ) {
if ( 'upload' == $screen->base ) {
if ( 'checked' != MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_GRID_TOOLBAR ) ) {
return;
}
} elseif ( 'checked' != MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TOOLBAR ) ) {
return;
}
}
}
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
if ( $wp_locale->is_rtl() ) {
wp_register_style( self::JAVASCRIPT_MEDIA_MODAL_STYLES, MLA_PLUGIN_URL . 'css/mla-media-modal-style-rtl.css', false, MLACore::CURRENT_MLA_VERSION );
} else {
wp_register_style( self::JAVASCRIPT_MEDIA_MODAL_STYLES, MLA_PLUGIN_URL . 'css/mla-media-modal-style.css', false, MLACore::CURRENT_MLA_VERSION );
}
wp_enqueue_style( self::JAVASCRIPT_MEDIA_MODAL_STYLES );
// Make sure ajaxurl is defined before loading wp-lists and suggest
wp_enqueue_script( self::JAVASCRIPT_DEFINE_AJAXURL_SLUG, MLA_PLUGIN_URL . "js/mla-define-ajaxurl-scripts{$suffix}.js", array(), MLACore::CURRENT_MLA_VERSION, false );
// Gutenberg Block Editor won't tolerate loading 'wp-lists' in the header section; load in footer section
if ( ! function_exists( 'use_block_editor_for_post_type' ) || isset( $_GET['classic-editor'] ) ) {
wp_enqueue_script( self::JAVASCRIPT_MEDIA_MODAL_SLUG, MLA_PLUGIN_URL . "js/mla-media-modal-scripts{$suffix}.js", array( 'media-views', 'wp-lists', 'suggest' ), MLACore::CURRENT_MLA_VERSION, false );
} else {
wp_enqueue_script( self::JAVASCRIPT_MEDIA_MODAL_SLUG, MLA_PLUGIN_URL . "js/mla-media-modal-scripts{$suffix}.js", array( 'media-views', 'wp-lists', 'suggest' ), MLACore::CURRENT_MLA_VERSION, true );
}
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TERMS_SEARCH ) ) {
MLAModal::mla_add_terms_search_scripts();
}
} // mla_wp_enqueue_media_action
/**
* Prints the templates used in the MLA Media Manager enhancements.
* Declared public because it is an action.
*
* @since 1.20
*
* @return void echoes HTML script tags for the templates
*/
public static function mla_print_media_templates_action( ) {
// If we know what screen we're on we can test our enabling options
if ( function_exists( 'get_current_screen' ) ) {
$screen = get_current_screen();
if ( is_object( $screen ) ) {
if ( 'upload' == $screen->base ) {
if ( 'checked' != MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_GRID_TOOLBAR ) ) {
return;
}
} elseif ( 'checked' != MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_TOOLBAR ) ) {
return;
}
}
} else {
$screen = NULL;
}
// Include mla javascript templates
$template_path = apply_filters( 'mla_media_modal_template_path', MLA_PLUGIN_PATH . 'includes/mla-media-modal-js-template.php', $screen);
if ( ! empty( $template_path ) ) {
require_once $template_path;
}
} // mla_print_media_templates_action
/**
* Clean up the 'save-attachment-compat' values, removing taxonomy updates MLA already handled
*
* @since 1.20
*
* @return void
*/
public static function mla_admin_init_action() {
/*
* Build a list of enhanced taxonomies for later $_REQUEST/$_POST cleansing.
* Remove "Media Categories" instances, if present.
*/
$enhanced_taxonomies = array();
foreach ( get_taxonomies( array ( 'show_ui' => true ), 'objects' ) as $key => $value ) {
if ( MLACore::mla_taxonomy_support( $key ) ) {
if ( ! $use_checklist = $value->hierarchical ) {
$use_checklist = MLACore::mla_taxonomy_support( $key, 'flat-checklist' );
}
if ( $use_checklist ) {
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_MEDIA_MODAL_DETAILS_CATEGORY_METABOX ) ) {
$enhanced_taxonomies[] = $key;
if ( class_exists( 'Media_Categories' ) && is_array( Media_Categories::$instances ) ) {
foreach( Media_Categories::$instances as $index => $instance ) {
if ( $instance->taxonomy == $key ) {
// unset( Media_Categories::$instances[ $index ] );
Media_Categories::$instances[ $index ]->taxonomy = 'MLA-has-disabled-this-instance';
}
}
} // class_exists
} // checked
} // use_checklist
} // supported
} // foreach taxonomy
} // mla_admin_init_action
/**
* Add the styles and scripts for the "Search Terms" popup modal window,
* but only once per page load
*
* @since 1.90
*
* @return void
*/
public static function mla_add_terms_search_scripts() {
global $wp_locale;
static $add_the_scripts = true;
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
if ( $add_the_scripts ) {
if ( $wp_locale->is_rtl() ) {
wp_register_style( MLACore::STYLESHEET_SLUG . '-terms-search', MLA_PLUGIN_URL . 'css/mla-style-terms-search-rtl.css', false, MLACore::CURRENT_MLA_VERSION );
} else {
wp_register_style( MLACore::STYLESHEET_SLUG . '-terms-search', MLA_PLUGIN_URL . 'css/mla-style-terms-search.css', false, MLACore::CURRENT_MLA_VERSION );
}
wp_enqueue_style( MLACore::STYLESHEET_SLUG . '-terms-search' );
wp_enqueue_script( MLACore::JAVASCRIPT_INLINE_EDIT_SLUG . '-terms-search', MLA_PLUGIN_URL . "js/mla-terms-search-scripts{$suffix}.js",
array( 'jquery' ), MLACore::CURRENT_MLA_VERSION, false );
$script_variables = array(
'useDashicons' => false,
'useSpinnerClass' => false,
);
if ( version_compare( get_bloginfo( 'version' ), '3.8', '>=' ) ) {
$script_variables['useDashicons'] = true;
}
if ( version_compare( get_bloginfo( 'version' ), '4.2', '>=' ) ) {
$script_variables['useSpinnerClass'] = true;
}
wp_localize_script( MLACore::JAVASCRIPT_INLINE_EDIT_SLUG . '-terms-search', self::JAVASCRIPT_TERMS_SEARCH_OBJECT, $script_variables );
/*
* Insert the hidden form for the Search Terms popup window
*/
MLAModal::mla_add_terms_search_form();
$add_the_scripts = false;
}
}
/**
* Add the hidden form for the "Search Terms" popup modal window,
* but only once per page load
*
* @since 1.90
*
* @return void
*/
public static function mla_add_terms_search_form() {
static $add_the_form = true;
if ( $add_the_form ) {
add_action( 'admin_footer', 'MLAModal::mla_echo_terms_search_form' );
$add_the_form = false;
}
}
/**
* Echo the hidden form for the "Search Terms" popup modal window
*
* @since 1.90
*
* @return void Echos the HTML <form> markup for hidden form
*/
public static function mla_echo_terms_search_form() {
echo MLAModal::mla_terms_search_form();
}
/**
* Build the hidden form for the "Search Terms" popup modal window
*
* @since 1.90
*
* @return string HTML <form> markup for hidden form
*/
public static function mla_terms_search_form() {
$page_template_array = MLACore::mla_load_template( 'admin-terms-search-form.tpl' );
if ( ! is_array( $page_template_array ) ) {
/* translators: 1: ERROR tag 2: function name 3: non-array value */
MLACore::mla_debug_add( sprintf( _x( '%1$s: %2$s non-array "%3$s"', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), 'MLA::_build_terms_search_form', var_export( $page_template_array, true ) ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return '';
}
$taxonomies = array();
foreach( get_object_taxonomies( 'attachment', 'objects' ) as $taxonomy ) {
if ( MLACore::mla_taxonomy_support( $taxonomy->name, 'support' ) ) {
$taxonomies[] = $taxonomy;
}
}
if( empty( $taxonomies ) ) {
$page_values = array(
'Search Terms' => __( 'Search Terms', 'media-library-assistant' ),
'message' => __( 'There are no taxonomies to search', 'media-library-assistant' ),
);
$terms_search_tpl = MLAData::mla_parse_template( $page_template_array['mla-terms-search-empty-div'], $page_values );
} else {
$taxonomy_list = '';
foreach ( $taxonomies as $taxonomy ) {
$page_values = array(
'taxonomy_checked' => MLACore::mla_taxonomy_support( $taxonomy->name, 'term-search' ) ? 'checked="checked"' : '',
'taxonomy_slug' => $taxonomy->name,
'taxonomy_label' => esc_attr( $taxonomy->label ),
);
$taxonomy_list .= MLAData::mla_parse_template( $page_template_array['mla-terms-search-taxonomy'], $page_values );
}
$page_values = array(
'Search Terms' => __( 'Search Terms', 'media-library-assistant' ),
'Search' => __( 'Search', 'media-library-assistant' ),
'phrases_and_checked' => 'checked="checked"',
'All phrases' => __( 'All phrases', 'media-library-assistant' ),
'phrases_or_checked' => '',
'Any phrase' => __( 'Any phrase', 'media-library-assistant' ),
'terms_and_checked' => '',
'All terms' => __( 'All terms', 'media-library-assistant' ),
'terms_or_checked' => 'checked="checked"',
'Any term' => __( 'Any term', 'media-library-assistant' ),
'exact_checked' => '',
'Exact' => __( 'Exact', 'media-library-assistant' ),
'mla_terms_search_taxonomies' => $taxonomy_list,
);
$terms_search_tpl = MLAData::mla_parse_template( $page_template_array['mla-terms-search-div'], $page_values );
}
$page_values = array(
'mla_terms_search_url' => esc_url( add_query_arg( array_merge( MLA_List_Table::mla_submenu_arguments( false ), array( 'page' => MLACore::ADMIN_PAGE_SLUG ) ), admin_url( 'upload.php' ) ) ),
'mla_terms_search_action' => MLACore::MLA_ADMIN_TERMS_SEARCH,
'wpnonce' => wp_nonce_field( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME, true, false ),
'mla_terms_search_div' => $terms_search_tpl,
);
$terms_search_tpl = MLAData::mla_parse_template( $page_template_array['mla-terms-search-form'], $page_values );
return $terms_search_tpl;
}
} //Class MLAModal
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,401 @@
<?php
/**
* Media Library Assistant Custom Taxonomy and Widget objects
*
* @package Media Library Assistant
* @since 0.1
*/
/**
* Class MLA (Media Library Assistant) Objects defines and manages custom taxonomies for Attachment Categories and Tags
*
* @package Media Library Assistant
* @since 0.20
*/
class MLAObjects {
/**
* Initialization function, similar to __construct()
*
* @since 0.20
*
* @return void
*/
public static function initialize() {
self::_add_taxonomy_support();
}
/**
* Registers Attachment Categories and Attachment Tags custom taxonomies
*
* @since 2.61
*
* @return void
*/
public static function mla_build_taxonomies( ) {
if ( MLACore::mla_taxonomy_support('attachment_category') ) {
$object_type = apply_filters( 'mla_attachment_category_types', array(
'attachment',
) );
$labels = apply_filters( 'mla_attachment_category_labels', array(
'name' => _x( 'Att. Categories', 'taxonomy_name_plural', 'media-library-assistant' ),
'singular_name' => _x( 'Att. Category', 'taxonomy_name_singular', 'media-library-assistant' ),
'search_items' => __( 'Search Att. Categories', 'media-library-assistant' ),
'all_items' => __( 'All Att. Categories', 'media-library-assistant' ),
'parent_item' => __( 'Parent Att. Category', 'media-library-assistant' ),
'parent_item_colon' => __( 'Parent Att. Category', 'media-library-assistant' ) . ':',
'edit_item' => __( 'Edit Att. Category', 'media-library-assistant' ),
'update_item' => __( 'Update Att. Category', 'media-library-assistant' ),
/* translators: %s: add new taxonomy label */
'add_new_item' => sprintf( __( 'Add New %1$s', 'media-library-assistant' ), __( 'Att. Category', 'media-library-assistant' ) ),
'new_item_name' => __( 'New Att. Category Name', 'media-library-assistant' ),
'menu_name' => __( 'Att. Category', 'media-library-assistant' )
) );
$args = apply_filters( 'mla_attachment_category_arguments', array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => true,
'update_count_callback' => '_update_generic_term_count'
) );
register_taxonomy( 'attachment_category', $object_type, $args );
}
if ( MLACore::mla_taxonomy_support('attachment_tag') ) {
$object_type = apply_filters( 'mla_attachment_tag_types', array(
'attachment'
) );
$labels = apply_filters( 'mla_attachment_tag_labels', array(
'name' => _x( 'Att. Tags', 'taxonomy_name_plural', 'media-library-assistant' ),
'singular_name' => _x( 'Att. Tag', 'taxonomy_name_singular', 'media-library-assistant' ),
'search_items' => __( 'Search Att. Tags', 'media-library-assistant' ),
'all_items' => __( 'All Att. Tags', 'media-library-assistant' ),
'parent_item' => __( 'Parent Att. Tag', 'media-library-assistant' ),
'parent_item_colon' => __( 'Parent Att. Tag', 'media-library-assistant' ) . ':',
'edit_item' => __( 'Edit Att. Tag', 'media-library-assistant' ),
'update_item' => __( 'Update Att. Tag', 'media-library-assistant' ),
/* translators: %s: add new taxonomy label */
'add_new_item' => sprintf( __( 'Add New %1$s', 'media-library-assistant' ), __( 'Att. Tag', 'media-library-assistant' ) ),
'new_item_name' => __( 'New Att. Tag Name', 'media-library-assistant' ),
'menu_name' => __( 'Att. Tag', 'media-library-assistant' )
) );
$args = apply_filters( 'mla_attachment_tag_arguments', array(
'hierarchical' => false,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => true,
'update_count_callback' => '_update_generic_term_count'
) );
register_taxonomy( 'attachment_tag', $object_type, $args );
}
} // mla_build_taxonomies
/**
* Adds taxonomy-related filters for MLA-supported taxonomies
*
* @since 2.61
*
* @return void
*/
private static function _add_taxonomy_support( ) {
MLACore::mla_initialize_tax_checked_on_top();
$taxonomies = get_taxonomies( array ( 'show_ui' => true ), 'names' );
foreach ( $taxonomies as $tax_name ) {
if ( MLACore::mla_taxonomy_support( $tax_name ) ) {
register_taxonomy_for_object_type( $tax_name, 'attachment');
add_filter( "manage_edit-{$tax_name}_columns", 'MLAObjects::mla_taxonomy_get_columns_filter', 0x7FFFFFFF, 1 );
add_filter( "manage_{$tax_name}_custom_column", 'MLAObjects::mla_taxonomy_column_filter', 0x7FFFFFFF, 3 );
} // taxonomy support
} // foreach
} // _add_taxonomy_support
/**
* WordPress Filter for edit taxonomy "Attachments" column,
* which replaces the "Posts" column with an equivalent "Attachments" column.
*
* @since 0.30
*
* @param array column definitions for the edit taxonomy list table
*
* @return array updated column definitions for the edit taxonomy list table
*/
public static function mla_taxonomy_get_columns_filter( $columns ) {
// Adding or inline-editing a tag is done with AJAX, and there's no current screen object
if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'add-tag', 'inline-save-tax' ) ) ) {
$post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
$taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
} else {
$screen = get_current_screen();
$post_type = !empty( $screen->post_type ) ? $screen->post_type : 'post';
$taxonomy = !empty( $screen->taxonomy ) ? $screen->taxonomy : 'post_tag';
}
if ( 'attachment' == $post_type ) {
$filter_columns = apply_filters( 'mla_taxonomy_get_columns', NULL, $columns, $taxonomy );
if ( ! empty( $filter_columns ) ) {
return $filter_columns;
}
if ( isset ( $columns[ 'posts' ] ) ) {
$wp_taxonomy = true; // in_array( $taxonomy, array( 'category', 'post_tag' ) );
if ( ! ( $wp_taxonomy && ( 'checked' === MLACore::mla_get_option( MLACoreOptions::MLA_SHOW_COUNT_COLUMN ) ) ) ) {
unset( $columns[ 'posts' ] );
}
}
$columns[ 'attachments' ] = __( 'Attachments', 'media-library-assistant' );
}
return $columns;
}
/**
* WordPress Filter for edit taxonomy "Attachments" column,
* which returns a count of the attachments assigned a given term
*
* @since 0.30
*
* @param string current column value; filled in by earlier filter handlers
* @param string name of the column
* @param integer ID of the term for which the count is desired
*
* @return array HTML markup for the column content; number of attachments in the category
* and alink to retrieve a list of them
*/
public static function mla_taxonomy_column_filter( $current_value, $column_name, $term_id ) {
static $taxonomy = NULL, $tax_object = NULL, $count_terms = false, $terms = array();
// Do setup tasks once per page load
if ( NULL == $taxonomy ) {
// Adding or inline-editing a tag is done with AJAX, and there's no current screen object
if ( defined('DOING_AJAX') && DOING_AJAX ) {
$taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
} else {
$screen = get_current_screen();
$taxonomy = !empty( $screen->taxonomy ) ? $screen->taxonomy : 'post_tag';
}
}
$filter_content = apply_filters( 'mla_taxonomy_column', NULL, $current_value, $column_name, $term_id, $taxonomy );
if ( ! empty( $filter_content ) ) {
return $filter_content;
}
if ( 'attachments' !== $column_name ) {
return $current_value;
}
// Do setup tasks once per page load
if ( NULL == $tax_object ) {
// Adding or inline-editing a tag is done with AJAX, and there's no current screen object
if ( defined('DOING_AJAX') && DOING_AJAX ) {
$taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
} else {
$screen = get_current_screen();
$taxonomy = !empty( $screen->taxonomy ) ? $screen->taxonomy : 'post_tag';
}
$tax_object = get_taxonomy( $taxonomy );
$count_terms = 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_COUNT_TERM_ATTACHMENTS );
if ( $count_terms ) {
$terms = get_transient( MLA_OPTION_PREFIX . 't_term_counts_' . $taxonomy );
if ( ! is_array( $terms ) ) {
// The MLAShortcodes class is only loaded when needed.
if ( !class_exists( 'MLAShortcodes' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
}
$cloud = MLAShortcodes::mla_get_terms( array(
'taxonomy' => $taxonomy,
'fields' => 't.term_id, tt.term_taxonomy_id, t.name, t.slug, COUNT(p.ID) AS `count`',
'number' => 0,
'no_orderby' => true
) );
unset( $cloud['found_rows'] );
foreach( $cloud as $term ) {
$terms[ $term->term_id ] = $term;
}
set_transient( MLA_OPTION_PREFIX . 't_term_counts_' . $taxonomy, $terms, 300 ); // five minutes
}// build the array
} // set $terms
} // setup tasks
if ( isset( $terms[ $term_id ] ) ) {
$term = $terms[ $term_id ];
$column_text = number_format_i18n( $term->count );
} else {
// Cache miss, e.g., WPML/Polylang language has changed
$term = get_term( $term_id, $taxonomy );
if ( is_wp_error( $term ) ) {
/* translators: 1: ERROR tag 2: taxonomy 3: error message */
MLACore::mla_debug_add( sprintf( _x( '%1$s: mla_taxonomy_column_filter( "%2$s" ) - get_term failed: "%3$s"', 'error_log', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $taxonomy, $term->get_error_message() ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return 0;
} elseif ( $count_terms ) {
// Default to zero, then try to find a real count
$column_text = number_format_i18n( 0 );
// The MLAShortcodes class is only loaded when needed.
if ( !class_exists( 'MLAShortcodes' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
}
$cloud = MLAShortcodes::mla_get_terms( array(
'taxonomy' => $taxonomy,
'include' => $term->term_id,
'fields' => 't.term_id, tt.term_taxonomy_id, t.name, t.slug, COUNT(p.ID) AS `count`',
'number' => 0,
'no_orderby' => true
) );
unset( $cloud['found_rows'] );
foreach( $cloud as $term ) {
$column_text = number_format_i18n( $term->count );
}
} else {
$column_text = __( 'click to search', 'media-library-assistant' );
}
}
$filter_content = apply_filters( 'mla_taxonomy_column_final', NULL, $tax_object, $term, $column_text, $count_terms );
if ( ! empty( $filter_content ) ) {
return $filter_content;
}
return sprintf( '<a href="%1$s">%2$s</a>', esc_url( add_query_arg(
array( 'page' => MLACore::ADMIN_PAGE_SLUG, 'mla-tax' => $taxonomy, 'mla-term' => $term->slug, 'heading_suffix' => urlencode( $tax_object->label . ':' . $term->name ) ), 'upload.php' ) ), $column_text );
}
} //Class MLAObjects
/**
* Class MLA (Media Library Assistant) Text Widget defines a shortcode-enabled version of the WordPress Text widget
*
* @package Media Library Assistant
* @since 1.60
*/
class MLATextWidget extends WP_Widget {
/**
* Calls the parent constructor to set some defaults.
*
* @since 1.60
*
* @return void
*/
function __construct() {
$widget_args = array(
'classname' => 'mla_text_widget',
'description' => __( 'Shortcode(s), HTML and/or Plain Text', 'media-library-assistant' )
);
$control_args = array(
'width' => 400,
'height' => 350
);
parent::__construct( 'mla-text-widget', __( 'MLA Text', 'media-library-assistant' ), $widget_args, $control_args );
}
/**
* Display the widget content - called from the WordPress "front end"
*
* @since 1.60
*
* @param array Widget arguments
* @param array Widget definition, from the database
*
* @return void Echoes widget output
*/
function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
$text = do_shortcode( apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance ) );
echo $args['before_widget'];
if ( !empty( $title ) ) { echo $args['before_title'] . $title . $args['after_title']; } ?>
<?php if ( !empty( $instance['textwidget_div'] ) ) echo '<div class="textwidget">';
echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text;
if ( !empty( $instance['textwidget_div'] ) ) echo '</div>'; ?>
<?php
echo $args['after_widget'];
}
/**
* Echo the "edit widget" form on the Appearance/Widgets admin screen
*
* @since 1.60
*
* @param array Previous definition values, from the database
*
* @return void Echoes "edit widget" form
*/
function form( $instance ) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) );
$title = strip_tags( $instance['title'] );
$text = esc_textarea( $instance['text'] );
?>
<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php echo __( 'Title', 'media-library-assistant' ) . ':'; ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p>
<textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id( 'text' ); ?>" name="<?php echo $this->get_field_name( 'text' ); ?>"><?php echo $text; ?></textarea>
<p><input id="<?php echo $this->get_field_id( 'filter' ); ?>" name="<?php echo $this->get_field_name( 'filter' ); ?>" type="checkbox" <?php checked( isset( $instance['filter'] ) ? $instance['filter'] : 0 ); ?> />&nbsp;<label for="<?php echo $this->get_field_id( 'filter' ); ?>"><?php _e( 'Automatically add paragraphs', 'media-library-assistant' ); ?></label></p>
<p><input id="<?php echo $this->get_field_id( 'textwidget_div' ); ?>" name="<?php echo $this->get_field_name( 'textwidget_div' ); ?>" type="checkbox" <?php checked( isset( $instance['textwidget_div'] ) ? $instance['textwidget_div'] : 1 ); ?> />&nbsp;<label for="<?php echo $this->get_field_id( 'textwidget_div' ); ?>"><?php _e( 'Add .textwidget div tags', 'media-library-assistant' ); ?></label></p>
<?php
}
/**
* Sanitize widget definition as it is saved to the database
*
* @since 1.60
*
* @param array Current definition values, to be saved in the database
* @param array Previous definition values, from the database
*
* @return array Updated definition values to be saved in the database
*/
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
if ( current_user_can( 'unfiltered_html' ) ) {
$instance['text'] = $new_instance['text'];
} else {
$instance['text'] = stripslashes( wp_filter_post_kses( addslashes( $new_instance['text'] ) ) ); // wp_filter_post_kses() expects slashed
}
$instance['filter'] = isset( $new_instance['filter'] );
$instance['textwidget_div'] = isset( $new_instance['textwidget_div'] );
return $instance;
}
/**
* Register the widget with WordPress
*
* Defined as public because it's an action.
*
* @since 1.60
*
* @return void
*/
public static function mla_text_widget_widgets_init_action(){
register_widget( 'MLATextWidget' );
}
} // Class MLATextWidget
/*
* Actions are added here, when the source file is loaded, because the MLATextWidget
* object(s) are created too late to be useful.
*/
add_action( 'widgets_init', 'MLATextWidget::mla_text_widget_widgets_init_action' );
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
<?php
/**
* Media Library Assistant Polylang Shortcode Support classes
*
* This file is conditionally loaded in MLAShortcodes::initialize after a check for Polylang presence.
*
* @package Media Library Assistant
* @since 2.40
*/
/**
* Class MLA (Media Library Assistant) Polylang Shortcdxodes provides front-end support for the
* Polylang Multilingual plugin
*
* @package Media Library Assistant
* @since 2.40
*/
class MLA_Polylang_Shortcodes {
/**
* Polylang version conditional to avoid deprecated functions in v1.8+
*
* @since 2.78
*
* @var boolean
*/
private static $polylang_2dot4_plus = false;
/**
* Initialization function, similar to __construct()
*
* @since 2.40
*
* @return void
*/
public static function initialize() {
self::$polylang_2dot4_plus = version_compare( POLYLANG_VERSION, '2.3.99', '>' );
// Defined in /media-library-assistant/includes/class-mla-shortcode-support.php
add_filter( 'mla_get_terms_query_arguments', 'MLA_Polylang_Shortcodes::mla_get_terms_query_arguments', 10, 1 );
add_filter( 'mla_get_terms_clauses', 'MLA_Polylang_Shortcodes::mla_get_terms_clauses', 10, 1 );
}
/**
* MLA Tag Cloud Query Arguments
*
* Saves [mla_tag_cloud] query parameters for use in MLA_Polylang_Shortcodes::mla_get_terms_clauses.
*
* @since 2.40
* @uses MLA_Polylang_Shortcodes::$all_query_parameters
*
* @param array shortcode arguments merged with attachment selection defaults
*/
public static function mla_get_terms_query_arguments( $all_query_parameters ) {
MLA_Polylang_Shortcodes::$all_query_parameters = $all_query_parameters;
return $all_query_parameters;
} // mla_get_terms_query_arguments
/**
* Save the query arguments
*
* @since 2.40
*
* @var array
*/
private static $all_query_parameters = array();
/**
* MLA Tag Cloud Query Clauses
*
* Adds language-specific clauses to filter the cloud terms.
*
* @since 2.40
* @uses MLA_Polylang_Shortcodes::$all_query_parameters
*
* @param array SQL clauses ( 'fields', 'join', 'where', 'order', 'orderby', 'limits' )
*/
public static function mla_get_terms_clauses( $clauses ) {
global $polylang;
if ( self::$polylang_2dot4_plus ) {
$clauses = $polylang->terms->terms_clauses($clauses, MLA_Polylang_Shortcodes::$all_query_parameters['taxonomy'], MLA_Polylang_Shortcodes::$all_query_parameters );
} else {
// Before v2.4, the Polylang terms_clauses method is in one of two places
if ( is_admin() ) {
$clauses = $polylang->filters_term->terms_clauses($clauses, MLA_Polylang_Shortcodes::$all_query_parameters['taxonomy'], MLA_Polylang_Shortcodes::$all_query_parameters );
} else {
$clauses = $polylang->filters->terms_clauses($clauses, MLA_Polylang_Shortcodes::$all_query_parameters['taxonomy'], MLA_Polylang_Shortcodes::$all_query_parameters );
}
}
return $clauses;
} // mla_get_terms_clauses
} // Class MLA_Polylang_Shortcodes
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,224 @@
<?php
/**
* Media Library Assistant Shortcode interface functions
*
* @package Media Library Assistant
* @since 0.1
*/
/**
* Class MLA (Media Library Assistant) Shortcodes defines the shortcodes available
* to MLA users and loads the support class if the shortcodes are executed.
*
* @package Media Library Assistant
* @since 0.20
*/
class MLAShortcodes {
/**
* Initialization function, similar to __construct()
*
* @since 0.20
*
* @return void
*/
public static function initialize() {
global $sitepress, $polylang;
/*
* Check for WPML/Polylang presence before loading language support class,
* then immediately initialize it since we're already in the "init" action.
*/
if ( is_object( $sitepress ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-wpml-shortcode-support.php' );
MLA_WPML_Shortcodes::initialize();
} elseif ( is_object( $polylang ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-polylang-shortcode-support.php' );
MLA_Polylang_Shortcodes::initialize();
}
add_shortcode( 'mla_gallery', 'MLAShortcodes::mla_gallery_shortcode' );
add_shortcode( 'mla_tag_cloud', 'MLAShortcodes::mla_tag_cloud_shortcode' );
add_shortcode( 'mla_term_list', 'MLAShortcodes::mla_term_list_shortcode' );
/*
* Avoid wptexturize defect
*/
if ( version_compare( get_bloginfo('version'), '4.0', '>=' ) ) {
add_filter( 'no_texturize_shortcodes', 'MLAShortcodes::mla_no_texturize_shortcodes_filter', 10, 1 );
}
}
/**
* Prevents wptexturizing of the [mla_gallery] shortcode, avoiding a bug in WP 4.0.
*
* Defined as public because it's a filter.
*
* @since 1.94
*
* @param array list of "do not texturize" shortcodes
*
* @return array updated list of "do not texturize" shortcodes
*/
public static function mla_no_texturize_shortcodes_filter( $no_texturize_shortcodes ) {
if ( ! in_array( 'mla_gallery', $no_texturize_shortcodes ) ) {
$no_texturize_shortcodes[] = 'mla_gallery';
$no_texturize_shortcodes[] = 'mla_tag_cloud';
}
return $no_texturize_shortcodes;
}
/**
* The MLA Gallery shortcode.
*
* Compatibility shim for MLAShortcode_Support::mla_gallery_shortcode
*
* @since .50
*
* @param array $attr Attributes of the shortcode
* @param string $content Optional content for enclosing shortcodes; used with mla_alt_shortcode
*
* @return string HTML content to display gallery.
*/
public static function mla_gallery_shortcode( $attr, $content = NULL ) {
if ( !class_exists( 'MLAShortcode_Support' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
}
return MLAShortcode_Support::mla_gallery_shortcode( $attr, $content );
}
/**
* The MLA Tag Cloud shortcode.
*
* Compatibility shim for MLAShortcode_Support::mla_tag_cloud_shortcode
*
* @since 1.60
*
* @param array $attr Attributes of the shortcode.
* @param string $content Optional content for enclosing shortcodes
*
* @return string HTML content to display the tag cloud.
*/
public static function mla_tag_cloud_shortcode( $attr, $content = NULL ) {
if ( !class_exists( 'MLAShortcode_Support' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
}
return MLAShortcode_Support::mla_tag_cloud_shortcode( $attr, $content );
}
/**
* The MLA Term List shortcode.
*
* Compatibility shim for MLAShortcode_Support::mla_term_list_shortcode
*
* @since 2.25
*
* @param array $attr Attributes of the shortcode.
* @param string $content Optional content for enclosing shortcodes
*
* @return string HTML content to display the tag cloud.
*/
public static function mla_term_list_shortcode( $attr, $content = NULL ) {
if ( !class_exists( 'MLAShortcode_Support' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
}
return MLAShortcode_Support::mla_term_list_shortcode( $attr, $content );
}
/**
* The WP_Query object used to select items for the gallery.
*
* Defined as a public, static variable so it can be inspected from the
* "mla_gallery_wp_query_object" action. Set to NULL at all other times.
*
* @since 1.51
*
* @var object
*/
public static $mla_gallery_wp_query_object = NULL;
/**
* Parses shortcode parameters and returns the gallery objects
*
* Compatibility shim for MLAShortcode_Support::mla_get_shortcode_attachments
*
* @since .50
*
* @param int Post ID of the parent
* @param array Attributes of the shortcode
* @param boolean true to calculate and return ['found_posts'] as an array element
*
* @return array List of attachments returned from WP_Query
*/
public static function mla_get_shortcode_attachments( $post_parent, $attr, $return_found_rows = NULL ) {
if ( !class_exists( 'MLAShortcode_Support' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
}
return MLAShortcode_Support::mla_get_shortcode_attachments( $post_parent, $attr, $return_found_rows );
}
/**
* Retrieve the terms in one or more taxonomies.
*
* Compatibility shim for MLAShortcode_Support::mla_get_terms
*
* @since 1.60
*
* @param array taxonomies to search and query parameters
*
* @return array array of term objects, empty if none found
*/
public static function mla_get_terms( $attr ) {
if ( !class_exists( 'MLAShortcode_Support' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
}
return MLAShortcode_Support::mla_get_terms( $attr );
}
/**
* Get IPTC/EXIF or custom field mapping data source; front end posts/pages mode
*
* Compatibility shim for MLAData_Source::mla_get_data_source.
*
* @since 1.70
*
* @param integer post->ID of attachment
* @param string category/scope to evaluate against: custom_field_mapping or single_attachment_mapping
* @param array data source specification ( name, *data_source, *keep_existing, *format, mla_column, quick_edit, bulk_edit, *meta_name, *option, no_null )
* @param array (optional) _wp_attachment_metadata, default NULL (use current postmeta database value)
*
* @return string|array data source value
*/
public static function mla_get_data_source( $post_id, $category, $data_value, $attachment_metadata = NULL ) {
if ( !class_exists( 'MLAData_Source' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-source.php' );
}
return MLAData_Source::mla_get_data_source( $post_id, $category, $data_value, $attachment_metadata );
} // mla_get_data_source
/**
* Identify custom field mapping data source; front end posts/pages mode
*
* Compatibility shim for MLAData_Source::mla_is_data_source.
*
* @since 1.80
*
* @param string candidate data source name
*
* @return boolean true if candidate name matches a data source
*/
public static function mla_is_data_source( $candidate_name ) {
if ( !class_exists( 'MLAData_Source' ) ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-source.php' );
}
return MLAData_Source::mla_is_data_source( $candidate_name );
}
} // Class MLAShortcodes
?>

View File

@@ -0,0 +1,710 @@
<?php
/**
* Media Library Assistant Custom Style/Markup Template handler(s).
*
* @package Media Library Assistant
* @since 2.30
*/
/**
* Class MLA (Media Library Assistant) Custom Style/Markup Template Support provides functions that
* define, import and export custom style and markup templates for MLA shortcodes.
*
* @package Media Library Assistant
* @since 2.30
*/
class MLATemplate_Support {
/**
* $mla_template_definitions defines the structure of the style and markup templates
* and the labels, etc. required to render them in the Settings/Shortcodes tab.
*
* The array must be populated at runtime in MLATemplate_Support::mla_localize_template_definitions();
* localization calls cannot be placed in the "public static" array definition itself.
*
* @since 2.30
* @access public
* @var array $mla_template_definitions {
* Definitions by type. Key $$type is 'markup' or 'style'.
*
* @type array $$type {
* Definitions by shortcode. Key $$shortcode_slug is 'gallery', 'tag-cloud' or 'term-list'
*
* @type array $$shortcode_slug {
* Templates by name. Key $$template_name is the template name/slug.
*
* @type string $label Label for the shortcode.
* @type array $default_names Names of the default templates.
* @type array $sections {
* Template section definitions. Key $$section_name is the section name/slug.
*
* @type array $$section_name {
* Definitions by section.
*
* @type string $label Label for the section textbox.
* @type integer $rows Number of rows for the section textbox.
* @type string $help Help text displayed below the textbox.
* @type integer $order Where the section appears in the template.
* }
* }
* }
* }
* }
*/
public static $mla_template_definitions = array ();
/**
* Localize $mla_option_definitions array.
*
* Localization must be done at runtime; these calls cannot be placed in the
* "public static" array definition itself. Called from MLATest::initialize.
*
* @since 2.30
*
* @return null
*/
public static function mla_localize_template_definitions() {
self::$mla_template_definitions = array (
'style' => array(
'gallery' => array(
'label' => _x( 'Gallery', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'default' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'styles' => array(
'label' => __( 'Styles', 'media-library-assistant' ),
'rows' => 10,
'help' => __( 'List of substitution parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 1,
),
),
),
'tag-cloud' => array(
'label' => _x( 'Tag Cloud', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'tag-cloud' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'styles' => array(
'label' => __( 'Styles', 'media-library-assistant' ),
'rows' => 10,
'help' => __( 'List of substitution parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 1,
),
),
),
'term-list' => array(
'label' => _x( 'Term List', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'term-list' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'styles' => array(
'label' => __( 'Styles', 'media-library-assistant' ),
'rows' => 10,
'help' => __( 'List of substitution parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 1,
),
),
),
),
'markup' => array(
'gallery' => array(
'label' => _x( 'Gallery', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'default' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'arguments' => array(
'label' => __( 'Arguments', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Default shortcode parameter values.', 'media-library-assistant' ),
'order' => 2,
),
'row-open' => array(
'label' => __( 'Row', 'media-library-assistant' ) . '&nbsp;' . __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of each row in the gallery.', 'media-library-assistant' ),
'order' => 4,
),
'open' => array(
'label' => __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of the gallery. List of parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 3,
),
'item' => array(
'label' => __( 'Item', 'media-library-assistant' ),
'rows' => 6,
'help' => __( 'Markup for each item/cell of the gallery.', 'media-library-assistant' ),
'order' => 5,
),
'row-close' => array(
'label' => __( 'Row', 'media-library-assistant' ) . '&nbsp;' . __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of each row in the gallery.', 'media-library-assistant' ),
'order' => 9,
),
'close' => array(
'label' => __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of the gallery.', 'media-library-assistant' ),
'order' => 10,
),
),
),
'tag-cloud' => array(
'label' => _x( 'Tag Cloud', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'tag-cloud', 'tag-cloud-ul', 'tag-cloud-dl' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'arguments' => array(
'label' => __( 'Arguments', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Default shortcode parameter values.', 'media-library-assistant' ),
'order' => 2,
),
'row-open' => array(
'label' => __( 'Row', 'media-library-assistant' ) . '&nbsp;' . __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of each row in the cloud; grid format only.', 'media-library-assistant' ),
'order' => 4,
),
'open' => array(
'label' => __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of the cloud. List of parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 3,
),
'item' => array(
'label' => __( 'Item', 'media-library-assistant' ),
'rows' => 6,
'help' => __( 'Markup for each item/cell of the cloud.', 'media-library-assistant' ),
'order' => 5,
),
'row-close' => array(
'label' => __( 'Row', 'media-library-assistant' ) . '&nbsp;' . __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of each row in the cloud; grid format only.', 'media-library-assistant' ),
'order' => 9,
),
'close' => array(
'label' => __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of the cloud.', 'media-library-assistant' ),
'order' => 10,
),
),
),
'term-list' => array(
'label' => _x( 'Term List', 'table_view_singular', 'media_library-assistant' ),
'default_names' => array( 'term-list-ul', 'term-list-dl', 'term-list-dropdown', 'term-list-checklist' ),
'sections' => array(
'description' => array(
'label' => __( 'Description', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Notes for the Shortcodes tab submenu table.', 'media-library-assistant' ),
'order' => 0,
),
'arguments' => array(
'label' => __( 'Arguments', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Default shortcode parameter values.', 'media-library-assistant' ),
'order' => 1,
),
'child-open' => array(
'label' => __( 'Child', 'media-library-assistant' ) . '&nbsp;' . __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of each level in the hierarchy; list format only.', 'media-library-assistant' ),
'order' => 6,
),
'child-item' => array(
'label' => __( 'Child', 'media-library-assistant' ) . '&nbsp;' . __( 'Item', 'media-library-assistant' ),
'rows' => 6,
'help' => __( 'Markup for each lower-level item in the hierarchy; list format only.', 'media-library-assistant' ),
'order' => 7,
),
'child-close' => array(
'label' => __( 'Child', 'media-library-assistant' ) . '&nbsp;' . __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of each level in the hierarchy; list format only.', 'media-library-assistant' ),
'order' => 8,
),
'open' => array(
'label' => __( 'Open', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the beginning of the list. List of parameters, e.g., [+selector+], on Documentation tab.', 'media-library-assistant' ),
'order' => 3,
),
'item' => array(
'label' => __( 'Item', 'media-library-assistant' ),
'rows' => 6,
'help' => __( 'Markup for each item/cell in the list.', 'media-library-assistant' ),
'order' => 5,
),
'close' => array(
'label' => __( 'Close', 'media-library-assistant' ),
'rows' => 3,
'help' => __( 'Markup for the end of the list.', 'media-library-assistant' ),
'order' => 10,
),
),
),
),
);
//error_log( __LINE__ . ' mla_localize_template_definitions MLATemplate_Support::$mla_template_definitions = ' . var_export( MLATemplate_Support::$mla_template_definitions, true ), 0 );
}
/**
* Style and Markup templates.
*
* @since 2.30
* @access private
* @var array $mla_custom_templates {
* Templates by type. Key $$type is 'markup' or 'style'.
*
* @type array $$type {
* Templates by shortcode. Key $$shortcode_slug is 'gallery', 'tag-cloud' or 'term-list'
*
* @type array $$shortcode_slug {
* Templates by name. Key $$template_name is the template name/slug, which must be unique within type.
*
* @type array $$template_name {
* Template content by section. Key $$section_name is the section name/slug.
*
* @type string $$section_name HTML markup/CSS styles for the template section.
* }
* }
* }
* }
*/
private static $mla_custom_templates = NULL;
/**
* Load style and markup templates to $mla_custom_templates.
*
* @since 2.30
*
* @return null
*/
public static function mla_load_custom_templates() {
if ( empty( MLATemplate_Support::$mla_template_definitions ) ) {
MLATemplate_Support::mla_localize_template_definitions();
}
MLATemplate_Support::$mla_custom_templates = NULL;
$default_templates = MLACore::mla_load_template( 'mla-custom-templates.tpl' );
// Load the default templates
if ( is_null( $default_templates ) ) {
MLACore::mla_debug_add( '<strong>mla_debug mla_load_custom_templates()</strong> ' . __( 'error loading tpls/mla-custom-templates.tpl', 'media-library-assistant' ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return;
} elseif ( !$default_templates ) {
MLACore::mla_debug_add( '<strong>mla_debug mla_load_custom_templates()</strong> ' . __( 'tpls/mla-custom-templates.tpl not found', 'media-library-assistant' ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return;
}
// Record explicit shortcode assignments, extract the style template description "section"
$mla_shortcode_slugs = array();
$mla_descriptions = array();
foreach ( $default_templates as $key => $value ) {
$mla_shortcode_slug = NULL;
$mla_description = NULL;
$match_count = preg_match( '#\<!-- mla_shortcode_slug="(.+)" --\>[\r\n]*#', $value, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count == 0 ) {
$match_count = preg_match( '#mla_shortcode_slug="(.+)"[ \r\n]*#', $value, $matches, PREG_OFFSET_CAPTURE );
}
if ( $match_count > 0 ) {
$mla_shortcode_slug = $matches[ 1 ][ 0 ];
$value = substr_replace( $value, '', $matches[ 0 ][ 1 ], strlen( $matches[ 0 ][ 0 ] ) );
}
if ( !empty( $mla_shortcode_slug ) ) {
$tail = strrpos( $key, '-style' );
if ( ! ( false === $tail ) ) {
$mla_shortcode_slugs['style'][ substr( $key, 0, $tail ) ] = $mla_shortcode_slug;
} else {
$tail = strrpos( $key, '-arguments-markup' );
if ( ! ( false === $tail ) ) {
$mla_shortcode_slugs['markup'][ substr( $key, 0, $tail ) ] = $mla_shortcode_slug;
}
}
}
$match_count = preg_match( '#\<!-- mla_description="(.+)" --\>[\r\n]*#', $value, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count > 0 ) {
$mla_description = $matches[ 1 ][ 0 ];
$value = substr_replace( $value, '', $matches[ 0 ][ 1 ], strlen( $matches[ 0 ][ 0 ] ) );
}
if ( empty( $value ) ) {
unset( $default_templates[ $key ] );
} else {
$default_templates[ $key ] = $value;
//error_log( __LINE__ . " replace default template {$key}, {$mla_shortcode_slug}, {$mla_description} value = " . MLAData::mla_hex_dump( $value ), 0 );
}
if ( !empty( $mla_shortcode_slug ) ) {
$tail = strrpos( $key, '-style' );
if ( ! ( false === $tail ) ) {
$mla_shortcode_slugs['style'][ substr( $key, 0, $tail ) ] = $mla_shortcode_slug;
} else {
$tail = strrpos( $key, '-arguments-markup' );
if ( ! ( false === $tail ) ) {
$mla_shortcode_slugs['markup'][ substr( $key, 0, $tail ) ] = $mla_shortcode_slug;
}
}
}
if ( !empty( $mla_description ) ) {
$tail = strrpos( $key, '-style' );
if ( ! ( false === $tail ) ) {
$mla_descriptions['style'][ substr( $key, 0, $tail ) ] = $mla_description;
}
}
}
// Find the shortcode and template type for array indices
foreach ( $default_templates as $key => $value ) {
$tail = strrpos( $key, '-style' );
if ( ! ( false === $tail ) ) {
// If we can't find the shortcode; assume it's ]mla_gallery]
$shortcode = 'gallery';
$name = substr( $key, 0, $tail );
if ( isset( $mla_shortcode_slugs['style'][ $name ] ) ) {
// Assign to the declared shortcode
$shortcode = $mla_shortcode_slugs['style'][ $name ];
} else {
// Guess at the shortcode
foreach( MLATemplate_Support::$mla_template_definitions['style'] as $slug => $definition ) {
if ( isset( $definition['default_names'] ) && in_array( $name, $definition['default_names'] ) ) {
$shortcode = $slug;
break;
}
}
}
if ( isset( $mla_descriptions['style'][ $name ] ) ) {
MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ][ $name ]['description'] = $mla_descriptions['style'][ $name ];
}
MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ][ $name ]['styles'] = $value;
continue;
}
$tail = strrpos( $key, '-markup' );
if ( ! ( false === $tail ) ) {
// If we can't find the shortcode; assume it's mla_gallery
$shortcode = 'gallery';
$name = substr( $key, 0, $tail );
// Look for explicit assignment
foreach( $mla_shortcode_slugs['markup'] as $root_name => $mla_shortcode_slug ) {
$root = strpos( $name, $root_name );
if ( 0 === $root ) {
$section_name = substr( $name, strlen( $root_name ) + 1 );
// Assign to the declared shortcode
MLATemplate_Support::$mla_custom_templates['markup'][ $mla_shortcode_slug ][ $root_name ][ $section_name ] = $value;
$name = NULL;
break;
}
}
if ( $name ) {
// Guess at the shortcode
foreach( MLATemplate_Support::$mla_template_definitions['markup'] as $slug => $definition ) {
if ( isset( $definition['default_names'] ) ) {
foreach( $definition['default_names'] as $default_name ) {
$root = strpos( $name, $default_name );
if ( 0 === $root ) {
foreach( $definition['sections'] as $section_name => $section_value ) {
$tail = strrpos( $name, '-' . $section_name );
if ( ! ( false === $tail ) ) {
$name = substr( $name, 0, $tail );
MLATemplate_Support::$mla_custom_templates['markup'][ $slug ][ $name ][ $section_name ] = $value;
}
}
$name = NULL;
break;
} // matched the default name
} // foreach default name
}
} // foreach shortcode
} // Guess the shortcode
// Can't find the shortcode; assume it's [mla_gallery]
if ( $name ) {
foreach( MLATemplate_Support::$mla_template_definitions['markup']['gallery']['sections'] as $section_name => $section_value ) {
$tail = strrpos( $name, '-' . $section_name );
if ( ! ( false === $tail ) ) {
$name = substr( $name, 0, $tail );
MLATemplate_Support::$mla_custom_templates['markup']['gallery'][ $name ][ $section_name ] = $value;
}
}
}
} // default markup template
} // foreach default template
// Add user-defined Style templates
$templates = MLACore::mla_get_option( 'style_templates' );
if ( is_array( $templates ) ) {
foreach ( $templates as $name => $value ) {
// If we can't find the shortcode; assume it's [mla_gallery]
$shortcode = 'gallery';
// Extract the description "section"
$mla_description = NULL;
$match_count = preg_match( '#\<!-- mla_description="(.+)" --\>[\r\n]*#', $value, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count > 0 ) {
$mla_description = $matches[ 1 ][ 0 ];
$value = substr_replace( $value, '', $matches[ 0 ][ 1 ], strlen( $matches[ 0 ][ 0 ] ) );
}
// Check for explicit shortcode assignment
$match_count = preg_match( '#\<!-- mla_shortcode_slug="(.+)" --\>[\r\n]*#', $value, $matches, PREG_OFFSET_CAPTURE );
if ( $match_count > 0 ) {
$value = substr_replace( $value, '', $matches[ 0 ][ 1 ], strlen( $matches[ 0 ][ 0 ] ) );
$shortcode = $matches[ 1 ][ 0 ];
} else {
// Guess from content
foreach( MLATemplate_Support::$mla_template_definitions['style'] as $slug => $definition ) {
if ( false !== strpos( $value, '.' . $slug ) ) {
$shortcode = $slug;
break;
}
}
}
if ( !empty( $mla_description ) ) {
MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ][ $name ]['description'] = $mla_description;
}
MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ][ $name ]['styles'] = $value;
} // foreach $templates
} // is_array
// Add user-defined Markup templates
$templates = MLACore::mla_get_option( 'markup_templates' );
if ( is_array( $templates ) ) {
foreach ( $templates as $name => $value ) {
// Check for explicit assignment
if ( isset( $value['arguments'] ) ) {
$match_count = preg_match( '#mla_shortcode_slug="(.+)"[ \r\n]*#', $value['arguments'], $matches, PREG_OFFSET_CAPTURE );
} else {
$match_count = 0;
}
if ( $match_count > 0 ) {
$value['arguments'] = substr_replace( $value['arguments'], '', $matches[ 0 ][ 1 ], strlen( $matches[ 0 ][ 0 ] ) );
if ( empty( $value['arguments'] ) ) {
unset( $value['arguments'] );
}
MLATemplate_Support::$mla_custom_templates['markup'][ $matches[ 1 ][ 0 ] ][ $name ] = $value;
continue;
}
// Guess from content
$full_text = ''; // for guessing shortcode name
foreach( $value as $section_name => $section_value ) {
$full_text .= $section_value;
}
foreach( MLATemplate_Support::$mla_template_definitions['markup'] as $slug => $definition ) {
if ( preg_match( '#class=[\'\"]*.*' . $slug . '#', $full_text, $matches ) ) {
MLATemplate_Support::$mla_custom_templates['markup'][ $slug ][ $name ] = $value;
$name = NULL;
break;
}
}
if ( $name ) {
MLATemplate_Support::$mla_custom_templates['markup']['gallery'][ $name ] = $value;
}
} // foreach $templates
} // is_array
//error_log( __LINE__ . ' mla_load_custom_templates MLATemplate_Support::$mla_custom_templates = ' . var_export( MLATemplate_Support::$mla_custom_templates, true ), 0 );
}
/**
* Fetch style or markup template from $mla_templates.
*
* @since 2.30
*
* @param string $key Template name.
* @param string $shortcode Optional. Shortcode slug; 'gallery', 'tag-cloud' or 'term-list'. Default 'gallery'.
* @param string $type Optional. Template type; 'style' or 'markup'. Default 'style'.
* @param string $section Optional. Template section. Default '[not supplied]'.
* @return string Requested template section, if it exists.
* @return boolean false if template section not found,
* true if section='[exists]' and template exists.
* @return null If no templates exist.
*/
public static function mla_fetch_custom_template( $key, $shortcode = 'gallery', $type = 'style', $section = '[not supplied]' ) {
//MLACore::mla_debug_add( "<strong>mla_fetch_custom_template( {$key}, {$shortcode}, {$type}, {$section} )</strong> " . __( 'calling parameters', 'media-library-assistant' ), MLACore::MLA_DEBUG_CATEGORY_ANY );
if ( ! is_array( MLATemplate_Support::$mla_custom_templates ) ) {
MLACore::mla_debug_add( '<strong>mla_fetch_custom_template()</strong> ' . __( 'no templates exist', 'media-library-assistant' ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return NULL;
}
//error_log( ' mla_fetch_custom_template mla_custom_templates = ' . var_export( MLATemplate_Support::$mla_custom_templates, true ), 0 );
if ( array_key_exists( $type, MLATemplate_Support::$mla_custom_templates ) ) {
if ( array_key_exists( $shortcode, MLATemplate_Support::$mla_custom_templates[ $type ] ) ) {
if ( array_key_exists( $key, MLATemplate_Support::$mla_custom_templates[ $type ][ $shortcode ] ) ) {
if ( '[exists]' == $section ) {
return true;
}
if ( array_key_exists( $section, MLATemplate_Support::$mla_custom_templates[ $type ][ $shortcode ][ $key ] ) ) {
return MLATemplate_Support::$mla_custom_templates[ $type ][ $shortcode ][ $key ][ $section ];
} elseif ( 'style' == $type && '[not supplied]' == $section ) {
return MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ][ $key ]['styles'];
}
// No error - not every section is required
return false;
} elseif ( '[exists]' == $section ) {
return false;
}
}
}
MLACore::mla_debug_add( "<strong>mla_fetch_custom_template( {$key}, {$shortcode}, {$type}, {$section} )</strong> " . __( 'not found', 'media-library-assistant' ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return false;
}
/**
* Get ALL style templates from $mla_custom_templates, including default(s).
*
* @since 2.30
*
* @param string $shortcode Optional. Shortcode to which the template(s) apply. Default ''.
* @return array|null Array ( name => value ) for all style templates or null if no templates.
*/
public static function mla_get_style_templates( $shortcode = '' ) {
if ( ! is_array( MLATemplate_Support::$mla_custom_templates ) ) {
MLACore::mla_debug_add( '<strong>mla_debug mla_get_style_templates()</strong> ' . __( 'no templates exist', 'media-library-assistant' ) );
return NULL;
}
if ( !empty( $shortcode ) ) {
if ( array_key_exists( $shortcode, MLATemplate_Support::$mla_custom_templates['style'] ) ) {
return MLATemplate_Support::$mla_custom_templates['style'][ $shortcode ];
}
return NULL;
}
$templates = array();
foreach ( MLATemplate_Support::$mla_custom_templates['style'] as $shortcode => $value ) {
$templates = array_merge( $templates, $value );
} // foreach
return $templates;
}
/**
* Put user-defined style templates to $mla_custom_templates and database
*
* @since 2.30
*
* @param array $templates Array ( name => value ) for all user-defined style templates.
* @return boolean true if success, false if failure.
*/
public static function mla_put_style_templates( $templates ) {
$new_templates = array();
foreach ( $templates as $name => $sections ) {
$styles = $sections['styles'];
// Embed description in the styles for backward compatibility
if ( isset( $sections['description'] ) ) {
$styles = sprintf( "<!-- mla_description=\"%1\$s\" -->\r\n%2\$s", $sections['description'], $styles );
}
$new_templates[ $name ] = $styles;
}
if ( MLACore::mla_update_option( 'style_templates', $new_templates ) ) {
MLATemplate_Support::mla_load_custom_templates();
return true;
}
return false;
}
/**
* Get ALL markup templates from $mla_custom_templates, including default(s).
*
* @since 2.30
*
* @param string $shortcode Optional. Shortcode to which the template(s) apply. Default 'gallery'.
* @return array|null Array ( name => value ) for all markup templates or null if no templates.
*/
public static function mla_get_markup_templates( $shortcode = '' ) {
if ( ! is_array( MLATemplate_Support::$mla_custom_templates ) ) {
MLACore::mla_debug_add( '<strong>mla_debug mla_get_markup_templates()</strong> ' . __( 'no templates exist', 'media-library-assistant' ) );
return NULL;
}
if ( !empty( $shortcode ) ) {
if ( array_key_exists( $shortcode, MLATemplate_Support::$mla_custom_templates['markup'] ) ) {
return MLATemplate_Support::$mla_custom_templates['markup'][ $shortcode ];
}
return NULL;
}
$templates = array();
foreach ( MLATemplate_Support::$mla_custom_templates['markup'] as $shortcode => $value ) {
$templates = array_merge( $templates, $value );
} // foreach
return $templates;
}
/**
* Put user-defined markup templates to $mla_custom_templates and database
*
* @since 2.30
*
* @param array $templates Array ( name => value ) for all user-defined markup templates.
* @return boolean true if success, false if failure.
*/
public static function mla_put_markup_templates( $templates ) {
if ( MLACore::mla_update_option( 'markup_templates', $templates ) ) {
MLATemplate_Support::mla_load_custom_templates();
return true;
}
return false;
}
} // Class MLATemplate_Support
MLATemplate_Support::mla_load_custom_templates();
?>

View File

@@ -0,0 +1,682 @@
<?php
/**
* Media Library Assistant Generate Featured Image class
*
* This file is conditionally loaded in MLA::initialize
*
* @package Media Library Assistant
* @since 2.13
*/
/**
* Class MLA (Media Library Assistant) Thumbnails provides support for
* Featured Image generation
*
* @package Media Library Assistant
* @since 2.13
*/
class MLA_Thumbnail {
/**
* Uniquely identifies the Thumbnails bulk action
*
* @since 2.13
*
* @var string
*/
const MLA_GFI_ACTION = 'mla-generate-featured-image';
/**
* Initialization function, similar to __construct()
*
* @since 2.13
*
* @return void
*/
public static function initialize() {
/*
* The remaining filters are only useful for the admin section;
* exit in the front-end posts/pages
*/
if ( ! is_admin() ) {
return;
}
/*
* Defined in /wp-admin/admin-header.php
*/
add_action( 'admin_enqueue_scripts', 'MLA_Thumbnail::admin_enqueue_scripts', 10, 1 );
/*
* Defined in /media-library-assistant/includes/class-mla-main.php
*/
add_filter( 'mla_list_table_help_template', 'MLA_Thumbnail::mla_list_table_help_template', 10, 3 );
add_filter( 'mla_list_table_begin_bulk_action', 'MLA_Thumbnail::mla_list_table_begin_bulk_action', 10, 2 );
add_filter( 'mla_list_table_custom_bulk_action', 'MLA_Thumbnail::mla_list_table_custom_bulk_action', 10, 3 );
add_filter( 'mla_list_table_end_bulk_action', 'MLA_Thumbnail::mla_list_table_end_bulk_action', 10, 2 );
add_filter( 'mla_list_table_inline_parse', 'MLA_Thumbnail::mla_list_table_inline_parse', 10, 3 );
/*
* Defined in /media-library-assistant/includes/class-mla-list-table.php
*/
add_filter( 'mla_list_table_get_bulk_actions', 'MLA_Thumbnail::mla_list_table_get_bulk_actions', 10, 1 );
add_filter( 'mla_list_table_submenu_arguments', 'MLA_Thumbnail::mla_list_table_submenu_arguments', 10, 2 );
}
/**
* Load the plugin's Style Sheet and Javascript files
*
* @since 2.13
*
* @param string Name of the page being loaded
*
* @return void
*/
public static function admin_enqueue_scripts( $page_hook ) {
global $wp_locale;
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
if ( 'media_page_mla-menu' != $page_hook ) {
return;
}
if ( $wp_locale->is_rtl() ) {
wp_register_style( 'mla-thumbnail-generation', MLA_PLUGIN_URL . 'css/mla-thumbnail-generation-rtl.css', false, MLACore::CURRENT_MLA_VERSION );
} else {
wp_register_style( 'mla-thumbnail-generation', MLA_PLUGIN_URL . 'css/mla-thumbnail-generation.css', false, MLACore::CURRENT_MLA_VERSION );
}
wp_enqueue_style( 'mla-thumbnail-generation' );
wp_enqueue_script( 'mla-thumbnail-generation-scripts', MLA_PLUGIN_URL . "js/mla-thumbnail-generation-scripts{$suffix}.js",
array( 'jquery' ), MLACore::CURRENT_MLA_VERSION, false );
$script_variables = array(
'error' => __( 'Error while saving the thumbnails.', 'media-library-assistant' ),
'ntdelTitle' => __( 'Remove From', 'media-library-assistant' ) . ' ' . __( 'Generate Thumbnails', 'media-library-assistant' ),
'noTitle' => __( '(no title)', 'media-library-assistant' ),
'bulkTitle' => __( 'Generate Thumbnails', 'media-library-assistant' ),
'comma' => _x( ',', 'tag_delimiter', 'media-library-assistant' ),
'useSpinnerClass' => false,
);
if ( version_compare( get_bloginfo( 'version' ), '4.2', '>=' ) ) {
$script_variables['useSpinnerClass'] = true;
}
wp_localize_script( 'mla-thumbnail-generation-scripts', 'mla_thumbnail_support_vars', $script_variables );
}
/**
* Options for the thumbnail generation bulk action
*
* @since 2.13
*
* @var array
*/
private static $bulk_action_options = array();
/**
* Items returned by custom bulk action(s)
*
* @since 2.13
*
* @var array
*/
private static $bulk_action_includes = array();
/**
* Load the MLA_List_Table dropdown help menu template
*
* Add the thumbnail generation options documentation.
*
* @since 2.13
*
* @param array $template_array NULL, to indicate no replacement template.
* @param string $file_name the complete name of the default template file.
* @param string $file_suffix the $screen->id or hook suffix part of the template file name.
*/
public static function mla_list_table_help_template( $template_array, $file_name, $file_suffix ) {
if ( 'media_page_mla-menu' != $file_suffix ) {
return $template_array;
}
// Retain other filters' additions
if ( empty( $template_array ) ) {
$template_array = MLACore::mla_load_template( $file_name );
}
$help_array = MLACore::mla_load_template( 'help-for-thumbnail_generation.tpl' );
if ( isset( $help_array['sidebar'] ) ) {
if ( isset( $template_array['sidebar'] ) ) {
$template_array['sidebar'] .= $help_array['sidebar'];
} else {
$template_array['sidebar'] = $help_array['sidebar'];
}
unset( $help_array['sidebar'] );
}
return array_merge( $template_array, $help_array );
}
/**
* Begin an MLA_List_Table bulk action
*
* Prepare the thumbnail generation options.
*
* @since 2.13
*
* @param array $item_content NULL, to indicate no handler.
* @param string $bulk_action the requested action.
*/
public static function mla_list_table_begin_bulk_action( $item_content, $bulk_action ) {
if ( self::MLA_GFI_ACTION != $bulk_action ) {
return $item_content;
}
self::$bulk_action_options = array();
$request_options = isset( $_REQUEST['mla_thumbnail_options'] ) ? $_REQUEST['mla_thumbnail_options'] : array();
$request_options['ghostscript_path'] = MLACore::mla_get_option( 'ghostscript_path' );
if ( empty( $request_options['existing_thumbnails'] ) ) {
$request_options['existing_thumbnails'] = 'keep';
}
foreach ( $request_options as $key => $value ) {
if ( ! empty( $value ) ) {
self::$bulk_action_options[ $key ] = $value;
}
}
// Convert checkboxes to booleans
self::$bulk_action_options['best_fit'] = isset( $request_options['best_fit'] );
self::$bulk_action_options['clear_filters'] = isset( $request_options['clear_filters'] );
// Convert page number to frame
if ( isset( self::$bulk_action_options['page'] ) ) {
$page = abs( intval( self::$bulk_action_options['page'] ) );
self::$bulk_action_options['frame'] = ( 0 < $page ) ? $page - 1 : 0;
unset( self::$bulk_action_options['page'] );
}
return $item_content;
} // mla_list_table_begin_bulk_action
/**
* Adjust wp_upload_dir results to match the original PDF location
*
* @since 2.54
*
* @param array $uploads Array of upload directory data with keys of 'path',
* 'url', 'subdir, 'basedir', and 'error'.
*/
public static function upload_dir( $uploads ) {
$subdir = self::$bulk_action_options['item_subdir'];
if ( $subdir !== $uploads['subdir'] ) {
// Remove the old subdir, if present
if ( !empty( $uploads['subdir'] ) ) {
$uploads['path'] = substr( $uploads['path'], 0, strpos( $uploads['path'], $uploads['subdir'] ) );
$uploads['url'] = substr( $uploads['url'], 0, strpos( $uploads['url'], $uploads['subdir'] ) );
}
// Add the new subdir
$uploads['path'] .= $subdir;
$uploads['url'] .= $subdir;
$uploads['subdir'] = $subdir;
}
return $uploads;
} // upload_dir
/**
* Intercept thumbnail file deletion errors
*
* @since 2.54
*
* @param int the level of the error raised
* @param string the error message
* @param string the filename that the error was raised in
* @param int the line number the error was raised at
*
* @return boolean true, to bypass PHP error handler
*/
public static function unlink_error_handler( $type, $string, $file, $line ) {
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::unlink_error_handler( $type, $string, $file, $line )", MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
// Don't execute PHP internal error handler
return true;
}
/**
* Generate WordPress-style (4.7+) thumbnail image
*
* Adapted from /wp-admin/includes/image.php function wp_generate_attachment_metadata()
*
* @since 2.40
*
* @param string $post_id ID of the source item
* @param string $file Source file path and name
* @param array $args Image file information, based on $_FILE in PHP uploads
* @param array $old_sizes Existing WordPress-style thumbnail images to be deleted
*
* @return array Sizes specifications for attachment metadata
*/
private static function _generate_wordpress_thumbnail( $post_id, $file, $args, $old_sizes = NULL ) {
// Get the metadata for the original (PDF) attachment.
$item_data = wp_get_attachment_metadata( $post_id );
// Make the file path relative to the upload dir.
$item_relative_path = _wp_relative_upload_path( $file );
if ( $item_relative_path !== $args['name'] ) {
self::$bulk_action_options['item_subdir'] = '/' . substr( $item_relative_path, 0, ( strpos( $item_relative_path, $args['name'] ) -1 ) );
} else {
self::$bulk_action_options['item_subdir'] = NULL;
}
// Try to remove intermediate images if there are any
if ( is_array( $old_sizes ) ) {
foreach ( $old_sizes as $size => $sizeinfo ) {
$intermediate_file = str_replace( basename( $file ), $sizeinfo['file'], $file );
set_error_handler( 'MLA_Thumbnail::unlink_error_handler' );
try {
unlink( $intermediate_file );
} catch ( Throwable $e ) { // PHP 7
} catch ( Exception $e ) { // PHP 5
}
restore_error_handler();
}
}
$fallback_sizes = array(
'thumbnail',
'medium',
'large',
);
// Filters the image sizes generated for non-image mime types.
$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $item_data );
$sizes = array();
$_wp_additional_image_sizes = wp_get_additional_image_sizes();
foreach ( $fallback_sizes as $s ) {
if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
} else {
$sizes[ $s ]['width'] = get_option( "{$s}_size_w" );
}
if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
$sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );
} else {
$sizes[ $s ]['height'] = get_option( "{$s}_size_h" );
}
if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
$sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];
} else {
// Force thumbnails to be soft crops.
if ( ! 'thumbnail' === $s ) {
$sizes[ $s ]['crop'] = get_option( "{$s}_crop" );
}
}
}
// Adjust the file name for the new item
$args['name'] = pathinfo( $args['name'], PATHINFO_FILENAME ) . '-pdf.jpg';
$overrides = array( 'test_form' => false, 'test_size' => true, 'test_upload' => true, );
// move the temporary file into the uploads directory
add_filter( 'upload_dir', 'MLA_Thumbnail::upload_dir', 10, 1 );
$results = wp_handle_sideload( $args, $overrides );
remove_filter( 'upload_dir', 'MLA_Thumbnail::upload_dir', 10 );
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::_generate_wordpress_thumbnail( $post_id, $file ) sideload results = " . var_export( $results, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
if ( ! empty( $results['error'] ) ) {
return $results['error'];
}
$editor_args = isset( $results['type'] ) ? array( 'mime_type' => $results['type'] ) : array();
$editor = wp_get_image_editor( $results['file'], $editor_args );
if ( is_wp_error( $editor ) ) {
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::_generate_wordpress_thumbnail editor = " . var_export( $editor, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
return implode( ',', $editor->get_error_messages() );
}
$results = $editor->multi_resize( $sizes );
$results['full'] = array(
'file' => $args['name'],
'width' => $args['width'],
'height' => $args['height'],
'mime-type' => $args['type'],
);
// Update the metadata for the original (PDF) attachment.
$item_data['sizes'] = $results;
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::_generate_wordpress_thumbnail item_data = " . var_export( $item_data, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
wp_update_attachment_metadata( $post_id, $item_data );
return true;
} // _generate_wordpress_thumbnail
/**
* Process an MLA_List_Table custom bulk action
*
* Creates new items from the "Bulk Thumbnail" list.
*
* @since 2.13
*
* @param array $item_content NULL, to indicate no handler.
* @param string $bulk_action the requested action.
* @param integer $post_id the affected attachment.
*
* @return object updated $item_content. NULL if no handler, otherwise
* ( 'message' => error or status message(s), 'body' => '' )
*/
public static function mla_list_table_custom_bulk_action( $item_content, $bulk_action, $post_id ) {
if ( self::MLA_GFI_ACTION != $bulk_action ) {
return $item_content;
}
/* translators: 1: post ID */
$item_prefix = sprintf( __( 'Item %1$d', 'media-library-assistant' ), $post_id ) . ', ';
// If there is a real thumbnail image, no generation is required or allowed except for PDFs
$old_sizes = NULL;
$thumbnail = image_downsize( $post_id, 'thumbnail' );
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::mla_list_table_custom_bulk_action image_downsize( {$post_id} ) thumbnail = " . var_export( $thumbnail, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
if ( ! empty( $thumbnail ) ) {
// Special case - allow replacement of WordPress-style thumbnails for PDFs, etc.
if ( 'delete' === self::$bulk_action_options['existing_thumbnails'] && 'WordPress' === self::$bulk_action_options['type'] ) {
if ( ! wp_attachment_is_image( $post_id ) ) {
$meta = wp_get_attachment_metadata( $post_id );
if ( ! empty( $meta['sizes'] ) ) {
$old_sizes = $meta['sizes'];
}
}
}
if ( empty( $old_sizes ) ) {
return array( 'message' => $item_prefix . __( 'has native thumbnail.', 'media-library-assistant' ) );
}
}
// Look for the "Featured Image" as an alternate thumbnail for PDFs, etc.
$thumbnail = get_post_thumbnail_id( $post_id );
MLACore::mla_debug_add( __LINE__ . " MLA_Thumbnail::mla_list_table_custom_bulk_action get_post_thumbnail_id( {$post_id} ) thumbnail = " . var_export( $thumbnail, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );
if ( ! empty( $thumbnail ) ) {
switch ( self::$bulk_action_options['existing_thumbnails'] ) {
case 'ignore':
break;
case 'trash':
delete_post_thumbnail( $post_id );
wp_delete_post( absint( $thumbnail ), false );
break;
case 'delete':
delete_post_thumbnail( $post_id );
wp_delete_post( absint( $thumbnail ), true );
break;
case 'keep':
default:
return array( 'message' => $item_prefix . __( 'Featured Image retained.', 'media-library-assistant' ) );
}
}
// Validate the file existance and type
$file = get_attached_file( $post_id );
if ( empty( $file ) ) {
/* translators: 1: ERROR tag 2: Item post ID */
return array( 'message' => sprintf( __( '%1$s: %2$sno attached file.', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $item_prefix ) );
}
if ( ! in_array( strtolower( pathinfo( $file, PATHINFO_EXTENSION ) ), array( 'ai', 'eps', 'pdf', 'ps' ) ) ) {
return array( 'message' => $item_prefix . __( 'unsupported file type.', 'media-library-assistant' ) );
}
// Generate a thumbnail
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-image-processor.php' );
$results = MLAImageProcessor::mla_handle_thumbnail_sideload( $file, self::$bulk_action_options );
if ( ! empty( $results['error'] ) ) {
/* translators: 1: ERROR tag 2: Item post ID */
return array( 'message' => sprintf( __( '%1$s: %2$sthumbnail generation failed', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $item_prefix ) . ' - ' . $results['error'] );
}
if ( 'WordPress' === self::$bulk_action_options['type'] ) {
$results = self::_generate_wordpress_thumbnail( $post_id, $file, $results, $old_sizes );
if ( true === $results ) {
/* translators: 1: Item post ID */
return array( 'message' => sprintf( __( '%1$sWordPress-style thumbnail generated.', 'media-library-assistant' ), $item_prefix ) );
}
/* translators: 1: ERROR tag 2: Item post ID */
return array( 'message' => sprintf( __( '%1$s: %2$sthumbnail generation failed', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $item_prefix ) . ' - ' . $results );
}
// Adjust the file name for the new item
$pathinfo = pathinfo( $results['name'] );
if ( isset( self::$bulk_action_options['suffix'] ) ) {
$pathinfo['filename'] = sanitize_file_name( $pathinfo['filename'] . strtolower( self::$bulk_action_options['suffix'] ) );
}
$pathinfo['extension'] = ( 'image/jpeg' == $results['type'] ) ? 'jpg' : 'png';
$results['name'] = $pathinfo['filename'] . '.' . $pathinfo['extension'];
$overrides = array( 'test_form' => false, 'test_size' => true, 'test_upload' => true, );
// move the temporary file into the uploads directory
$results = wp_handle_sideload( $results, $overrides );
$item_data = get_post( $post_id, ARRAY_A );
unset( $item_data['ID'] );
unset( $item_data['post_author'] );
unset( $item_data['post_date'] );
unset( $item_data['post_date_gmt'] );
if ( isset( self::$bulk_action_options['suffix'] ) ) {
$item_data['post_title'] .= self::$bulk_action_options['suffix'];
}
unset( $item_data['post_name'] );
unset( $item_data['post_modified'] );
unset( $item_data['post_modified_gmt'] );
$item_parent = $item_data['post_parent'];
unset( $item_data['post_parent'] );
$item_data['guid'] = $results['url'];
$item_data['post_mime_type'] = $results['type'];
unset( $item_data['comment_count'] );
unset( $item_data['ancestors'] );
unset( $item_data['post_category'] );
unset( $item_data['tags_input'] );
// Insert the attachment.
$item_id = wp_insert_attachment( $item_data, $results['file'], $item_parent );
if ( empty( $item_id ) ) {
/* translators: 1: ERROR tag 2: Item post ID */
return array( 'message' => sprintf( __( '%1$s: %2$swp_insert_attachment failed.', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $item_prefix ) );
}
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Update the metadata for the original (PDF) attachment.
$item_data = wp_generate_attachment_metadata( $item_id, $results['file']);
wp_update_attachment_metadata( $item_id, $item_data );
// Assign the new item as the source item's Featured Image
delete_post_thumbnail( $post_id );
set_post_thumbnail( $post_id, $item_id );
MLA_Thumbnail::$bulk_action_includes[] = $item_id;
/* translators: 1: Item post ID, 2: new thumbnail item ID */
$item_content = array( 'message' => sprintf( __( '%1$sthumbnail generated as new item %2$s.', 'media-library-assistant' ), $item_prefix, $item_id ) );
return $item_content;
} // mla_list_table_custom_bulk_action
/**
* End an MLA_List_Table bulk action
*
* Add the query arguments required for the "Generated Thumbnails" filter.
*
* @since 2.13
*
* @param array $item_content NULL, to indicate no handler.
* @param string $bulk_action the requested action.
*/
public static function mla_list_table_end_bulk_action( $item_content, $bulk_action ) {
if ( self::MLA_GFI_ACTION != $bulk_action ) {
return $item_content;
}
if ( ! empty( MLA_Thumbnail::$bulk_action_includes ) ) {
MLA::mla_clear_filter_by( array( 'ids' ) );
// Reset the current view to "All" to ensure that thumbnails are displayed
unset( $_REQUEST['post_mime_type'] );
unset( $_POST['post_mime_type'] );
unset( $_GET['post_mime_type'] );
unset( $_REQUEST['meta_query'] );
unset( $_GET['meta_query'] );
unset( $_REQUEST['meta_slug'] );
unset( $_GET['meta_slug'] );
// Clear the "extra_nav" controls and the Search Media box, too
unset( $_REQUEST['m'] );
unset( $_POST['m'] );
unset( $_GET['m'] );
unset( $_REQUEST['mla_filter_term'] );
unset( $_POST['mla_filter_term'] );
unset( $_GET['mla_filter_term'] );
unset( $_REQUEST['s'] );
unset( $_POST['s'] );
unset( $_GET['s'] );
// Clear the pagination control
unset( $_REQUEST['paged'] );
unset( $_POST['paged'] );
unset( $_GET['paged'] );
$_REQUEST['ids'] = MLA_Thumbnail::$bulk_action_includes;
$_REQUEST['heading_suffix'] = __( 'Generated Thumbnails', 'media-library-assistant' );
}
return $item_content;
} // mla_list_table_end_bulk_action
/**
* Filter the MLA_List_Table bulk actions
*
* Adds the "Thumbnail" action to the Bulk Actions list.
*
* @since 2.13
*
* @param array $actions An array of bulk actions.
* Format: 'slug' => 'Label'
*
* @return array updated array of actions.
*/
public static function mla_list_table_get_bulk_actions( $actions ) {
if ( !( isset( $_REQUEST['status'] ) && $_REQUEST['status'] == 'trash' ) ) {
$actions[self::MLA_GFI_ACTION] = __( 'Thumbnail', 'media-library-assistant' );
}
return $actions;
} // mla_list_table_get_bulk_actions
/**
* MLA_List_Table inline edit parse
*
* @since 2.13
*
* Adds Bulk Translate form and the Language dropdown
* markup used for the Quick and Bulk Edit forms.
*
* @param string HTML markup returned by the template parser
* @param string template used to generate the HTML markup
* @param array parameter_name => parameter_value pairs
*
* @return array updated HTML markup for the Quick and Bulk Edit forms
*/
public static function mla_list_table_inline_parse( $html_markup, $item_template, $item_values ) {
// Add the Thumbnail Generation Markup
$page_template_array = MLACore::mla_load_template( 'mla-thumbnail-generation.tpl' );
if ( ! is_array( $page_template_array ) ) {
MLACore::mla_debug_add( 'ERROR: mla-thumbnail-generation.tpl path = ' . var_export( plugin_dir_path( __FILE__ ) . 'mla-thumbnail-generation.tpl', true ), MLACore::MLA_DEBUG_CATEGORY_ANY );
MLACore::mla_debug_add( 'ERROR: mla-thumbnail-generation.tpl non-array result = ' . var_export( $page_template_array, true ), MLACore::MLA_DEBUG_CATEGORY_ANY );
return $html_markup;
}
// WordPress thumbnail generation began in version 4.7
if ( version_compare( get_bloginfo('version'), '4.6.9', '>' ) ) {
$wp_style = '';
$wp_checked = 'checked="checked"';
$jpg_checked = '';
$wp_help = __( 'Type &ldquo;WP&rdquo; generates native WordPress thumbnails without creating a separate image item.', 'media-library-assistant' );
} else {
$wp_style = 'style="display: none"';
$wp_checked = '';
$jpg_checked = 'checked="checked"';
$wp_help = '';
}
$page_values = array(
'colspan' => $item_values['colspan'],
'Generate Thumbnails' => __( 'Generate Thumbnails', 'media-library-assistant' ),
'See Documentation' => __( 'Pull down the Help menu and select Thumbnail Generation for setting details', 'media-library-assistant' ),
'Width' => __( 'Width', 'media-library-assistant' ),
'Height' => __( 'Height', 'media-library-assistant' ),
'Best Fit' => __( 'Best Fit', 'media-library-assistant' ),
'Page' => __( 'Page', 'media-library-assistant' ),
'Resolution' => __( 'Resolution', 'media-library-assistant' ),
'Quality' => __( 'Quality', 'media-library-assistant' ),
'Type' => __( 'Type', 'media-library-assistant' ),
'WP Style' => $wp_style,
'WP Checked' => $wp_checked,
'JPG Checked' => $jpg_checked,
'WP Help' => $wp_help,
'Existing Items' => __( 'Existing Items', 'media-library-assistant' ),
'Keep' => __( 'Keep', 'media-library-assistant' ),
'Ignore' => __( 'Ignore', 'media-library-assistant' ),
'Trash' => __( 'Trash', 'media-library-assistant' ),
'Delete' => __( 'Delete', 'media-library-assistant' ),
'Suffix' => __( 'Suffix', 'media-library-assistant' ),
'default_suffix' => '-' . __( 'Thumbnail', 'media-library-assistant' ),
'Options' => __( 'Options', 'media-library-assistant' ),
'Clear Filter-by' => __( 'Clear Filter-by', 'media-library-assistant' ),
'Cancel' => __( 'Cancel', 'media-library-assistant' ),
);
$parse_value = MLAData::mla_parse_template( $page_template_array['page'], $page_values );
return $html_markup . "\n" . $parse_value;
} // mla_list_table_inline_parse
/**
* Filter the "sticky" submenu URL parameters
*
* Maintains the list of "Generated Thumbnails" items in the URLs for filtering the table display.
*
* @since 2.13
*
* @param array $submenu_arguments Current view, pagination and sort parameters.
* @param object $include_filters True to include "filter-by" parameters, e.g., year/month dropdown.
*
* @return array updated submenu_arguments.
*/
public static function mla_list_table_submenu_arguments( $submenu_arguments, $include_filters ) {
if ( $include_filters && ( ! empty( MLA_Thumbnail::$bulk_action_includes ) ) ) {
$submenu_arguments['ids'] = implode( ',', MLA_Thumbnail::$bulk_action_includes );
$submenu_arguments['heading_suffix'] = __( 'Generated Thumbnails', 'media-library-assistant' );
}
return $submenu_arguments;
} // mla_list_table_submenu_arguments
} // Class MLA_Thumbnail
// Install the filters at an early opportunity
add_action('init', 'MLA_Thumbnail::initialize');
?>

View File

@@ -0,0 +1,94 @@
<?php
/**
* Media Library Assistant WPML Shortcode Support classes, front-end mode
*
* This file is conditionally loaded in MLAShortcodes::initialize after a check for WPML presence.
*
* @package Media Library Assistant
* @since 2.40
*/
/**
* Class MLA (Media Library Assistant) WPML Shortcodes provides front-end support for the
* WPML Multilingual CMS family of plugins, including WPML Media
*
* @package Media Library Assistant
* @since 2.40
*/
class MLA_WPML_Shortcodes {
/**
* Initialization function, similar to __construct()
*
* This function contains add_action and add_filter calls.
*
* @since 2.40
*
* @return void
*/
public static function initialize() {
/*
* Defined in /media-library-assistant/includes/class-mla-shortcode-support.php
*/
add_filter( 'mla_get_terms_query_arguments', 'MLA_WPML_Shortcodes::mla_get_terms_query_arguments', 10, 1 );
add_filter( 'mla_get_terms_clauses', 'MLA_WPML_Shortcodes::mla_get_terms_clauses', 10, 1 );
}
/**
* MLA Tag Cloud Query Arguments
*
* Saves [mla_tag_cloud] query parameters for use in MLA_WPML_Shortcodes::mla_get_terms_clauses.
*
* @since 2.40
* @uses MLA_WPML_Shortcodes::$all_query_parameters
*
* @param array shortcode arguments merged with attachment selection defaults
*/
public static function mla_get_terms_query_arguments( $all_query_parameters ) {
self::$all_query_parameters = $all_query_parameters;
return $all_query_parameters;
} // mla_get_terms_query_arguments
/**
* Save the query arguments
*
* @since 2.40
*
* @var array
*/
private static $all_query_parameters = array();
/**
* MLA Tag Cloud Query Clauses
*
* Adds language-specific clauses to filter the cloud terms.
*
* @since 2.11
* @uses MLA_WPML_Shortcodes::$all_query_parameters
*
* @param array SQL clauses ( 'fields', 'join', 'where', 'order', 'orderby', 'limits' )
*/
public static function mla_get_terms_clauses( $clauses ) {
global $wpdb, $sitepress;
if ( 'all' != ( $current_language = $sitepress->get_current_language() ) ) {
$clauses['join'] = preg_replace( '/(^.* AS tt ON t.term_id = tt.term_id)/m', '${1}' . ' JOIN `' . $wpdb->prefix . 'icl_translations` AS icl_t ON icl_t.element_id = tt.term_taxonomy_id', $clauses['join'] );
$clauses['where'] .= " AND icl_t.language_code = '" . $current_language . "'";
if ( is_string( $query_taxonomies = self::$all_query_parameters['taxonomy'] ) ) {
$query_taxonomies = array ( $query_taxonomies );
}
$taxonomies = array();
foreach ( $query_taxonomies as $taxonomy) {
$taxonomies[] = 'tax_' . $taxonomy;
}
$clauses['where'] .= "AND icl_t.element_type IN ( '" . join( "','", $taxonomies ) . "' )";
}
return $clauses;
} // mla_get_terms_clauses
} // Class MLA_WPML_Shortcodes
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
<?php
/**
* Stand-alone file download handler for the [mla_gallery]
*
* @package Media Library Assistant
* @since 2.32
*/
/*
* Process [mla_gallery link=download] requests
*/
//@ini_set('error_log','C:\Program Files (x86)\Apache Software Foundation\Apache24\logs\php-errors.log');
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-file-downloader.php' );
if ( isset( $_REQUEST['mla_download_file'] ) && isset( $_REQUEST['mla_download_type'] ) ) {
MLAFileDownloader::$mla_debug = isset( $_REQUEST['mla_debug'] ) && 'log' == $_REQUEST['mla_debug'];
MLAFileDownloader::mla_process_download_file();
}
MLAFileDownloader::mla_die( 'MLA File Download parameters not set', __LINE__, 500 );
?>

View File

@@ -0,0 +1,63 @@
<?php
/**
* PHP "template" for Media/Assistant submenu table Search Media box
*
* @package Media Library Assistant
* @since 1.90
*/
/**
* Harmless declaration to suppress phpDocumentor "No page-level DocBlock" error
*
* @global $post
*/
global $post;
if ( !empty( $_REQUEST['s'] ) ) {
$search_value = esc_attr( stripslashes( trim( $_REQUEST['s'] ) ) );
$search_fields = isset ( $_REQUEST['mla_search_fields'] ) ? $_REQUEST['mla_search_fields'] : array();
$search_connector = $_REQUEST['mla_search_connector'];
} else {
$search_value = MLACore::mla_get_option( MLACoreOptions::MLA_SEARCH_MEDIA_FILTER_DEFAULTS );
$search_fields = $search_value['search_fields'];
$search_connector = $search_value['search_connector'];
$search_value = '';
}
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_SEARCH_MEDIA_FILTER_SHOW_CONTROLS ) ) {
$controls_style = 'style="display: inline;"';
} else {
$controls_style = 'style="display: none;"';
}
$supported_taxonomies = MLACore::mla_supported_taxonomies('support');
if ( empty( $supported_taxonomies ) ) {
$terms_style = 'style="display: none;"';
unset( $search_fields['terms'] );
} else {
$terms_style = 'style="display: inline;"';
}
?>
<p class="search-box">
<label class="screen-reader-text" for="mla-media-search-input"><?php _e( 'Search Media', 'media-library-assistant' ); ?></label>
<input name="s" id="mla-media-search-input" type="text" size="45" value="<?php echo $search_value ?>" />
<input name="mla-search-submit" class="button" id="search-submit" type="submit" value="<?php _e( 'Search Media', 'media-library-assistant' ); ?>" /><br />
<span <?php echo $controls_style ?>>
<span id="search-title-span">
<input name="mla_search_fields[]" id="search-title" type="checkbox" <?php echo ( in_array( 'title', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="title" /><?php _e( 'Title', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-title-span">
<input name="mla_search_fields[]" id="search-name" type="checkbox" <?php echo ( in_array( 'name', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="name" /><?php _e( 'Name', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-alt-text-span">
<input name="mla_search_fields[]" id="search-alt-text" type="checkbox" <?php echo ( in_array( 'alt-text', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="alt-text" /><?php _e( 'ALT Text', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-excerpt-span">
<input name="mla_search_fields[]" id="search-excerpt" type="checkbox" <?php echo ( in_array( 'excerpt', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="excerpt" /><?php _e( 'Caption', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-content-span">
<input name="mla_search_fields[]" id="search-content" type="checkbox" <?php echo ( in_array( 'content', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="content" /><?php _e( 'Description', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-file-span">
<input name="mla_search_fields[]" id="search-file" type="checkbox" <?php echo ( in_array( 'file', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="file" /><?php _e( 'File', 'media-library-assistant' )?>&nbsp;</span>
<span id="search-terms-span" <?php echo $terms_style ?>><input name="mla_search_fields[]" id="terms-search" type="checkbox" <?php echo ( in_array( 'terms', $search_fields ) ) ? 'checked="checked"' : ''; ?> value="terms" /><?php _e( 'Terms', 'media-library-assistant' )?></span>
<br />
<input name="mla_search_connector" type="radio" <?php echo ( 'OR' === $search_connector ) ? '' : 'checked="checked"'; ?> value="AND" /><?php _e( 'and', 'media-library-assistant' ); ?>&nbsp;
<input name="mla_search_connector" type="radio" <?php echo ( 'OR' === $search_connector ) ? 'checked="checked"' : ''; ?> value="OR" /><?php _e( 'or', 'media-library-assistant' ); ?>
</span>
</p>

View File

@@ -0,0 +1,76 @@
<?php
/**
* Backbone/JavaScript template for Media Library Assistant Media Manager enhancements
*
* @package Media Library Assistant
* @since 1.80
*/
/**
* Harmless declaration to suppress phpDocumentor "No page-level DocBlock" error
*
* @global $post
*/
global $post;
$supported_taxonomies = MLACore::mla_supported_taxonomies('support');
if ( empty( $supported_taxonomies ) ) {
$terms_style = 'style="display: none;"';
} else {
$terms_style = 'style="display: inline;"';
}
?>
<script type="text/html" id="tmpl-mla-search-box">
<div style="display: inline-block">
<label class="screen-reader-text" for="mla-media-search-input"><?php _e( 'Search Media', 'media-library-assistant' ); ?>:</label>
<input name="s[mla_search_value]" class="search" id="mla-media-search-input" style="width: 100%; max-width: 100%" type="search" value="{{ data.searchValue }}" placeholder="{{ data.searchBoxPlaceholder }}" />
</div>
<input name="mla_search_submit" class="button media-button mla-search-submit-button" id="mla-search-submit" type="submit" style="float: none" value="<?php _e( 'Search', 'media-library-assistant' ); ?>" /><br>
<ul class="mla-search-options" style="{{ data.searchBoxControlsStyle }}">
<li>
<input type="radio" name="s[mla_search_connector]" value="AND" <# if ( 'OR' !== data.searchConnector ) { #>checked="checked"<# } #> />
<?php _e( 'and', 'media-library-assistant' ); ?>
</li>
<li>
<input type="radio" name="s[mla_search_connector]" value="OR" <# if ( 'OR' === data.searchConnector ) { #>checked="checked"<# } #> />
<?php _e( 'or', 'media-library-assistant' ); ?>
</li>
<li>
<input type="checkbox" name="s[mla_search_title]" id="search-title" value="title" <# if ( -1 != data.searchFields.indexOf( 'title' ) ) { #>checked<# } #> />
<?php _e( 'Title', 'media-library-assistant' ); ?>
</li>
<li>
<input type="checkbox" name="s[mla_search_name]" id="search-name" value="name" <# if ( -1 != data.searchFields.indexOf( 'name' ) ) { #>checked<# } #> />
<?php _e( 'Name', 'media-library-assistant' ); ?>
</li>
<li>
<input type="checkbox" name="s[mla_search_alt_text]" id="search-alt-text" value="alt-text" <# if ( -1 != data.searchFields.indexOf( 'alt-text' ) ) { #>checked<# } #> />
<?php _e( 'ALT Text', 'media-library-assistant' ); ?>
</li>
<br style="clear: both">
<li>
<input type="checkbox" name="s[mla_search_excerpt]" id="search-excerpt" value="excerpt" <# if ( -1 != data.searchFields.indexOf( 'excerpt' ) ) { #>checked<# } #> />
<?php _e( 'Caption', 'media-library-assistant' ); ?>
</li>
<li>
<input type="checkbox" name="s[mla_search_content]" id="search-content" value="content" <# if ( -1 != data.searchFields.indexOf( 'content' ) ) { #>checked<# } #> />
<?php _e( 'Description', 'media-library-assistant' ); ?>
</li>
<li>
<input type="checkbox" name="s[mla_search_file]" id="search-file" value="file" <# if ( -1 != data.searchFields.indexOf( 'file' ) ) { #>checked<# } #> />
<?php _e( 'File', 'media-library-assistant' ); ?>
</li>
<span <?php echo $terms_style ?>>
<li>
<input type="checkbox" name="s[mla_search_terms]" id="search-terms" value="terms" <# if ( -1 != data.searchFields.indexOf( 'terms' ) ) { #>checked<# } #> />
<?php _e( 'Terms', 'media-library-assistant' ); ?>
</li>
</span>
</ul>
</script>
<script type="text/html" id="tmpl-mla-terms-search-button">
<input type="button" name="mla_terms_search" id="mla-terms-search" class="button media-button button-large mla-terms-search-button" value="<?php _e( 'Terms Search', 'media-library-assistant' ); ?>" />
</script>
<script type="text/html" id="tmpl-mla-simulate-search-button">
<input style="display:none" type="button" name="mla_search_submit" id="mla-search-submit" class="button" value="<?php _e( 'Search', 'media-library-assistant' ); ?>" />
</script>

View File

@@ -0,0 +1,206 @@
<?php
/**
* Media Library Assistant Plugin Loader
*
* Defines constants and loads all of the classes and functions required to run the plugin.
* This file is only loaded if the naming conflict tests in index.php are passed.
*
* @package Media Library Assistant
* @since 0.20
*/
defined( 'ABSPATH' ) or die();
if ( ! defined('MLA_OPTION_PREFIX') ) {
/**
* Gives a unique prefix for plugin options; can be set in wp-config.php
*/
define('MLA_OPTION_PREFIX', 'mla_');
}
if ( ! defined('MLA_DEBUG_LEVEL') ) {
/**
* Activates debug options; can be set in wp-config.php
*/
define('MLA_DEBUG_LEVEL', 1);
}
if ( ! defined('MLA_AJAX_EXCEPTIONS') ) {
/**
* Activates full MLA load for specified AJAX actions; can be set in wp-config.php
*/
define('MLA_AJAX_EXCEPTIONS', '');
}
/**
* Accumulates error messages from name conflict tests
*
* @since 1.14
*/
$mla_plugin_loader_error_messages = '';
/**
* Displays version conflict error messages at the top of the Dashboard
*
* @since 1.14
*/
function mla_plugin_loader_reporting_action () {
global $mla_plugin_loader_error_messages;
echo '<div class="error"><p><strong>' . __( 'The Media Library Assistant cannot load.', 'media-library-assistant' ) . '</strong></p>'."\r\n";
echo "<ul>{$mla_plugin_loader_error_messages}</ul>\r\n";
echo '<p>' . __( 'You must resolve these conflicts before this plugin can safely load.', 'media-library-assistant' ) . '</p></div>'."\r\n";
}
// Basic library of run-time tests.
require_once( MLA_PLUGIN_PATH . 'tests/class-mla-tests.php' );
$mla_plugin_loader_error_messages .= MLATest::min_php_version( '5.3' );
$mla_plugin_loader_error_messages .= MLATest::min_WordPress_version( '3.5.0' );
if ( ! empty( $mla_plugin_loader_error_messages ) ) {
add_action( 'admin_notices', 'mla_plugin_loader_reporting_action' );
} else {
// MLATest is loaded above
add_action( 'init', 'MLATest::initialize', 0x7FFFFFFF );
// Minimum support functions required by all other components
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-core.php' );
add_action( 'plugins_loaded', 'MLACore::mla_plugins_loaded_action', 0x7FFFFFFF );
add_action( 'init', 'MLACore::initialize', 0x7FFFFFFF );
// WP/LR Sync plugin has its own protocol to process uploads
$is_wplr_sync = isset( $_SERVER['REQUEST_URI'] ) && false !== strpos( $_SERVER['REQUEST_URI'], '/?wplr-sync-api' );
// Check for XMLPRC, WP REST API and front end requests
if( !( defined('WP_ADMIN') && WP_ADMIN ) ) {
$front_end_only = true;
// XMLRPC requests need everything loaded to process uploads
if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) {
$front_end_only = false;
}
// WP REST API calls need everything loaded to process uploads
if ( isset( $_SERVER['REQUEST_URI'] ) && 0 === strpos( $_SERVER['REQUEST_URI'], '/wp-json/' ) ) {
$front_end_only = false; // TODO be more selective
}
// WP/LR Sync plugin has its own protocol to process uploads
if ( $is_wplr_sync ) {
$front_end_only = false;
}
// Front end posts/pages only need shortcode support; load the interface shims.
if ( $front_end_only ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
add_action( 'init', 'MLAShortcodes::initialize', 0x7FFFFFFF );
return;
}
}
if( defined('DOING_AJAX') && DOING_AJAX ) {
//error_log( __LINE__ . " mla-plugin-loader.php DOING_AJAX \$_REQUEST = " . var_export( $_REQUEST, true ), 0 );
//error_log( __LINE__ . ' MEMORY mla-plugin-loader.php memory_get_peak_usage( true ) ' . number_format( memory_get_peak_usage( true ) ), 0);
//error_log( __LINE__ . ' MEMORY mla-plugin-loader.php memory_get_peak_usage( false ) ' . number_format( memory_get_peak_usage( false ) ), 0);
//error_log( __LINE__ . ' MEMORY mla-plugin-loader.php memory_get_usage( true ) ' . number_format( memory_get_usage( true ) ), 0);
//error_log( __LINE__ . ' MEMORY mla-plugin-loader.php memory_get_usage( false ) ' . number_format( memory_get_usage( false ) ), 0);
// Ajax handlers
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-ajax.php' );
add_action( 'init', 'MLA_Ajax::initialize', 0x7FFFFFFF );
/*
* Quick and Bulk Edit requires full support for content templates, etc.
* IPTC/EXIF and Custom Field mapping require full support, too.
* NOTE: AJAX upload_attachment is no longer used - see /wp-admin/asynch-upload.php
*/
$ajax_exceptions = array( MLACore::JAVASCRIPT_INLINE_EDIT_SLUG, 'mla-inline-mapping-iptc-exif-scripts', 'mla-inline-mapping-custom-scripts', 'mla-polylang-quick-translate', 'mla-inline-edit-upload-scripts', 'mla-inline-edit-view-scripts', 'mla-inline-edit-custom-scripts', 'mla-inline-edit-iptc-exif-scripts', 'upload-attachment' );
$ajax_only = true;
if ( MLA_AJAX_EXCEPTIONS ) {
if ( 'always' === trim( strtolower( MLA_AJAX_EXCEPTIONS ) ) ) {
$ajax_only = false;
} else {
$ajax_exceptions = array_merge( $ajax_exceptions, explode( ',', MLA_AJAX_EXCEPTIONS ) );
}
}
if ( $ajax_only && isset( $_REQUEST['action'] ) ) {
if ( in_array( $_REQUEST['action'], $ajax_exceptions ) ) {
$ajax_only = false;
} elseif ( 'mla-update-compat-fields' == $_REQUEST['action'] ) {
global $sitepress;
//Look for multi-lingual terms updates
if ( is_object( $sitepress ) || class_exists( 'Polylang' ) ) {
$ajax_only = false;
}
} elseif ( 'ajax-tag-search' == $_REQUEST['action'] ) {
global $sitepress;
//Look for WPML flat taxonomy autocomplete
if ( is_object( $sitepress ) ) {
$ajax_only = false;
}
}
}
MLA_Ajax::$ajax_only = $ajax_only; // for debug logging
if ( $ajax_only ) {
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
add_action( 'init', 'MLAQuery::initialize', 0x7FFFFFFF );
// Other plugins such as "No Cache AJAX Widgets" might need shortcodes
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
add_action( 'init', 'MLAShortcodes::initialize', 0x7FFFFFFF );
return;
}
}
// Template file and database access functions.
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
add_action( 'init', 'MLAQuery::initialize', 0x7FFFFFFF );
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
add_action( 'init', 'MLAData::initialize', 0x7FFFFFFF );
// Shortcode shim functions
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
add_action( 'init', 'MLAShortcodes::initialize', 0x7FFFFFFF );
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
// Plugin settings management
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-options.php' );
if ( $is_wplr_sync ) {
// WP/LR Sync runs in the plugin's "init" action, so we must set our hooks before that
add_action( 'init', 'MLAOptions::initialize', 9 );
} else {
add_action( 'init', 'MLAOptions::initialize', 0x7FFFFFFF );
}
// Plugin settings management page
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-settings.php' );
add_action( 'init', 'MLASettings::initialize', 0x7FFFFFFF );
// Main program
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-main.php' );
add_action( 'init', 'MLA::initialize', 0x7FFFFFFF );
// Edit Media screen additions, e.g., meta boxes
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-edit-media.php' );
add_action( 'init', 'MLAEdit::initialize', 0x7FFFFFFF );
// Media Manager (Modal window) additions
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-media-modal.php' );
add_action( 'init', 'MLAModal::initialize', 0x7FFFFFFF );
/*
* Custom list table package that extends the core WP_List_Table class.
* Doesn't need an initialize function; has a constructor.
*/
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-list-table.php' );
}
?>

View File

@@ -0,0 +1,22 @@
<?php
/**
* Stand-alone stream image handler for the mla_viewer
*
* @package Media Library Assistant
* @since 2.10
*/
/*
* Process mla_viewer image stream requests
*/
//@ini_set('error_log','C:\Program Files (x86)\Apache Software Foundation\Apache24\logs\php-errors.log');
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-image-processor.php' );
if ( isset( $_REQUEST['mla_stream_file'] ) ) {
MLAImageProcessor::$mla_debug = isset( $_REQUEST['mla_debug'] ) && 'log' == $_REQUEST['mla_debug'];
MLAImageProcessor::mla_process_stream_image();
}
MLAImageProcessor::_mla_die( 'mla_stream_file not set', __LINE__, 500 );
?>