This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,42 @@
<?php
/**
* A3 Lazy Load Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_A3_Lazy_Load
*/
class Visual_Portfolio_3rd_A3_Lazy_Load {
/**
* Visual_Portfolio_3rd_A3_Lazy_Load constructor.
*/
public function __construct() {
// Fix conflict with lazy loading.
add_filter( 'a3_lazy_load_skip_images_classes', array( $this, 'a3_lazy_load_skip_images_classes' ) );
}
/**
* Add lazyload class to skip.
*
* @param string $classes classes.
*
* @return string
*/
public function a3_lazy_load_skip_images_classes( $classes ) {
if ( '' !== $classes && ! empty( $classes ) ) {
$classes .= ',';
}
$classes .= 'vp-lazyload';
return $classes;
}
}
new Visual_Portfolio_3rd_A3_Lazy_Load();

View File

@ -0,0 +1,105 @@
<?php
/**
* All In One SEO Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_All_In_One_Seo
*/
class Visual_Portfolio_3rd_All_In_One_Seo {
/**
* Visual_Portfolio_3rd_All_In_One_Seo constructor.
*/
public function __construct() {
// Fixed canonical links.
add_filter( 'aioseo_canonical_url', array( 'Visual_Portfolio_Archive_Mapping', 'get_canonical' ) );
add_filter( 'aioseo_schema_output', array( $this, 'graph_schema_output' ) );
add_action( 'wp_print_footer_scripts', array( $this, 'set_query_as_archive' ), 8 ); // priority one level lower than what the plugin uses.
add_action( 'wp_print_footer_scripts', array( $this, 'remove_query_as_archive' ), 13 ); // priority one level higher than what the plugin uses.
add_action( 'wp', array( $this, 'set_query_as_archive' ), 9 );
add_action( 'wp', array( $this, 'remove_query_as_archive' ), 13 );
}
/**
* Allows changing graph output.
*
* @param array $graph - Graph output array.
* @return array
*/
public function graph_schema_output( $graph ) {
if ( isset( $graph ) && ! empty( $graph ) && is_array( $graph ) ) {
foreach ( $graph as $key => $graph_item ) {
if ( isset( $graph_item['@type'] ) ) {
switch ( $graph_item['@type'] ) {
case 'BreadcrumbList':
$graph[ $key ]['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical_anchor( $graph_item['@id'] );
break;
case 'WebPage':
case 'CollectionPage':
$graph[ $key ]['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical_anchor( $graph_item['@id'] );
$graph[ $key ]['url'] = Visual_Portfolio_Archive_Mapping::get_canonical( $graph_item['@id'] );
$graph[ $key ]['breadcrumb']['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical_anchor( $graph_item['@id'] );
break;
}
}
}
}
return $graph;
}
/**
* Set query as archive temporary.
* This is necessary for the plugin to work correctly and set all the necessary settings in the page footer.
* Because our custom archive and taxonomy pages override the base query and interfere with the global object,
* Conflicts may occur with some SEO plugins that work this way.
* In this case, the search plugin is trying to place the assets needed for a regular page in the footer,
* While the page itself is defined as a taxonomy.
* In this case, we let the plugin know that this is not a page, but a category.
*
* @return void
*/
public function set_query_as_archive() {
if ( Visual_Portfolio_Archive_Mapping::is_category() ) {
global $wp_query;
$wp_query->is_archive = true;
$wp_query->is_single = false;
$wp_query->is_singular = false;
$wp_query->is_page = false;
$wp_query->is_post_type_archive = true;
$wp_query->is_category = true;
}
}
/**
* Set query as archive temporary.
* This is necessary for the plugin to work correctly and set all the necessary settings in the page footer.
* Because our custom archive and taxonomy pages override the base query and interfere with the global object,
* Conflicts may occur with some SEO plugins that work this way.
* In this case, the search plugin is trying to place the assets needed for a regular page in the footer,
* While the page itself is defined as a taxonomy.
* In this case, we let the plugin know that this is not a page, but a category.
* This function cancels previous settings so as not to interfere with further system operation.
*
* @return void
*/
public function remove_query_as_archive() {
if ( Visual_Portfolio_Archive_Mapping::is_category() ) {
global $wp_query;
$wp_query->is_archive = false;
$wp_query->is_single = false;
$wp_query->is_singular = true;
$wp_query->is_page = true;
$wp_query->is_post_type_archive = false;
$wp_query->is_category = false;
}
}
}
new Visual_Portfolio_3rd_All_In_One_Seo();

View File

@ -0,0 +1,43 @@
<?php
/**
* Divi Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_Divi
*/
class Visual_Portfolio_Divi {
/**
* Visual_Portfolio_Divi constructor.
*/
public function __construct() {
add_action( 'wp_head', array( $this, 'maybe_fix_images_width' ) );
}
/**
* Add CSS to fix lazy loaded Divi images widths.
* When the image has lazy loading attributes, width is set to 4px, not the actual image size.
*/
public function maybe_fix_images_width() {
if ( ! defined( 'ET_CORE' ) || 'full' !== Visual_Portfolio_Settings::get_option( 'lazy_loading', 'vp_images' ) ) {
return;
}
?>
<style type="text/css">
.et-db #et-boc .et-l .et_pb_module .et_pb_image_wrap,
.et-db #et-boc .et-l .et_pb_module .et_pb_image_wrap img[data-src] {
width: 100%;
}
</style>
<?php
}
}
new Visual_Portfolio_Divi();

View File

@ -0,0 +1,254 @@
<?php
/**
* Widget for Elementor
*
* @package visual-portfolio/elementor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Elementor_Widget
*/
class Visual_Portfolio_3rd_Elementor_Widget extends \Elementor\Widget_Base {
/**
* Constructor of Visual_Portfolio_3rd_Elementor_Widget class.
*
* @param array $data default widget data.
* @param null|array $args default widget args.
*/
public function __construct( $data = array(), $args = null ) {
// Migrate from old 'id' control to new 'saved_id'.
if ( isset( $data['settings']['id'] ) ) {
if ( $data['settings']['id'] && ( ! isset( $data['settings']['saved_id'] ) || ! $data['settings']['saved_id'] ) ) {
$data['settings']['saved_id'] = $data['settings']['id'];
}
unset( $data['settings']['id'] );
}
parent::__construct( $data, $args );
if ( $this->is_preview_mode() ) {
Visual_Portfolio_Assets::register_script( 'iframe-resizer', 'assets/vendor/iframe-resizer/js/iframeResizer.min', array(), '4.3.7' );
Visual_Portfolio_Assets::register_script( 'visual-portfolio-elementor', 'build/assets/admin/js/elementor', array( 'elementor-frontend', 'iframe-resizer' ) );
Visual_Portfolio_Assets::register_style( 'visual-portfolio-elementor', 'build/assets/admin/css/elementor' );
wp_style_add_data( 'visual-portfolio-elementor', 'rtl', 'replace' );
wp_style_add_data( 'visual-portfolio-elementor', 'suffix', '.min' );
}
}
/**
* Is edit mode check.
*
* @return boolean
*/
public function is_preview_mode() {
return \Elementor\Plugin::$instance->preview->is_preview_mode() || \Elementor\Plugin::$instance->editor->is_edit_mode();
}
/**
* Get widget name.
*
* @return string Widget name.
*/
public function get_name() {
return 'visual-portfolio';
}
/**
* Get widget title.
*
* @return string Widget title.
*/
public function get_title() {
return visual_portfolio()->plugin_name;
}
/**
* Get widget icon.
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-gallery-grid';
}
/**
* Get widget categories.
*
* @return array Widget categories.
*/
public function get_categories() {
return array( 'general' );
}
/**
* Get widget keywords.
*
* @return array Widget keywords.
*/
public function get_keywords() {
return array( 'portfolio', 'gallery', 'images', 'visual portfolio', 'vpf' );
}
/**
* Get script dependencies.
*
* @return array Widget script dependencies.
*/
public function get_script_depends() {
if ( $this->is_preview_mode() ) {
return array( 'visual-portfolio-elementor' );
}
return array();
}
/**
* We should add the prefix to all options, because Select2 conflicts with the Safari for some reason.
*
* @param String $option - option value.
*
* @return String
*/
public function set_option_prefix( $option ) {
return 'post-id-' . $option;
}
/**
* Remove prefix from the option.
*
* @param String $option - prefixed option value.
*
* @return String
*/
public function unset_option_prefix( $option ) {
return str_replace( 'post-id-', '', $option );
}
/**
* Get style dependencies.
*
* @return array Widget style dependencies.
*/
public function get_style_depends() {
if ( $this->is_preview_mode() ) {
return array( 'visual-portfolio-elementor' );
}
return array();
}
/**
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @return void
*/
protected function register_controls() {
// get all visual-portfolio post types.
// Don't use WP_Query on the admin side https://core.trac.wordpress.org/ticket/18408 .
$vp_query = get_posts(
array(
'post_type' => 'vp_lists',
'posts_per_page' => -1,
'paged' => -1,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
)
);
$options = array(
'' => esc_html__( '-- Select Layout --', 'visual-portfolio' ),
);
foreach ( $vp_query as $post ) {
$options[ $this->set_option_prefix( $post->ID ) ] = '#' . $post->ID . ' - ' . $post->post_title;
}
$this->start_controls_section(
'content_section',
array(
'label' => __( 'General', 'visual-portfolio' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
)
);
$this->add_control(
'saved_id',
array(
'label' => esc_html__( 'Saved Layout', 'visual-portfolio' ),
'type' => \Elementor\Controls_Manager::SELECT2,
'options' => $options,
'dynamic' => array(
'active' => true,
),
)
);
$this->end_controls_section();
}
/**
* Render widget output on the frontend.
*/
protected function render() {
$settings = array_merge(
array(
'saved_id' => '',
'class' => '',
),
$this->get_settings_for_display()
);
// No saved layout selected.
if ( ! $settings['saved_id'] ) {
return;
}
if ( $this->is_preview_mode() ) {
$this->add_render_attribute(
'wrapper',
array(
'class' => 'visual-portfolio-elementor-preview',
'data-id' => $this->unset_option_prefix( $settings['saved_id'] ),
)
);
}
?>
<div
<?php
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $this->get_render_attribute_string( 'wrapper' );
?>
>
<?php if ( $this->is_preview_mode() ) : ?>
<iframe allowtransparency="true"></iframe>
<?php else : ?>
<?php echo do_shortcode( '[visual_portfolio id="' . esc_attr( $this->unset_option_prefix( $settings['saved_id'] ) ) . '"]' ); ?>
<?php endif; ?>
</div>
<?php
}
/**
* Render shortcode widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 1.0.0
* @access protected
*/
protected function content_template() {}
/**
* Render Plain Content
*
* @param array $instance instance data.
*/
// phpcs:ignore
public function render_plain_content( $instance = array() ) {}
}

View File

@ -0,0 +1,160 @@
<?php
/**
* Class for Elementor
*
* @package visual-portfolio/elementor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Elementor
*/
class Visual_Portfolio_3rd_Elementor {
/**
* Lightbox fix added.
*
* @var boolean
*/
public $lightbox_fix_added = false;
/**
* Visual_Portfolio_3rd_Elementor constructor.
*/
public function __construct() {
add_action( 'elementor/widgets/register', array( $this, 'register_widget' ) );
// We should also try to include this script in the footer,
// since caching plugins place jQuery in the footer, and our script depends on it.
add_action( 'wp_body_open', array( $this, 'maybe_fix_elementor_lightbox_conflict' ) );
add_action( 'wp_footer', array( $this, 'maybe_fix_elementor_lightbox_conflict' ), 20 );
// Compatibility code for Swiper library.
add_action( 'wp_enqueue_scripts', array( $this, 'fix_elementor_swiper_assets' ), 101 );
}
/**
* Register widget
*/
public function register_widget() {
require_once visual_portfolio()->plugin_path . 'classes/3rd/plugins/class-elementor-widget.php';
\Elementor\Plugin::instance()->widgets_manager->register( new Visual_Portfolio_3rd_Elementor_Widget() );
}
/**
* Fix Elementor lightbox conflict.
*
* @see https://github.com/nk-crew/visual-portfolio/issues/103
*/
public function maybe_fix_elementor_lightbox_conflict() {
if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
return;
}
// We should check it, as we are trying to inject this script twice.
if ( $this->lightbox_fix_added ) {
return;
}
if ( ! wp_script_is( 'jquery', 'enqueued' ) ) {
return;
}
$this->lightbox_fix_added = true;
?>
<script>
(function($) {
if (!$) {
return;
}
// Previously we added this code on Elementor pages only,
// but sometimes Lightbox enabled globally and it still conflicting with our galleries.
// if (!$('.elementor-page').length) {
// return;
// }
function addDataAttribute($items) {
$items.find('.vp-portfolio__item a:not([data-elementor-open-lightbox])').each(function () {
if (/\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i.test(this.href)) {
this.dataset.elementorOpenLightbox = 'no';
}
});
}
$(document).on('init.vpf', function(event, vpObject) {
if ('vpf' !== event.namespace) {
return;
}
addDataAttribute(vpObject.$item);
});
$(document).on('addItems.vpf', function(event, vpObject, $items) {
if ('vpf' !== event.namespace) {
return;
}
addDataAttribute($items);
});
})(window.jQuery);
</script>
<?php
}
/**
* Add Swiper from the Elementor plugin to prevent conflicts.
*
* @link https://wordpress.org/support/topic/visual-portfolio-elementor-issue/ - Old Elementor (< v3.11.0) and their lightbox is not working properly if we include new Swiper library.
* @link https://wordpress.org/support/topic/elementor-image-carousel-navigation-is-affected-by-this-plugin/ - New Elementor (>= 3.11.0) added support for the latest version of Swiper library and changed their old fallback Swiper library. This is why we have to include Swiper's assets instead of ours.
*/
public function fix_elementor_swiper_assets() {
if ( ! class_exists( '\Elementor\Plugin' ) || ! isset( \Elementor\Plugin::$instance->experiments ) || ! defined( 'ELEMENTOR_URL' ) ) {
return;
}
global $wp_scripts;
global $wp_styles;
// Since the Elementor assets methods like `get_css_assets_url` are protected
// and we can't use it directly, we prepare assets URLs manually.
$e_swiper_latest = \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_swiper_latest' );
$e_swiper_asset_path = $e_swiper_latest ? 'assets/lib/swiper/v8/' : 'assets/lib/swiper/';
$e_swiper_version = $e_swiper_latest ? '8.4.5' : '5.3.6';
$e_file_name = 'swiper';
$e_assets_base_url = ELEMENTOR_URL;
$e_assets_relative_url = 'assets/';
$e_css_relative_url = $e_swiper_asset_path . 'css/';
$e_js_relative_url = $e_swiper_asset_path;
if ( ! $e_css_relative_url ) {
$e_css_relative_url = $e_assets_relative_url . 'css/';
}
if ( ! $e_js_relative_url ) {
$e_js_relative_url = $e_assets_relative_url;
}
$e_swiper_css_url = $e_assets_base_url . $e_css_relative_url . $e_file_name . '.css';
$e_swiper_js_url = $e_assets_base_url . $e_js_relative_url . $e_file_name . '.js';
// Elementor < 3.11.0 does not have a Swiper CSS file.
if ( version_compare( ELEMENTOR_VERSION, '3.11.0', '<' ) ) {
$e_swiper_css_url = visual_portfolio()->plugin_url . 'assets/vendor/swiper-5-3-6/swiper.min.css';
}
// Since we include Swiper library ourselves, here we have to override assets URLs.
if ( isset( $wp_scripts->registered['swiper']->src ) ) {
$wp_scripts->registered['swiper']->src = $e_swiper_js_url;
$wp_scripts->registered['swiper']->ver = $e_swiper_version;
}
if ( isset( $wp_styles->registered['swiper']->src ) ) {
$wp_styles->registered['swiper']->src = $e_swiper_css_url;
$wp_styles->registered['swiper']->ver = $e_swiper_version;
}
}
}
new Visual_Portfolio_3rd_Elementor();

View File

@ -0,0 +1,30 @@
<?php
/**
* EWWW Image Optimizer Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Ewww_Image_Optimizer
*/
class Visual_Portfolio_3rd_Ewww_Image_Optimizer {
/**
* Visual_Portfolio_3rd_Ewww_Image_Optimizer constructor.
*/
public function __construct() {
if ( ! function_exists( 'ewww_image_optimizer_get_option' ) || ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_lazy_load' ) ) {
return;
}
// Disable our lazyload if EWWW lazyload used.
add_filter( 'vpf_images_lazyload', '__return_false' );
add_filter( 'vpf_enqueue_plugin_lazysizes', '__return_false' );
}
}
new Visual_Portfolio_3rd_Ewww_Image_Optimizer();

View File

@ -0,0 +1,67 @@
<?php
/**
* Imagify Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Imagify
*/
class Visual_Portfolio_3rd_Imagify {
/**
* Visual_Portfolio_3rd_Imagify constructor.
*/
public function __construct() {
// Fix lazyload attributes.
//
// Thanks to:
// - https://wordpress.org/support/topic/all-images-are-grey/
// - https://wordpress.org/support/topic/all-images-are-grey-again/.
add_filter( 'imagify_picture_attributes', array( $this, 'imagify_picture_attributes' ) );
add_filter( 'imagify_picture_img_attributes', array( $this, 'imagify_picture_img_attributes' ), 10, 2 );
}
/**
* Remove lazyload class from the picture tag.
*
* @param array $attributes image tag attributes.
*
* @return array
*/
public function imagify_picture_attributes( $attributes ) {
if ( isset( $attributes['class'] ) && strpos( $attributes['class'], 'vp-lazyload' ) !== false ) {
$attributes['class'] = str_replace( 'vp-lazyload', '', $attributes['class'] );
}
return $attributes;
}
/**
* Restore lazyload class to the img tag.
*
* @param array $attributes image tag attributes.
* @param array $image image data.
*
* @return array
*/
public function imagify_picture_img_attributes( $attributes, $image ) {
if ( isset( $image['attributes']['class'] ) && strpos( $image['attributes']['class'], 'vp-lazyload' ) !== false ) {
if ( isset( $attributes['class'] ) ) {
$attributes['class'] .= ' ';
} else {
$attributes['class'] = '';
}
$attributes['class'] .= 'vp-lazyload';
}
return $attributes;
}
}
new Visual_Portfolio_3rd_Imagify();

View File

@ -0,0 +1,55 @@
<?php
/**
* Jetpack Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Jetpack
*/
class Visual_Portfolio_3rd_Jetpack {
/**
* Visual_Portfolio_3rd_Jetpack constructor.
*/
public function __construct() {
// Fix conflict with lazy loading.
add_filter( 'jetpack_lazy_images_skip_image_with_attributes', array( $this, 'jetpack_lazy_images_skip_image_with_attributes' ), 15, 2 );
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ), 20 );
}
/**
* We need to init the Jetpack lazy loading manually after Visual Portfolio AJAX completed.
*/
public function wp_enqueue_scripts() {
$wp_scripts = wp_scripts();
$jetpack_ll_handler = 'jetpack-lazy-images';
if ( ! isset( $wp_scripts->registered[ $jetpack_ll_handler ] ) ) {
return;
}
Visual_Portfolio_Assets::register_script( 'visual-portfolio-3rd-jetpack', 'build/assets/js/3rd/plugin-jetpack' );
$wp_scripts->registered[ $jetpack_ll_handler ]->deps[] = 'visual-portfolio-3rd-jetpack';
}
/**
* Skip Jetpack lazy loading when data-src attribute added to image.
*
* @param boolean $return skip lazy Jetpack.
* @param array $attributes image attributes.
*
* @return boolean
*/
public function jetpack_lazy_images_skip_image_with_attributes( $return, $attributes ) {
return isset( $attributes['data-src'] );
}
}
new Visual_Portfolio_3rd_Jetpack();

