locations-manager.php
246 lines
| 1 | <?php |
| 2 | namespace Auxin\Plugin\CoreElements\Elementor\Modules\ThemeBuilder\Classes; |
| 3 | |
| 4 | use Elementor\Plugin; |
| 5 | use Elementor\Controls_Manager; |
| 6 | use Elementor\Core\DocumentTypes\Post; |
| 7 | use Elementor\Modules\PageTemplates\Module as Single; |
| 8 | use Elementor\TemplateLibrary\Source_Local; |
| 9 | use Elementor\Modules\Library\Documents\Library_Document; |
| 10 | use Elementor\Core\Files\CSS\Post as Post_CSS; |
| 11 | use Auxin\Plugin\CoreElements\Elementor\Modules\ThemeBuilder\Module; |
| 12 | use Auxin\Plugin\CoreElements\Elementor\Modules\ThemeBuilder\Theme_Document; |
| 13 | |
| 14 | |
| 15 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | exit; // Exit if accessed directly. |
| 17 | } |
| 18 | |
| 19 | class Locations_Manager { |
| 20 | |
| 21 | protected $core_locations = []; |
| 22 | protected $locations = []; |
| 23 | protected $did_locations = []; |
| 24 | protected $current_location; |
| 25 | protected $locations_queue = []; |
| 26 | protected $locations_printed = []; |
| 27 | protected $locations_skipped = []; |
| 28 | |
| 29 | public function __construct() { |
| 30 | add_filter( 'the_content', [ $this, 'builder_wrapper' ], 9999999 ); // 9999999 = after preview->builder_wrapper |
| 31 | add_action( 'template_redirect', [ $this, 'register_locations' ] ); |
| 32 | add_filter( 'elementor/admin/create_new_post/meta', [ $this, 'filter_add_location_meta_on_create_new_post' ] ); |
| 33 | } |
| 34 | |
| 35 | public function register_locations() { |
| 36 | // Run Once. |
| 37 | if ( ! did_action( 'elementor/theme/register_locations' ) ) { |
| 38 | do_action( 'elementor/theme/register_locations', $this ); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | /** |
| 43 | * @param string $location |
| 44 | * @param integer $document_id |
| 45 | */ |
| 46 | public function add_doc_to_location( $location, $document_id ) { |
| 47 | if ( isset( $this->locations_skipped[ $location ][ $document_id ] ) ) { |
| 48 | // Don't re-add skipped documents. |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | if ( ! isset( $this->locations_queue[ $location ] ) ) { |
| 53 | $this->locations_queue[ $location ] = []; |
| 54 | } |
| 55 | |
| 56 | $this->locations_queue[ $location ][ $document_id ] = $document_id; |
| 57 | } |
| 58 | |
| 59 | public function remove_doc_from_location( $location, $document_id ) { |
| 60 | unset( $this->locations_queue[ $location ][ $document_id ] ); |
| 61 | } |
| 62 | |
| 63 | public function skip_doc_in_location( $location, $document_id ) { |
| 64 | $this->remove_doc_from_location( $location, $document_id ); |
| 65 | |
| 66 | if ( ! isset( $this->locations_skipped[ $location ] ) ) { |
| 67 | $this->locations_skipped[ $location ] = []; |
| 68 | } |
| 69 | |
| 70 | $this->locations_skipped[ $location ][ $document_id ] = $document_id; |
| 71 | } |
| 72 | |
| 73 | public function is_printed( $location, $document_id ) { |
| 74 | return isset( $this->locations_printed[ $location ][ $document_id ] ); |
| 75 | } |
| 76 | |
| 77 | public function set_is_printed( $location, $document_id ) { |
| 78 | if ( ! isset( $this->locations_printed[ $location ] ) ) { |
| 79 | $this->locations_printed[ $location ] = []; |
| 80 | } |
| 81 | |
| 82 | $this->locations_printed[ $location ][ $document_id ] = $document_id; |
| 83 | $this->remove_doc_from_location( $location, $document_id ); |
| 84 | } |
| 85 | |
| 86 | public function set_global_authordata() { |
| 87 | global $authordata; |
| 88 | if ( ! isset( $authordata->ID ) ) { |
| 89 | $post = get_post(); |
| 90 | $authordata = get_userdata( $post->post_author ); |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | public function get_documents_for_location( $location ){ |
| 95 | $locations = $this->get_locations(); |
| 96 | $documents = array(); |
| 97 | foreach ( $locations as $name => $args ) { |
| 98 | $template = get_page_by_path( auxin_get_option( 'site_' . $name . '_template', ' ' ), OBJECT, 'elementor_library' ); |
| 99 | if( isset( $template->ID ) && $template->ID !== ' ' && get_post_status( $template->ID ) ){ |
| 100 | $documents[ $template->ID ] = 'gu'; |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | public function do_location( $document_id, $location ) { |
| 106 | |
| 107 | $this->add_doc_to_location( $location, $document_id ); |
| 108 | |
| 109 | |
| 110 | // Locations Queue can contain documents that added manually. |
| 111 | if ( empty( $this->locations_queue[ $location ] ) ) { |
| 112 | return false; |
| 113 | } |
| 114 | |
| 115 | if ( is_singular() ) { |
| 116 | $this->set_global_authordata(); |
| 117 | } |
| 118 | |
| 119 | $document = Module::instance()->get_document( $document_id ); |
| 120 | |
| 121 | if ( ! $document || $this->is_printed( $location, $document_id ) ) { |
| 122 | $this->skip_doc_in_location( $location, $document_id ); |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | $this->current_location = $location; |
| 127 | $document->print_content(); |
| 128 | $this->did_locations[] = $this->current_location; |
| 129 | $this->current_location = null; |
| 130 | |
| 131 | $this->set_is_printed( $location, $document_id ); |
| 132 | |
| 133 | return true; |
| 134 | } |
| 135 | |
| 136 | public function did_location( $location ) { |
| 137 | return in_array( $location, $this->did_locations, true ); |
| 138 | } |
| 139 | |
| 140 | public function get_current_location() { |
| 141 | return $this->current_location; |
| 142 | } |
| 143 | |
| 144 | public function builder_wrapper( $content ) { |
| 145 | $post_id = get_the_ID(); |
| 146 | |
| 147 | if ( $post_id ) { |
| 148 | $document = Module::instance()->get_document( $post_id ); |
| 149 | if ( $document ) { |
| 150 | $document_location = $document->get_location(); |
| 151 | $location_settings = $this->get_location( $document_location ); |
| 152 | // If is a `content` document or the theme is not support the document location (header/footer and etc.). |
| 153 | if ( $location_settings && ! $location_settings['edit_in_content'] ) { |
| 154 | $content = '<div class="elementor-theme-builder-content-area">' . __( 'Content Area', 'auxin-elements' ) . '</div>'; |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | return $content; |
| 160 | } |
| 161 | |
| 162 | public function get_locations( $filter_args = [] ) { |
| 163 | $this->register_locations(); |
| 164 | return wp_list_filter( $this->locations, $filter_args ); |
| 165 | } |
| 166 | |
| 167 | public function get_location( $location ) { |
| 168 | $locations = $this->get_locations(); |
| 169 | |
| 170 | if ( isset( $locations[ $location ] ) ) { |
| 171 | $location_config = $locations[ $location ]; |
| 172 | } else { |
| 173 | $location_config = []; |
| 174 | } |
| 175 | |
| 176 | return $location_config; |
| 177 | } |
| 178 | |
| 179 | public function get_doc_location( $post_id ) { |
| 180 | $document = Plugin::instance()->documents->get( $post_id ); |
| 181 | return $document->get_location(); |
| 182 | } |
| 183 | |
| 184 | public function get_core_locations() { |
| 185 | return $this->core_locations; |
| 186 | } |
| 187 | |
| 188 | public function register_all_core_location() { |
| 189 | foreach ( $this->core_locations as $location => $settings ) { |
| 190 | $this->register_location( $location, $settings ); |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | public function register_location( $location, $args = [] ) { |
| 195 | $args = wp_parse_args( $args, [ |
| 196 | 'label' => $location, |
| 197 | 'multiple' => false, |
| 198 | 'public' => true, |
| 199 | 'edit_in_content' => true, |
| 200 | 'hook' => 'elementor/theme/' . $location, |
| 201 | ] ); |
| 202 | |
| 203 | $this->locations[ $location ] = $args; |
| 204 | |
| 205 | add_action( $args['hook'], function() use ( $location, $args ) { |
| 206 | $did_location = Module::instance()->get_locations_manager()->do_location( $location ); |
| 207 | |
| 208 | if ( $did_location && ! empty( $args['remove_hooks'] ) ) { |
| 209 | foreach ( $args['remove_hooks'] as $item ) { |
| 210 | remove_action( $args['hook'], $item ); |
| 211 | } |
| 212 | } |
| 213 | }, 5 ); |
| 214 | } |
| 215 | |
| 216 | public function register_core_location( $location, $args = [] ) { |
| 217 | if ( ! isset( $this->core_locations[ $location ] ) ) { |
| 218 | /* translators: %s: Location name. */ |
| 219 | wp_die( esc_html( sprintf( __( 'Location \'%s\' is not a core location.', 'auxin-elements' ), $location ) ) ); |
| 220 | } |
| 221 | |
| 222 | $args = array_replace_recursive( $this->core_locations[ $location ], $args ); |
| 223 | |
| 224 | $this->register_location( $location, $args ); |
| 225 | } |
| 226 | |
| 227 | public function location_exits( $location = '', $check_match = false ) { |
| 228 | $location_exits = ! ! $this->get_location( $location ); |
| 229 | |
| 230 | // if ( $location_exits && $check_match ) { |
| 231 | // $location_exits = ! ! Module::instance()->get_conditions_manager()->get_documents_for_location( $location ); |
| 232 | // } |
| 233 | |
| 234 | return $location_exits; |
| 235 | } |
| 236 | |
| 237 | public function filter_add_location_meta_on_create_new_post( $meta ) { |
| 238 | if ( ! empty( $_GET['meta_location'] ) ) { |
| 239 | $meta[ Theme_Document::LOCATION_META_KEY ] = auxin_sanitize_input( $_GET['meta_location'] ); |
| 240 | } |
| 241 | |
| 242 | return $meta; |
| 243 | } |
| 244 | |
| 245 | } |
| 246 |