Create New Item
×
Item Type
File
Folder
Item Name
×
Search file in folder and subfolders...
File Manager
/
wp-content
/
plugins
/
powerpack-elements
/
classes
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php /** * PowerPack Template Library. * * @package PowerPackElements */ namespace PowerpackElements\Classes; use Elementor\Plugin; use Elementor\TemplateLibrary\Source_Base; use Elementor\TemplateLibrary\Source_Local; use Elementor\Core\Common\Modules\Ajax\Module as Ajax; use Elementor\User; /** * PowerPack Template Library. * * @since 1.6.0 */ class PP_Templates_Lib { /** * PowerPack library option key. */ const LIBRARY_OPTION_KEY = 'pp_templates_library'; /** * API templates URL. * * Holds the URL of the templates API. * * @access public * @static * * @var string API URL. */ public static $api_url = 'https://demo.powerpackelements.com/api/powerpack/v1/templates'; /** * Init. * * Initializes the hooks. * * @since 1.6.0 * @access public * * @return void */ public static function init() { add_action( 'elementor/init', [ __CLASS__, 'register_source' ] ); add_action( 'elementor/editor/after_enqueue_scripts', [ __CLASS__, 'enqueue_editor_scripts' ] ); add_action( 'elementor/ajax/register_actions', [ __CLASS__, 'register_ajax_actions' ] ); add_action( 'elementor/editor/footer', [ __CLASS__, 'render_template' ] ); // add_action( 'wp_ajax_elementor_reset_library', [ __CLASS__, 'ajax_reset_api_data' ] ); @codingStandardsIgnoreLine. } /** * Register source. * * Registers the library source. * * @since 1.6.0 * @access public * * @return void */ public static function register_source() { Plugin::$instance->templates_manager->register_source( __NAMESPACE__ . '\PP_Source' ); } /** * Enqueue Editor Scripts. * * Enqueues required scripts in Elementor edit mode. * * @since 1.6.0 * @access public * * @return void */ public static function enqueue_editor_scripts() { wp_enqueue_script( 'powerpack-templates-lib', POWERPACK_ELEMENTS_URL . 'assets/js/pp-templates-lib.js', [ 'jquery', 'backbone-marionette', 'backbone-radio', 'elementor-common-modules', 'elementor-dialog', 'powerpack-editor', ], POWERPACK_ELEMENTS_VER, true ); wp_localize_script( 'powerpack-templates-lib', 'pp_templates_lib', array( 'logoUrl' => POWERPACK_ELEMENTS_URL . 'assets/images/pp-logo-sm.png', ) ); } /** * Init ajax calls. * * Initialize template library ajax calls for allowed ajax requests. * * @since 1.6.0 * @access public * * @param Ajax $ajax Elementor's Ajax object. * @return void */ public static function register_ajax_actions( Ajax $ajax ) { $library_ajax_requests = [ 'pp_get_library_data', ]; foreach ( $library_ajax_requests as $ajax_request ) { $ajax->register_ajax_action( $ajax_request, function( $data ) use ( $ajax_request ) { return self::handle_ajax_request( $ajax_request, $data ); } ); } } /** * Handle ajax request. * * Fire authenticated ajax actions for any given ajax request. * * @since 1.6.0 * @access private * * @param string $ajax_request Ajax request. * @param array $data Elementor data. * * @return mixed * @throws \Exception Throws error message. */ private static function handle_ajax_request( $ajax_request, array $data ) { if ( ! User::is_current_user_can_edit_post_type( Source_Local::CPT ) ) { throw new \Exception( 'Access Denied' ); } if ( ! empty( $data['editor_post_id'] ) ) { $editor_post_id = absint( $data['editor_post_id'] ); if ( ! get_post( $editor_post_id ) ) { throw new \Exception( __( 'Post not found.', 'powerpack' ) ); } Plugin::$instance->db->switch_to_post( $editor_post_id ); } $result = call_user_func( [ __CLASS__, $ajax_request ], $data ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return $result; } /** * Get library data. * * Get data for template library. * * @since 1.6.0 * @access public * * @param array $args Arguments. * * @return array Collection of templates data. */ public static function pp_get_library_data( array $args ) { $library_data = self::get_library_data( ! empty( $args['sync'] ) ); // Ensure all document are registered. Plugin::$instance->documents->get_document_types(); return [ 'templates' => self::get_templates(), 'config' => $library_data['types_data'], ]; } /** * Get templates. * * Retrieve all the templates from all the registered sources. * * @since 1.16.0 * @access public * * @return array Templates array. */ public static function get_templates() { $source = Plugin::$instance->templates_manager->get_source( 'powerpack' ); return $source->get_items(); } /** * Ajax reset API data. * * Reset Elementor library API data using an ajax call. * * @since 1.6.0 * @access public * @static */ public static function ajax_reset_api_data() { check_ajax_referer( 'elementor_reset_library', '_nonce' ); self::get_templates_data( true ); wp_send_json_success(); } /** * Get templates data. * * This function the templates data. * * @since 1.6.0 * @access private * @static * * @param bool $force_update Optional. Whether to force the data retrieval or * not. Default is false. * * @return array|false Templates data, or false. */ private static function get_templates_data( $force_update = false ) { $cache_key = 'pp_templates_data_' . POWERPACK_ELEMENTS_VER; $templates_data = get_transient( $cache_key ); if ( $force_update || false === $templates_data ) { $timeout = ( $force_update ) ? 25 : 8; $response = wp_remote_get( self::$api_url, [ 'timeout' => $timeout, 'body' => [ // Which API version is used. 'api_version' => POWERPACK_ELEMENTS_VER, // Which language to return. 'site_lang' => get_bloginfo( 'language' ), ], ] ); if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { set_transient( $cache_key, [], 2 * HOUR_IN_SECONDS ); return false; } $templates_data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( empty( $templates_data ) || ! is_array( $templates_data ) ) { set_transient( $cache_key, [], 2 * HOUR_IN_SECONDS ); return false; } if ( isset( $templates_data['library'] ) ) { update_option( self::LIBRARY_OPTION_KEY, $templates_data['library'], 'no' ); unset( $templates_data['library'] ); } set_transient( $cache_key, $templates_data, 12 * HOUR_IN_SECONDS ); } return $templates_data; } /** * Get templates data. * * Retrieve the templates data from a remote server. * * @since 1.6.0 * @access public * @static * * @param bool $force_update Optional. Whether to force the data update or * not. Default is false. * * @return array The templates data. */ public static function get_library_data( $force_update = false ) { self::get_templates_data( $force_update ); $library_data = get_option( self::LIBRARY_OPTION_KEY ); if ( empty( $library_data ) ) { return []; } return $library_data; } /** * Get template content. * * Retrieve the templates content received from a remote server. * * @since 1.6.0 * @access public * @static * * @param int $template_id The template ID. * * @return object|\WP_Error The template content. */ public static function get_template_content( $template_id ) { $url = self::$api_url . '/' . $template_id; $license_key = null; if ( function_exists( 'pp_get_license_key' ) ) { $license_key = pp_get_license_key(); } if ( ! defined( 'POWERPACK_ELEMENTS_VER' ) ) { $license_key = 'lite'; } if ( empty( $license_key ) ) { return new \WP_Error( 'no_license', __( 'License is not active.', 'powerpack' ) ); } $args = [ 'body' => [ // Which API version is used. 'api_version' => POWERPACK_ELEMENTS_VER, 'license_key' => $license_key, 'home_url' => trailingslashit( home_url() ), ], 'timeout' => 25, ]; $response = wp_remote_post( $url, $args ); if ( is_wp_error( $response ) ) { // @codingStandardsIgnoreStart WordPress.XSS.EscapeOutput. wp_die( $response, [ 'back_link' => true, ] ); // @codingStandardsIgnoreEnd WordPress.XSS.EscapeOutput. } $body = wp_remote_retrieve_body( $response ); $response_code = (int) wp_remote_retrieve_response_code( $response ); if ( ! $response_code ) { return new \WP_Error( 500, 'No Response' ); } // Server sent a success message without content. if ( 'null' === $body ) { $body = true; } $as_array = true; $body = json_decode( $body, $as_array ); if ( false === $body ) { return new \WP_Error( 422, 'Wrong Server Response' ); } if ( 200 !== $response_code ) { // In case $as_array = true. $body = (object) $body; $message = isset( $body->message ) ? $body->message : wp_remote_retrieve_response_message( $response ); $code = isset( $body->code ) ? $body->code : $response_code; return new \WP_Error( $code, $message ); } return $body; } /** * Render template. * * Library modal template. * * @since 1.6.0 * @access public * @static * * @return void */ public static function render_template() { ?> <script type="text/template" id="tmpl-elementor-template-library-header-actions-pp"> <div id="elementor-template-library-header-sync" class="elementor-templates-modal__header__item"> <i class="eicon-sync" aria-hidden="true" title="<?php esc_attr_e( 'Sync Templates', 'powerpack' ); ?>"></i> <span class="elementor-screen-only"><?php echo esc_html__( 'Sync Templates', 'powerpack' ); ?></span> </div> </script> <script type="text/template" id="tmpl-elementor-templates-modal__header__logo_pp"> <span class="elementor-templates-modal__header__logo__icon-wrapper"> <img src="<?php echo esc_url( POWERPACK_ELEMENTS_URL . 'assets/images/pp-logo-sm.png' ); ?>" style="height: 30px;" /> </span> <span class="elementor-templates-modal__header__logo__title">{{{ title }}}</span> </script> <script type="text/template" id="tmpl-elementor-template-library-header-preview-pp"> <div id="elementor-template-library-header-preview-insert-wrapper" class="elementor-templates-modal__header__item"> {{{ pp_templates_lib.templates.layout.getTemplateActionButton( obj ) }}} </div> </script> <script type="text/template" id="tmpl-elementor-template-library-templates-pp"> <# var activeSource = pp_templates_lib.templates.getFilter('source'); #> <div id="elementor-template-library-toolbar"> <# if ( 'powerpack' === activeSource ) { var activeType = pp_templates_lib.templates.getFilter('type'); #> <div id="elementor-template-library-filter-toolbar-remote" class="elementor-template-library-filter-toolbar"> <# if ( 'new_page' === activeType ) { #> <div id="elementor-template-library-order"> <input type="radio" id="elementor-template-library-order-new" class="elementor-template-library-order-input" name="elementor-template-library-order" value="date"> <label for="elementor-template-library-order-new" class="elementor-template-library-order-label"><?php echo esc_html__( 'New', 'powerpack' ); ?></label> <input type="radio" id="elementor-template-library-order-trend" class="elementor-template-library-order-input" name="elementor-template-library-order" value="trendIndex"> <label for="elementor-template-library-order-trend" class="elementor-template-library-order-label"><?php echo esc_html__( 'Trend', 'powerpack' ); ?></label> <input type="radio" id="elementor-template-library-order-popular" class="elementor-template-library-order-input" name="elementor-template-library-order" value="popularityIndex"> <label for="elementor-template-library-order-popular" class="elementor-template-library-order-label"><?php echo esc_html__( 'Popular', 'powerpack' ); ?></label> </div> <# } else { var config = pp_templates_lib.templates.getConfig( activeType ); if ( config.categories ) { #> <div id="elementor-template-library-filter"> <select id="elementor-template-library-filter-subtype" class="elementor-template-library-filter-select" data-elementor-filter="subtype"> <option></option> <# config.categories.forEach( function( category ) { var selected = category === pp_templates_lib.templates.getFilter( 'subtype' ) ? ' selected' : ''; #> <option value="{{ category }}"{{{ selected }}}>{{{ category }}}</option> <# } ); #> </select> </div> <# } } #> <div id="elementor-template-library-my-favorites"> <# var checked = pp_templates_lib.templates.getFilter( 'favorite' ) ? ' checked' : ''; #> <input id="elementor-template-library-filter-my-favorites" type="checkbox"{{{ checked }}}> <label id="elementor-template-library-filter-my-favorites-label" for="elementor-template-library-filter-my-favorites"> <i class="eicon" aria-hidden="true"></i> <?php echo esc_html__( 'My Favorites', 'powerpack' ); ?> </label> </div> </div> <# } #> <div id="elementor-template-library-filter-text-wrapper"> <label for="elementor-template-library-filter-text" class="elementor-screen-only"><?php echo esc_html__( 'Search Templates:', 'powerpack' ); ?></label> <input id="elementor-template-library-filter-text" placeholder="<?php echo esc_attr__( 'Search', 'powerpack' ); ?>"> <i class="eicon-search"></i> </div> </div> <div id="elementor-template-library-templates-container"></div> <# if ( 'powerpack' === activeSource ) { #> <div id="elementor-template-library-footer-banner"> <img class="elementor-nerd-box-icon" src="<?php echo esc_url( ELEMENTOR_ASSETS_URL . 'images/information.svg' ); ?>" /> <div class="elementor-excerpt"><?php echo esc_html__( 'Stay tuned! More awesome templates coming real soon.', 'powerpack' ); ?></div> </div> <# } #> </script> <script type="text/template" id="tmpl-elementor-template-library-template-pp"> <div class="elementor-template-library-template-body"> <# if ( 'page' === type ) { #> <div class="elementor-template-library-template-screenshot" style="background-image: url({{ thumbnail }});"></div> <# } else { #> <img src="{{ thumbnail }}"> <# } #> <div class="elementor-template-library-template-preview"> <i class="eicon-zoom-in-bold" aria-hidden="true"></i> </div> </div> <div class="elementor-template-library-template-footer"> {{{ pp_templates_lib.templates.layout.getTemplateActionButton( obj ) }}} <div class="elementor-template-library-template-name">{{{ title }}} - {{{ type }}}</div> <div class="elementor-template-library-favorite"> <input id="elementor-template-library-template-{{ template_id }}-favorite-input" class="elementor-template-library-template-favorite-input" type="checkbox"{{ favorite ? " checked" : "" }}> <label for="elementor-template-library-template-{{ template_id }}-favorite-input" class="elementor-template-library-template-favorite-label"> <i class="eicon-heart-o" aria-hidden="true"></i> <span class="elementor-screen-only"><?php echo esc_html__( 'Favorite', 'powerpack' ); ?></span> </label> </div> </div> </script> <script type="text/template" id="tmpl-elementor-template-library-get-pro-button-pp"> <a class="elementor-template-library-template-action elementor-button elementor-go-pro" href="https://powerpackelements.com/pricing/?utm_source=panel-library&utm_campaign=gopro&utm_medium=wp-dash" target="_blank"> <i class="eicon-external-link-square" aria-hidden="true"></i> <span class="elementor-button-title"><?php esc_html__( 'Go Pro', 'powerpack' ); ?></span> </a> </script> <script type="text/template" id="tmpl-elementor-pro-template-library-activate-license-button-pp"> <a class="elementor-template-library-template-action elementor-button elementor-go-pro" href="<?php echo PP_Admin_Settings::get_form_action(); ?>" target="_blank"> <i class="eicon-external-link-square"></i> <span class="elementor-button-title"><?php esc_html__( 'Activate License', 'powerpack' ); ?></span> </a> </script> <?php } } PP_Templates_Lib::init(); /** * Custom source. */ class PP_Source extends Source_Base { /** * Get remote template ID. * * Retrieve the remote template ID. * * @since 1.14.5 * @access public * * @return string The remote template ID. */ public function get_id() { return 'powerpack'; } /** * Get remote template title. * * Retrieve the remote template title. * * @since 1.14.5 * @access public * * @return string The remote template title. */ public function get_title() { return 'PowerPack'; } /** * Register remote template data. * * Used to register custom template data like a post type, a taxonomy or any * other data. * * @since 1.14.5 * @access public */ public function register_data() {} /** * Get remote templates. * * Retrieve remote templates from PowerpackElements.com servers. * * @since 1.14.5 * @access public * * @param array $args Optional. Nou used in remote source. * * @return array Remote templates. */ public function get_items( $args = [] ) { $library_data = PP_Templates_Lib::get_library_data(); $is_pro_active = defined( 'POWERPACK_ELEMENTS_VER' ); $pro_status = 'active'; if ( ! $is_pro_active ) { $pro_status = 'inactive'; } elseif ( 'valid' !== get_option( 'pp_license_status' ) ) { $pro_status = 'license_inactive'; } $templates = []; if ( ! empty( $library_data['templates'] ) ) { foreach ( $library_data['templates'] as $template_data ) { $data = $this->prepare_template( $template_data ); $data['proStatus'] = $pro_status; $templates[] = $data; } } return $templates; } /** * Get remote template. * * Retrieve a single remote template from PowerPackElements.com servers. * * @since 1.14.5 * @access public * * @param int $template_id The template ID. * * @return array Remote template. */ public function get_item( $template_id ) { $templates = $this->get_items(); return $templates[ $template_id ]; } /** * Save remote template. * * Remote template from PowerPackElements.com servers cannot be saved on the * database as they are retrieved from remote servers. * * @since 1.14.5 * @access public * * @param array $template_data Remote template data. * * @return \WP_Error */ public function save_item( $template_data ) { return new \WP_Error( 'invalid_request', 'Cannot save template to a remote source' ); } /** * Update remote template. * * Remote template from PowerPackElements.com servers cannot be updated on the * database as they are retrieved from remote servers. * * @since 1.14.5 * @access public * * @param array $new_data New template data. * * @return \WP_Error */ public function update_item( $new_data ) { return new \WP_Error( 'invalid_request', 'Cannot update template to a remote source' ); } /** * Delete remote template. * * Remote template from PowerPackElements.com servers cannot be deleted from the * database as they are retrieved from remote servers. * * @since 1.14.5 * @access public * * @param int $template_id The template ID. * * @return \WP_Error */ public function delete_template( $template_id ) { return new \WP_Error( 'invalid_request', 'Cannot delete template from a remote source' ); } /** * Export remote template. * * Remote template from PowerPackElements.com servers cannot be exported from the * database as they are retrieved from remote servers. * * @since 1.14.5 * @access public * * @param int $template_id The template ID. * * @return \WP_Error */ public function export_template( $template_id ) { return new \WP_Error( 'invalid_request', 'Cannot export template from a remote source' ); } /** * Get remote template data. * * Retrieve the data of a single remote template from PowerPackElements.com servers. * * @since 1.14.5 * @access public * * @param array $args Custom template arguments. * @param string $context Optional. The context. Default is `display`. * * @return array|\WP_Error Remote Template data. */ public function get_data( array $args, $context = 'display' ) { $data = PP_Templates_Lib::get_template_content( $args['template_id'] ); if ( is_wp_error( $data ) ) { return $data; } $data = (array) $data; $data['content'] = $this->replace_elements_ids( $data['content'] ); $data['content'] = $this->process_export_import_content( $data['content'], 'on_import' ); $post_id = $args['editor_post_id']; $document = Plugin::$instance->documents->get( $post_id ); if ( $document ) { $data['content'] = $document->get_elements_raw_data( $data['content'], true ); } return $data; } /** * Prepare template. * * Prepare template data. * * @since 1.6.0 * @access private * * @param array $template_data Collection of template data. * @return array Collection of template data. */ private function prepare_template( array $template_data ) { $favorite_templates = $this->get_user_meta( 'favorites' ); return [ 'template_id' => $template_data['id'], 'source' => $this->get_id(), 'type' => $template_data['type'], 'subtype' => $template_data['subtype'], 'title' => $template_data['title'], 'thumbnail' => $template_data['thumbnail'], 'date' => $template_data['tmpl_created'], 'author' => $template_data['author'], 'tags' => json_decode( $template_data['tags'] ), 'isPro' => $template_data['is_pro'], 'url' => $template_data['url'], 'favorite' => ! empty( $favorite_templates[ $template_data['id'] ] ), ]; } }