View File

@ -0,0 +1,30 @@
<?php
/**
* Lazy Loader Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Lazy_Loader
*/
class Visual_Portfolio_3rd_Lazy_Loader {
/**
* Visual_Portfolio_3rd_Lazy_Loader constructor.
*/
public function __construct() {
if ( ! class_exists( 'FlorianBrinkmann\LazyLoadResponsiveImages\Plugin' ) ) {
return;
}
// Disable our lazyload if Lazy Loader plugin installed.
add_filter( 'vpf_images_lazyload', '__return_false' );
add_filter( 'vpf_enqueue_plugin_lazysizes', '__return_false' );
}
}
new Visual_Portfolio_3rd_Lazy_Loader();

View File

@ -0,0 +1,41 @@
<?php
/**
* Paid Memberships Pro Plugin.
*
* @package visual-portfolio/pmp
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Paid_Memberships_Pro
*/
class Visual_Portfolio_3rd_Paid_Memberships_Pro {
/**
* Visual_Portfolio_3rd_Paid_Memberships_Pro constructor.
*/
public function __construct() {
add_action( 'init', array( $this, 'fix_pmpromh_redirect_in_preview' ) );
}
/**
* Remove redirect action from the preview frame.
* Because "Paid Memberships Pro - Member Homepages Add On" make their own redirect and our preview frame failed to load.
*/
public function fix_pmpromh_redirect_in_preview() {
if ( ! function_exists( 'pmpromh_template_redirect_homepage' ) ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( ! isset( $_GET['vp_preview'] ) ) {
return;
}
remove_action( 'template_redirect', 'pmpromh_template_redirect_homepage' );
}
}
new Visual_Portfolio_3rd_Paid_Memberships_Pro();

View File

@ -0,0 +1,85 @@
<?php
/**
* Rank Math SEO Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Rank_Math
*/
class Visual_Portfolio_3rd_Rank_Math {
/**
* Visual_Portfolio_3rd_Rank_Math constructor.
*/
public function __construct() {
// Fixed canonical links.
add_filter( 'rank_math/frontend/canonical', array( 'Visual_Portfolio_Archive_Mapping', 'get_canonical' ) );
add_filter( 'rank_math/frontend/title', array( $this, 'get_title' ) );
add_filter( 'rank_math/opengraph/facebook/og_title', array( $this, 'get_title' ) );
add_action( 'rank_math/head', array( $this, 'set_query_as_archive' ), 5 ); // priority one level lower than what the plugin uses.
add_action( 'rank_math/head', array( $this, 'remove_query_as_archive' ), 23 ); // priority one level higher than what the plugin uses.
}
/**
* Allow changing the Rank Math generated title.
*
* @param string $title - Current Page Title.
* @return string
*/
public function get_title( $title ) {
return Visual_Portfolio_Archive_Mapping::get_current_term_title() ?? $title;
}
/**
* Set query as archive temporary.
* This is necessary for the plugin to work correctly and set all the necessary settings in the page header.
* Because our custom archive and taxonomy pages override the base query and interfere with the global object,
* Conflicts may occur with some SEO plugins that work this way.
* In this case, the search plugin is trying to place the assets needed for a regular page in the header,
* While the page itself is defined as a taxonomy.
* In this case, we let the plugin know that this is not a page, but a category.
*
* @return void
*/
public function set_query_as_archive() {
if ( Visual_Portfolio_Archive_Mapping::is_category() ) {
global $wp_query;
$wp_query->is_archive = true;
$wp_query->is_single = false;
$wp_query->is_singular = false;
$wp_query->is_page = false;
$wp_query->is_post_type_archive = true;
}
}
/**
* Remove query as archive temporary.
* This is necessary for the plugin to work correctly and set all the necessary settings in the page header.
* Because our custom archive and taxonomy pages override the base query and interfere with the global object,
* Conflicts may occur with some SEO plugins that work this way.
* In this case, the search plugin is trying to place the assets needed for a regular page in the header,
* While the page itself is defined as a taxonomy.
* In this case, we let the plugin know that this is not a page, but a category.
* This function cancels previous settings so as not to interfere with further system operation.
*
* @return void
*/
public function remove_query_as_archive() {
if ( Visual_Portfolio_Archive_Mapping::is_category() ) {
global $wp_query;
$wp_query->is_archive = false;
$wp_query->is_single = true;
$wp_query->is_singular = true;
$wp_query->is_page = true;
$wp_query->is_post_type_archive = false;
}
}
}
new Visual_Portfolio_3rd_Rank_Math();

View File

@ -0,0 +1,87 @@
<?php
/**
* SiteGround Optimizer Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_SG_Cachepress
*/
class Visual_Portfolio_3rd_SG_Cachepress {
/**
* Visual_Portfolio_3rd_SG_Cachepress constructor.
*/
public function __construct() {
if ( ! class_exists( '\SiteGround_Optimizer\Options\Options' ) || ! \SiteGround_Optimizer\Options\Options::is_enabled( 'siteground_optimizer_lazyload_images' ) ) {
return;
}
// Disable our lazyload if SiteGround Optimizer lazyload used.
add_filter( 'vpf_images_lazyload', '__return_false' );
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ), 20 );
}
/**
* SG lazy loading breaks our scripts which calculate size of the images,
* we need to resolve it in a hacky way by changing src placeholder.
*/
public function wp_enqueue_scripts() {
$wp_scripts = wp_scripts();
$sg_ll_handler = 'siteground-optimizer-lazy-sizes-js';
if ( ! isset( $wp_scripts->registered[ $sg_ll_handler ] ) ) {
return;
}
$wp_scripts->registered[ $sg_ll_handler ]->deps[] = 'jquery';
wp_add_inline_script(
$sg_ll_handler,
'(function($){
if ( !$ ) {
return;
}
function maybeFixSGSrc( $images ) {
$images.find( "img[src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\"]" ).each( function() {
var $img = $( this );
var width = $img.attr( "width" );
var height = $img.attr( "height" );
if ( width && height ) {
var newSrc = "<svg width=\"" + width + "\" height=\"" + height + "\" viewBox=\"0 0 " + width + " " + height + "\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"></svg>";
newSrc = newSrc
.replace( /</g, "%3c" )
.replace( />/g, "%3e" )
.replace( /#/g, "%23" )
.replace( /"/g, "\'" );
$img.attr( "src", "data:image/svg+xml;utf8," + newSrc );
}
} );
}
// Fix starter images.
maybeFixSGSrc( $( ".vp-portfolio__items" ) );
// Fix AJAX loaded images.
$( document ).on( "addItems.vpf", function ( event, self, $items, removeExisting ) {
if ( "vpf" !== event.namespace ) {
return;
}
maybeFixSGSrc( $items );
} );
}(window.jQuery));',
'before'
);
}
}
new Visual_Portfolio_3rd_SG_Cachepress();

View File

@ -0,0 +1,107 @@
<?php
/**
* Extend TinyMCE toolbar
*
* @package visual-portfolio/tinymce
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_TinyMCE
*/
class Visual_Portfolio_3rd_TinyMCE {
/**
* Visual_Portfolio_3rd_TinyMCE constructor.
*/
public function __construct() {
$this->init_hooks();
}
/**
* Hooks.
*/
public function init_hooks() {
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'admin_head', array( $this, 'admin_head' ) );
}
/**
* Admin Head Action.
*/
public function admin_head() {
if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) ) {
add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins' ) );
add_filter( 'mce_buttons', array( $this, 'mce_buttons' ) );
}
}
/**
* Enqueue admin scripts
*
* @param string $page - page name.
*/
public function admin_enqueue_scripts( $page ) {
if ( 'post.php' === $page || 'post-new.php' === $page ) {
// add tiny mce data.
$data_tiny_mce = array(
'plugin_name' => visual_portfolio()->plugin_name,
'layouts' => array(),
);
// get all visual-portfolio post types.
// Don't use WP_Query on the admin side https://core.trac.wordpress.org/ticket/18408 .
$vp_query = get_posts(
array(
'post_type' => 'vp_lists',
'posts_per_page' => -1,
'paged' => -1,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
)
);
foreach ( $vp_query as $post ) {
$data_tiny_mce['layouts'][] = array(
'id' => $post->ID,
'title' => '#' . $post->ID . ' - ' . $post->post_title,
);
}
// return if no data.
if ( empty( $data_tiny_mce['layouts'] ) ) {
return;
}
Visual_Portfolio_Assets::enqueue_script( 'visual-portfolio-tinymce-localize', 'build/assets/admin/js/mce-localize' );
wp_localize_script( 'visual-portfolio-tinymce-localize', 'VPTinyMCEData', $data_tiny_mce );
}
}
/**
* Add script for button
*
* @param array $plugins - available plugins.
*
* @return mixed
*/
public function mce_external_plugins( $plugins ) {
$plugins['visual_portfolio'] = visual_portfolio()->plugin_url . 'build/assets/admin/js/mce-dropdown.js';
return $plugins;
}
/**
* Add dropdown button to tinymce
*
* @param array $buttons - available buttons.
*
* @return mixed
*/
public function mce_buttons( $buttons ) {
array_push( $buttons, 'visual_portfolio' );
return $buttons;
}
}
new Visual_Portfolio_3rd_TinyMCE();

View File

@ -0,0 +1,99 @@
<?php
/**
* Shortcode for Visual Composer
*
* @package visual-portfolio/vc
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_VC
*/
class Visual_Portfolio_3rd_VC {
/**
* Visual_Portfolio_3rd_VC constructor.
*/
public function __construct() {
$this->init_hooks();
}
/**
* Hooks.
*/
public function init_hooks() {
add_action( 'init', array( $this, 'add_shortcode' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
}
/**
* Enqueue script for frontend VC
*
* @param object $page - page object.
*/
public function admin_enqueue_scripts( $page ) {
if ( 'post.php' === $page || 'post-new.php' === $page ) {
Visual_Portfolio_Assets::enqueue_script( 'visual-portfolio-vc-frontend', 'build/assets/admin/js/vc-frontend' );
}
}
/**
* Add shortcode to the visual composer
*/
public function add_shortcode() {
if ( function_exists( 'vc_map' ) ) {
// get all visual-portfolio post types.
// Don't use WP_Query on the admin side https://core.trac.wordpress.org/ticket/18408 .
$vp_query = get_posts(
array(
'post_type' => 'vp_lists',
'posts_per_page' => -1,
'paged' => -1,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
)
);
$data_vc = array();
foreach ( $vp_query as $post ) {
$data_vc[] = array( $post->ID, '#' . $post->ID . ' - ' . $post->post_title );
}
vc_map(
array(
'name' => visual_portfolio()->plugin_name,
'base' => 'visual_portfolio',
'controls' => 'full',
'icon' => 'icon-visual-portfolio',
'params' => array(
array(
'type' => 'dropdown',
'heading' => esc_html__( 'Select Layout', 'visual-portfolio' ),
'param_name' => 'id',
'value' => $data_vc,
'description' => '',
'admin_label' => true,
),
array(
'type' => 'textfield',
'heading' => esc_html__( 'Custom Classes', 'visual-portfolio' ),
'param_name' => 'class',
'value' => '',
'description' => '',
),
array(
'type' => 'css_editor',
'heading' => esc_html__( 'CSS', 'visual-portfolio' ),
'param_name' => 'vc_css',
'group' => esc_html__( 'Design Options', 'visual-portfolio' ),
),
),
)
);
}
}
}
new Visual_Portfolio_3rd_VC();

View File

@ -0,0 +1,40 @@
<?php
/**
* WP Rocket Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_WP_Rocket
*/
class Visual_Portfolio_3rd_WP_Rocket {
/**
* Visual_Portfolio_3rd_WP_Rocket constructor.
*/
public function __construct() {
// Fix conflict with lazy loading.
add_filter( 'rocket_delay_js_exclusions', array( $this, 'rocket_delay_js_exclusions' ) );
}
/**
* Exclude all our lazysizes scripts from delayed loading,
* because WP Rocket excluded lazysizes automatically, but not other assets,
* this causes problems with lazy loading.
*
* @param array $excluded excluded scripts.
*
* @return array
*/
public function rocket_delay_js_exclusions( $excluded ) {
$excluded[] = 'visual-portfolio/assets/js/lazysizes';
return $excluded;
}
}
new Visual_Portfolio_3rd_WP_Rocket();

View File

@ -0,0 +1,166 @@
<?php
/**
* Register some fields for WPML.
*
* @package visual-portfolio/preview
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
/**
* Class Visual_Portfolio_3rd_WPML
*/
class Visual_Portfolio_3rd_WPML {
/**
* Archive Page.
*
* @var int $archive_page
*/
private $archive_page = null;
/**
* Visual_Portfolio_3rd_WPML constructor.
*/
public function __construct() {
global $iclTranslationManagement;
if ( class_exists( 'SitePress' ) ) {
add_action( 'init', array( $this, 'init' ), 9 );
}
if ( ! isset( $iclTranslationManagement ) ) {
return;
}
add_filter( 'vpf_registered_controls', array( $this, 'make_control_translatable' ) );
add_filter( 'vpf_extend_options_before_query_args', array( $this, 'prepare_custom_query_taxonomies' ) );
}
/**
* Initialize archive.
*
* @see __construct
*/
public function init() {
$this->archive_page = Visual_Portfolio_Settings::get_option( 'portfolio_archive_page', 'vp_general' );
if ( isset( $this->archive_page ) && ! empty( $this->archive_page ) ) {
add_action( 'wp_insert_post', array( $this, 'set_archive_meta' ), 10, 1 );
}
}
/**
* Set Archive Meta.
*
* @param int $post_id - Post ID.
* @return void
*/
public function set_archive_meta( $post_id ) {
$translate_page_id = self::get_object_id( $this->archive_page );
if ( $translate_page_id === $post_id ) {
visual_portfolio()->defer_flush_rewrite_rules();
update_post_meta( (int) $post_id, '_vp_post_type_mapped', 'portfolio' );
}
}
/**
* Get wpml object ID.
*
* @param int $post_id - Post ID.
* @return int
*/
public static function get_object_id( $post_id ) {
if ( class_exists( 'SitePress' ) ) {
return apply_filters( 'wpml_object_id', $post_id, 'page', true );
}
return $post_id;
}
/**
* Make Control Translatable.
* https://wpml.org/forums/topic/unable-to-save-custom-field-translation-settings-when-acf-ml-is-installed/
*
* @param array $controls - controls array.
*
* @return array
*/
public function make_control_translatable( $controls ) {
global $iclTranslationManagement;
$allow_save = false;
// Prepare Saved Layouts meta fields.
foreach ( $controls as $control ) {
$name = 'vp_' . $control['name'];
// Create initial arrays.
if ( ! isset( $iclTranslationManagement->settings['custom_fields_translation'] ) ) {
$iclTranslationManagement->settings['custom_fields_translation'] = array();
}
if ( ! isset( $iclTranslationManagement->settings['custom_fields_readonly_config'] ) ) {
$iclTranslationManagement->settings['custom_fields_readonly_config'] = array();
}
// Add fields translation.
if ( ! isset( $iclTranslationManagement->settings['custom_fields_translation'][ $name ] ) ) {
$iclTranslationManagement->settings['custom_fields_translation'][ $name ] = $control['wpml'] ? WPML_TRANSLATE_CUSTOM_FIELD : WPML_COPY_CUSTOM_FIELD;
$allow_save = true;
}
// Add fields read only.
if ( ! in_array( $name, $iclTranslationManagement->settings['custom_fields_readonly_config'], true ) ) {
$iclTranslationManagement->settings['custom_fields_readonly_config'][] = $name;
$allow_save = true;
}
}
// Images meta array.
if ( ! isset( $iclTranslationManagement->settings['custom_fields_attributes_whitelist']['vp_images'] ) ) {
$iclTranslationManagement->settings['custom_fields_attributes_whitelist']['vp_images'] = array(
'*' => array(
'title' => array(),
'description' => array(),
'author' => array(),
'categories' => array(),
),
);
$allow_save = true;
}
if ( $allow_save ) {
$iclTranslationManagement->save_settings();
}
return $controls;
}
/**
* Convert custom taxonomies to the current language.
*
* @param array $options - query options.
*
* @return array
*/
public function prepare_custom_query_taxonomies( $options ) {
if ( isset( $options['posts_taxonomies'] ) && ! empty( $options['posts_taxonomies'] ) ) {
foreach ( $options['posts_taxonomies'] as $k => $taxonomy ) {
$taxonomy_data = get_term( $taxonomy );
if ( isset( $taxonomy_data->taxonomy ) ) {
$options['posts_taxonomies'][ $k ] = apply_filters( 'wpml_object_id', $taxonomy, $taxonomy_data->taxonomy, true );
}
}
}
return $options;
}
}
new Visual_Portfolio_3rd_WPML();

View File

@ -0,0 +1,73 @@
<?php
/**
* Yoast SEO Plugin.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Yoast
*/
class Visual_Portfolio_3rd_Yoast {
/**
* Visual_Portfolio_3rd_Yoast constructor.
*/
public function __construct() {
// Fixed canonical links.
add_filter( 'wpseo_canonical', array( 'Visual_Portfolio_Archive_Mapping', 'get_canonical' ), 12, 1 );
add_filter( 'wpseo_opengraph_url', array( 'Visual_Portfolio_Archive_Mapping', 'get_canonical' ), 12, 1 );
add_filter( 'wpseo_schema_webpage', array( $this, 'graph_schema_webpage' ), 12, 1 );
add_filter( 'wpseo_schema_breadcrumb', array( $this, 'graph_schema_breadcrumb' ), 12, 1 );
add_filter( 'wpseo_opengraph_title', array( $this, 'graph_title' ), 12, 1 );
}
/**
* Allows changing webpage graph piece output.
*
* @param array $webpage_graph_piece - The webpage graph piece to filter.
* @return array
*/
public function graph_schema_webpage( $webpage_graph_piece ) {
$webpage_graph_piece['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical( $webpage_graph_piece['@id'] );
$webpage_graph_piece['url'] = Visual_Portfolio_Archive_Mapping::get_canonical( $webpage_graph_piece['url'] );
$webpage_graph_piece['breadcrumb']['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical_anchor( $webpage_graph_piece['breadcrumb']['@id'] );
$webpage_graph_piece['name'] = Visual_Portfolio_Archive_Mapping::get_current_term_title() ?? $webpage_graph_piece['name'];
if ( ! empty( $webpage_graph_piece['potentialAction'] ) ) {
foreach ( $webpage_graph_piece['potentialAction'] as $key => $potential_action ) {
if ( isset( $potential_action['target'] ) && ! is_array( $potential_action['target'] ) && isset( $potential_action['@type'] ) && 'ReadAction' === $potential_action['@type'] ) {
$webpage_graph_piece['potentialAction'][ $key ]['target'] = Visual_Portfolio_Archive_Mapping::get_canonical( $potential_action['target'] );
}
}
}
return $webpage_graph_piece;
}
/**
* Allows changing breadcrumb graph piece output.
*
* @param array $breadcrumb_graph_piece - The breadcrumb graph piece to filter.
* @return array
*/
public function graph_schema_breadcrumb( $breadcrumb_graph_piece ) {
$breadcrumb_graph_piece['@id'] = Visual_Portfolio_Archive_Mapping::get_canonical_anchor( $breadcrumb_graph_piece['@id'] );
return $breadcrumb_graph_piece;
}
/**
* Allow changing the Yoast SEO generated title.
*
* @param string $title - Current Graph Title.
* @return string
*/
public function graph_title( $title ) {
return Visual_Portfolio_Archive_Mapping::get_current_term_title() ?? $title;
}
}
new Visual_Portfolio_3rd_Yoast();

View File

@ -0,0 +1,37 @@
<?php
/**
* Avada Theme.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Avada
*/
class Visual_Portfolio_3rd_Avada {
/**
* Visual_Portfolio_3rd_Avada constructor.
*/
public function __construct() {
if ( is_admin() ) {
return;
}
$avada_options = get_option( 'fusion_options' );
// Important - Avada folder is in uppercase, this is not a mistake.
if ( 'Avada' !== get_template() || ! isset( $avada_options['lazy_load'] ) || 'avada' !== $avada_options['lazy_load'] ) {
return;
}
// Disable our lazyload if Avada's lazyload used.
add_filter( 'vpf_images_lazyload', '__return_false' );
add_filter( 'vpf_enqueue_plugin_lazysizes', '__return_false' );
}
}
new Visual_Portfolio_3rd_Avada();

View File

@ -0,0 +1,82 @@
<?php
/**
* Enfold Theme.
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Enfold
*/
class Visual_Portfolio_3rd_Enfold {
/**
* Cache for lazy loading option
*
* @var string
*/
public $lazy_loading_option_cache = null;
/**
* Visual_Portfolio_3rd_Enfold constructor.
*/
public function __construct() {
if ( is_admin() ) {
return;
}
if ( 'enfold' !== get_template() ) {
return;
}
// Disable Enfold lightbox by adding classname.
add_filter( 'vpf_extend_portfolio_class', array( $this, 'disable_lightbox_class' ) );
// Disable our lazyload if Enfold lazyload enabled.
add_filter( 'vpf_images_lazyload', array( $this, 'disable_lazy_load' ) );
}
/**
* Disable Enfold lightbox by adding classname.
*
* @param string $class - portfolio block classname.
*
* @return string
*/
public function disable_lightbox_class( $class ) {
$class .= ' noLightbox';
return $class;
}
/**
* Disable VPF lazy load if Enfold uses their own.
*
* @param boolean $return - portfolio block classname.
*
* @return boolean
*/
public function disable_lazy_load( $return ) {
$enfold_option = '';
if ( null !== $this->lazy_loading_option_cache ) {
$enfold_option = $this->lazy_loading_option_cache;
} elseif ( function_exists( 'avia_get_option' ) ) {
$enfold_option = avia_get_option( 'lazy_loading', '' );
}
if ( null === $this->lazy_loading_option_cache ) {
$this->lazy_loading_option_cache = $enfold_option;
}
if ( '' === $enfold_option ) {
return false;
}
return $return;
}
}
new Visual_Portfolio_3rd_Enfold();

View File

@ -0,0 +1,36 @@
<?php
/**
* Thrive Architect Theme Builder.
* This builder overrides page output and we can't enqueue inline dynamic styles using `wp_add_inline_style`
*
* @package visual-portfolio
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Visual_Portfolio_3rd_Thrive_Architect
*/
class Visual_Portfolio_3rd_Thrive_Architect {
/**
* Visual_Portfolio_3rd_Thrive_Architect constructor.
*/
public function __construct() {
add_action( 'init', array( $this, 'init' ) );
}
/**
* Init action.
*/
public function init() {
if ( ! function_exists( 'tcb_custom_editable_content' ) ) {
return;
}
add_filter( 'vpf_enqueue_dynamic_styles_inline_style', '__return_false' );
}
}
new Visual_Portfolio_3rd_Thrive_Architect();