PluginProbe
Scrollsequence – Cinematic Scroll Image Animation Plugin / 1.5.2
Scrollsequence – Cinematic Scroll Image Animation Plugin v1.5.2
1.4.3 1.4.4 1.4.5 1.4.6 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 trunk 0.9.92 0.9.93 0.9.94 0.9.96 1.0.072 1.0.073 All 61 releases
scrollsequence / admin / class-scrollsequence-admin.php

class-scrollsequence-admin.php in Scrollsequence – Cinematic Scroll Image Animation Plugin 1.5.2, at admin/class-scrollsequence-admin.php

1,019 lines 52.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Carbon_Fields\Container ;
4 use Carbon_Fields\Field ;
5 //use Carbon_Fields\Block; //not at the moment
6 /**
7 * The admin-specific functionality of the plugin.
8 *
9 * @link www.scrollsequence.com
10 * @since 0.7.0
11 *
12 * @package Scrollsequence
13 * @subpackage Scrollsequence/admin
14 */
15 /**
16 * The admin-specific functionality of the plugin.
17 *
18 * Defines the plugin name, version, and two examples hooks for how to
19 * enqueue the admin-specific stylesheet and JavaScript.
20 *
21 * @package Scrollsequence
22 * @subpackage Scrollsequence/admin
23 * @author Scrollsequence <info@scrollsequence.com>
24 */
25 class Scrollsequence_Admin
26 {
27 /**
28 * The ID of this plugin.
29 *
30 * @since 0.7.0
31 * @access private
32 * @var string $plugin_name The ID of this plugin.
33 */
34 private $plugin_name ;
35 /**
36 * The version of this plugin.
37 *
38 * @since 0.7.0
39 * @access private
40 * @var string $version The current version of this plugin.
41 */
42 private $version ;
43 /**
44 * Initialize the class and set its properties.
45 *
46 * @since 0.7.0
47 * @param string $plugin_name The name of this plugin.
48 * @param string $version The version of this plugin.
49 */
50 public function __construct( $plugin_name, $version )
51 {
52 $this->plugin_name = $plugin_name;
53 $this->version = $version;
54 add_shortcode( 'scrollsequence', array( $this, 'scrollsequence_shortcode' ) );
55 }
56
57 /**
58 * Register the stylesheets for the admin area.
59 *
60 * @since 0.7.0
61 */
62 public function enqueue_styles()
63 {
64 /**
65 * This function is provided for demonstration purposes only.
66 *
67 * An instance of this class should be passed to the run() function
68 * defined in Scrollsequence_Loader as all of the hooks are defined
69 * in that particular class.
70 *
71 * The Scrollsequence_Loader will then create the relationship
72 * between the defined hooks and the functions defined in this
73 * class.
74 */
75 // Ak: I want to add an IF statement to enqueue scripts only to my CPT
76 global $post_type ;
77 if ( 'scrollsequence' == $post_type ) {
78 wp_enqueue_style(
79 $this->plugin_name,
80 plugin_dir_url( __FILE__ ) . 'css/scrollsequence-admin.css',
81 array(),
82 $this->version,
83 'all'
84 );
85 }
86 // Ak: end
87 }
88
89 /**
90 * Register the JavaScript for the admin area.
91 *
92 * @since 0.7.0
93 */
94 public function enqueue_scripts()
95 {
96 /**
97 * This function is provided for demonstration purposes only.
98 *
99 * An instance of this class should be passed to the run() function
100 * defined in Scrollsequence_Loader as all of the hooks are defined
101 * in that particular class.
102 *
103 * The Scrollsequence_Loader will then create the relationship
104 * between the defined hooks and the functions defined in this
105 * class.
106 */
107 // Ak: I want to add an IF statement to enqueue scripts only to my CPT
108 global $post_type ;
109 global $pagenow ;
110 if ( 'scrollsequence' == $post_type && ('post-new.php' === $pagenow || 'post.php' === $pagenow) ) {
111 // Free
112 wp_enqueue_script(
113 $this->plugin_name,
114 plugin_dir_url( __FILE__ ) . 'js/scrollsequence-admin.js',
115 array( 'jquery' ),
116 $this->version,
117 true
118 );
119 }
120 // Ak: end
121 }
122
123 /**
124 * Register Scrollsequence CPT .
125 *
126 * @since 0.7.0
127 */
128 public function scrollsequence_cpt()
129 {
130 require_once "create-cpt.php";
131 }
132
133 /**
134 * Register Scrollsequence CPT .
135 *
136 * @since 0.7.3
137 */
138 public function scrollsequence_cpt_submenu()
139 {
140 add_submenu_page(
141 'edit.php?post_type=scrollsequence',
142 /*parent_slug*/
143 'Dashboard Scrollsequence',
144 /*page title*/
145 'Dashboard',
146 /*menu title*/
147 'edit_posts',
148 /*roles and capability needed*/
149 // Update 0.9.93
150 'scrollsequence-dashboard',
151 /*menu slug*/
152 'scrollsequence_cpt_dashboard_callback'
153 );
154 function scrollsequence_cpt_dashboard_callback()
155 {
156 require_once "partials/scrollsequence-admin-display.php";
157 }
158
159 }
160
161 public function scrollsequence_preview_media()
162 {
163 add_submenu_page(
164 'edit.php?post_type=scrollsequence',
165 'Preview Scrollsequence',
166 /*page title*/
167 'Preview ',
168 /*menu title*/
169 'edit_posts',
170 /*roles and capability needed*/
171 // Update 0.9.93
172 'scrollsequence-preview',
173 /*menu slug*/
174 'scrollsequence_preview_callback'
175 );
176 function scrollsequence_preview_callback()
177 {
178 require_once "partials/scrollsequence-admin-display-media-tools-preview.php";
179 }
180
181 // Enqueue script on this specific submenu page
182 add_action( 'admin_enqueue_scripts', array( $this, 'scrollsequence_preview_enqueue_scripts' ) );
183 }
184
185 function scrollsequence_preview_media_hide_submenu_page()
186 {
187 echo '<style>
188 #adminmenumain a[href="admin.php?page=scrollsequence-preview"] {
189 display: none;
190 }
191 </style>' ;
192 }
193
194 public function scrollsequence_preview_enqueue_scripts( $hook )
195 {
196 // Check if we're on the 'scrollsequence-preview' page
197 if ( 'admin_page_scrollsequence-preview' !== $hook ) {
198 return;
199 }
200 }
201
202 /**
203 * Single file custom template for scrollsequence. I am following this:
204 * https://code.tutsplus.com/tutorials/a-guide-to-wordpress-custom-post-types-creation-display-and-meta-boxes--wp-27645
205 * ref "tutsplus" in class-scrollsequence add action thing
206 * @since 0.7.0
207 * @uses i dont know
208 * Step 1 https://blog.wplauncher.com/add-meta-box-wordpress-custom-post-type/
209 */
210 public function scrollsequence_template( $template_path )
211 {
212 if ( get_post_type() == 'scrollsequence' ) {
213 if ( is_single() ) {
214 // checks if the file exists in the theme first,
215 // otherwise serve the file from the plugin
216
217 if ( $theme_file = locate_template( array( 'single-scrollsequence.php' ) ) ) {
218 $template_path = $theme_file;
219 } else {
220 $template_path = plugin_dir_path( __DIR__ ) . 'public/partials/single-scrollsequence.php';
221 }
222
223 }
224 }
225 return $template_path;
226 }
227
228 /**
229 * Carbon Fields Boot function. This function boots up carbon fields.
230 *
231 * @since 0.9.8
232 */
233 public function scrollsequence_carbon_fields_load()
234 {
235 require_once __DIR__ . '/../includes/carbonfields/autoload.php';
236 \Carbon_Fields\Carbon_Fields::boot();
237 }
238
239 /**
240 * Carbon Fields Main Function (Scrollsequence CPT)
241 *
242 * @since 0.9.8
243 */
244 public function scrollsequence_carbon_fields_cpt()
245 {
246 /* TRANSLATION IS MISSING FOR STRINGS BELOW */
247 $scrollsequence_advert_html = '<h4>Full animation settings are available in <a href=' . admin_url( "admin.php?page=scrollsequence-pricing" ) . '>Scrollsequence PRO</a>.</h4><strong>NEW: </strong>We offer <a href=' . admin_url( "admin.php?page=scrollsequence-pricing&trial=true" ) . '>14 days FREE trial</a> - no card required, no risk. ';
248 $scrollsequence_left_center_right = '
249 <div style="float: left">' . __( 'Left', 'scrollsequence' ) . '</div>
250 <div style="float: right">' . __( 'Right', 'scrollsequence' ) . '</div>
251 <div style="margin: 0 auto; width: 100px;"></div>
252 ';
253 $scrollsequence_bottom_center_top = '
254 <div style="float: left">' . __( 'Top', 'scrollsequence' ) . '</div>
255 <div style="float: right">' . __( 'Bottom', 'scrollsequence' ) . '</div>
256 <div style="margin: 0 auto; width: 100px;"></div>
257 ';
258 $scrollsequence_trigger_start = '
259 <div style="float: left">' . __( 'Start Sooner', 'scrollsequence' ) . '</div>
260 <div style="float: right">' . __( 'Default', 'scrollsequence' ) . '</div>
261 <div style="margin: 0 auto; width: 100px;"></div>
262 ';
263 $scrollsequence_trigger_end = '
264 <div style="float: left">' . __( 'Default', 'scrollsequence' ) . '</div>
265 <div style="float: right">' . __( 'End Later', 'scrollsequence' ) . '</div>
266 <div style="margin: 0 auto; width: 100px;"></div>
267 ';
268 /* TRANSLATION IS MISSING FOR STRINGS BELOW */
269 $scrollsequence_aglignmentadv = '<p>More Scale and Alignment settings are available in <a href=' . admin_url( "admin.php?page=scrollsequence-pricing" ) . '>Scrollsequence PRO</a>. </p><p><strong>NEW: </strong>We offer <a href=' . admin_url( "admin.php?page=scrollsequence-pricing&trial=true" ) . '>14 days FREE trial</a> - no card required, no risk.</p>';
270 $scrollsequence_condition_need_images = array(
271 'relation' => 'AND',
272 array(
273 'field' => 'scrollsequence_p_images',
274 'value' => '',
275 'compare' => '!=',
276 ),
277 );
278 // FREE VERSION
279 Container::make( 'post_meta', 'Scrollsequence' )->where( 'post_type', '=', 'scrollsequence' )->set_context( 'carbon_fields_after_title' )->add_fields( array( Field::make( 'complex', 'scrollsequence_page', __( 'Scene', 'scrollsequence' ) )->setup_labels( array(
280 'plural_name' => __( 'Scenes', 'scrollsequence' ),
281 'singular_name' => __( 'Scene', 'scrollsequence' ),
282 ) )->set_layout( 'tabbed-horizontal' )->set_required( true )->set_max( 3 )->add_fields( array(
283 Field::make( 'rich_text', 'scrollsequence_p_wysiwyg', __( 'Fixed Content', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_default_value( '<div class="ssq-center-center"><h1 id="on-earth">' . __( 'Another day on Earth', 'scrollsequence' ) . '</h1></div>' ),
284 Field::make( 'media_gallery', 'scrollsequence_p_images', __( 'Image Sequence', 'scrollsequence' ) )->set_type( array( 'image' ) )->set_required( true )->set_duplicates_allowed( true )->set_classes( 'scrollsequence-custom-class' ),
285 Field::make( 'complex', 'ssqnce_anim', __( 'Fixed Content Animation', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_layout( 'tabbed-vertical' )->setup_labels( array(
286 'plural_name' => __( 'Animations', 'scrollsequence' ),
287 'singular_name' => __( 'Animation', 'scrollsequence' ),
288 ) )->add_fields( 'ssqnce_anim_io', 'Animate From/To', array(
289 Field::make( 'text', 'ssqnce_anim_io_id', __( 'Selector', 'scrollsequence' ) )->set_width( 20 )->set_required( true )->set_help_text( __( 'Enter #id or .class selector', 'scrollsequence' ) ),
290 Field::make( 'text', 'ssqnce_anim_io_start', __( 'Start', 'scrollsequence' ) )->set_width( 20 )->set_required( true )->set_help_text( __( 'Enter image number where element becomes visible', 'scrollsequence' ) )->set_attribute( 'type', 'number' )->set_attribute( 'min', '0' )->set_attribute( 'step', '1' ),
291 Field::make( 'text', 'ssqnce_anim_io_end', __( 'End', 'scrollsequence' ) )->set_width( 20 )->set_required( true )->set_help_text( __( 'Enter image number where element is hidden', 'scrollsequence' ) )->set_attribute( 'type', 'number' )->set_attribute( 'min', '0' )->set_attribute( 'step', '1' ),
292 // Free advert
293 Field::make( 'separator', 'scrollsequence_advert', __( 'Animation Settings Not Available in Free Version', 'scrollsequence' ) )->set_help_text( $scrollsequence_advert_html ),
294 ) )->set_header_template( __( 'Animation', 'scrollsequence' ) . '
295 <% if (ssqnce_anim_io_id) { %>
296 - <%- ssqnce_anim_io_id %>
297 <% } %>
298 ' ),
299 // PRO ONLY END1
300 // Field::make( 'text', 'scrollsequence_p_duration', __( 'Page Height (vh)' ) )
301 // ->set_conditional_logic($scrollsequence_condition_need_images)
302 // ->set_attribute( 'type', 'number' )
303 // ->set_required( true )
304 // ->set_default_value('200')
305 // ->set_attribute( 'min', '20' )
306 // ->set_attribute( 'max', '2000' )
307 // ->set_attribute( 'step', '1' )
308 // ->help_text('This sets the amount of scroll needed to get past this page.'),
309 Field::make( 'text', 'scrollsequence_p_imgdur', __( 'Image Duration (px)', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_attribute( 'type', 'number' )->set_required( true )->set_default_value( '25' )->set_attribute( 'min', '5' )->set_attribute( 'max', '500' )->set_attribute( 'step', '1' )->help_text( __( 'This sets how far the images are apart.', 'scrollsequence' ) ),
310 // PANORAMA (MOBILE)
311 Field::make( 'html', 'scrollsequence_info_html_panorama' )->set_conditional_logic( $scrollsequence_condition_need_images )->set_html( '<h3>' . __( 'Image Scale and Alignment', 'scrollsequence' ) . '</h3>' ),
312 Field::make( 'select', 'scrollsequence_p_scaleto_mobile', __( 'Portrait (Mobile)', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_width( 30 )->set_default_value( 'fill' )->set_options( array(
313 'fill' => __( 'Scale to fill', 'scrollsequence' ),
314 'fit' => __( 'Scale to fit', 'scrollsequence' ) . ' 100%',
315 '0.5' => __( 'Scale to fit', 'scrollsequence' ) . ' 50%',
316 ) ),
317 Field::make( 'text', 'scrollsequence_p_alignx_mobile', __( 'Horizontal Align', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_help_text( $scrollsequence_left_center_right )->set_width( 35 )->set_attribute( 'type', 'range' )->set_classes( 'ssq-range-slider' )->set_default_value( '0.5' )->set_attribute( 'min', '0' )->set_attribute( 'max', '1' )->set_attribute( 'step', '0.5' ),
318 // ROADM
319 Field::make( 'text', 'scrollsequence_p_aligny_mobile', __( 'Vertical Align', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_help_text( $scrollsequence_bottom_center_top )->set_width( 35 )->set_attribute( 'type', 'range' )->set_classes( 'ssq-range-slider' )->set_default_value( '0.5' )->set_attribute( 'min', '0' )->set_attribute( 'max', '1' )->set_attribute( 'step', '0.5' ),
320 // ROADM
321 // LANDSCAPE (DESKTOP)
322 Field::make( 'select', 'scrollsequence_p_scaleto_desktop', __( 'Landscape (Desktop)', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_width( 30 )->set_default_value( 'fill' )->set_options( array(
323 'fill' => __( 'Scale to fill', 'scrollsequence' ),
324 'fit' => __( 'Scale to fit', 'scrollsequence' ) . ' 100%',
325 '0.5' => __( 'Scale to fit', 'scrollsequence' ) . ' 50%',
326 ) ),
327 Field::make( 'text', 'scrollsequence_p_alignx_desktop', __( 'Horizontal Align', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_help_text( $scrollsequence_left_center_right )->set_width( 35 )->set_attribute( 'type', 'range' )->set_classes( 'ssq-range-slider' )->set_default_value( '0.5' )->set_attribute( 'min', '0' )->set_attribute( 'max', '1' )->set_attribute( 'step', '0.5' ),
328 // ROADM
329 Field::make( 'text', 'scrollsequence_p_aligny_desktop', __( 'Vertical Align', 'scrollsequence' ) )->set_conditional_logic( $scrollsequence_condition_need_images )->set_help_text( $scrollsequence_bottom_center_top )->set_width( 35 )->set_attribute( 'type', 'range' )->set_classes( 'ssq-range-slider' )->set_default_value( '0.5' )->set_attribute( 'min', '0' )->set_attribute( 'max', '1' )->set_attribute( 'step', '0.5' ),
330 // ROADM
331 Field::make( 'html', 'scrollsequence_info_html_freealignadv' )->set_conditional_logic( $scrollsequence_condition_need_images )->set_html( $scrollsequence_aglignmentadv ),
332 ) )->set_header_template( __( 'Scene', 'scrollsequence' ) . ' <%- $_index %>' ) ) );
333 // FREE
334 $scrub_field = Field::make( 'html', 'scrollsequence_hidden', '' )->set_html( '
335 <style>
336 .nevim{
337 line-height: 1.4;
338 font-size: 13px;
339 cursor: pointer;
340 vertical-align: middle;
341 display: block;
342 padding-bottom: 5px;
343 font-weight: 600;
344 color: #23282d;
345 }
346
347
348 </style>
349 <div class="nevim">' . __( 'Scroll Delay', 'scrollsequence' ) . '</div>
350 <select disabled>
351 <option value="0">0s (instant)</option>
352 </select>
353 <p>' . __( 'Scroll Delay Settings available only in', 'scrollsequence' ) . ' <a href=' . admin_url( "admin.php?page=scrollsequence-pricing" ) . '>Scrollsequence PRO</a>.</p>' );
354 $debug_multi_options_array = array(
355 'debug' => __( 'General Debug', 'scrollsequence' ),
356 'preloaddebug' => __( 'Image Preload Debug', 'scrollsequence' ),
357 'detectdebug' => __( 'Device Detect Debug', 'scrollsequence' ),
358 );
359 $scrollsequence_trigger_start_field = Field::make( 'hidden', 'scrollsequence_trigger_start_hidden', '' )->set_classes( 'schovej-to-policko' );
360 $scrollsequence_trigger_end_field = Field::make( 'hidden', 'scrollsequence_trigger_end_hidden', '' )->set_classes( 'schovej-to-policko' );
361 // END OF FREE __(,'scrollsequence')
362 Container::make( 'post_meta', 'Scrollsequence Settings' )->where( 'post_type', '=', 'scrollsequence' )->set_context( 'side' )->set_priority( 'low' )->add_fields( array(
363 $scrollsequence_trigger_start_field,
364 $scrollsequence_trigger_end_field,
365 Field::make( 'select', 'scrollsequence_position', __( 'Position', 'scrollsequence' ) )->help_text( __( 'Sticky position fixes animation to the viewport. Static makes it flow with the rest of the page. Sticky behavior can be controlled via options. See more in documentation. ', 'scrollsequence' ) )->add_options( array(
366 'sticky' => __( 'Sticky (default)', 'scrollsequence' ),
367 'absolute' => __( 'Absolute', 'scrollsequence' ),
368 'static' => __( 'Static', 'scrollsequence' ),
369 ) ),
370 $scrub_field,
371 Field::make( 'select', 'scrollsequence_image_full_width', __( 'Image Width', 'scrollsequence' ) )->add_options( array(
372 false => __( 'Content Width (default)', 'scrollsequence' ),
373 true => __( 'Force Full Width', 'scrollsequence' ),
374 ) )->help_text( __( 'Select "Force Full Width" to overrride your templates default width. If the setting does not work, use full width template included in your Theme.', 'scrollsequence' ) ),
375 Field::make( 'text', 'scrollsequence_image_opacity', __( 'Image Opacity', 'scrollsequence' ) )->set_attribute( 'type', 'number' )->set_required( true )->set_default_value( '1' )->set_attribute( 'min', '0' )->set_attribute( 'max', '1' )->set_attribute( 'step', '0.01' ),
376 // THIS IS QUITE COMPLEX - ACTIVATE LATER ???
377 // Field::make( 'text', 'scrollsequence_image_zindex', __( 'Image z-index (optional)' ) )
378 // //->set_help_text( '' )
379 // ->set_attribute( 'type', 'number' )
380 // ->set_attribute( 'min', '-9999' )
381 // ->set_attribute( 'max', '9999' )
382 // ->set_attribute( 'step', '1' ),
383 // Field::make( 'select', 'scrollsequence_content_spacer', 'Classic Content Position' ) // LEGACY
384 // ->add_options( array( // LEGACY
385 // 'after100' => 'End of Document (default)', // LEGACY
386 // 'after' => 'End of Document (with overlap) ', // LEGACY
387 // 'during' => 'Start of Document',
388 // ) ),
389 Field::make( 'textarea', 'scrollsequence_custom_css', __( 'Custom CSS', 'scrollsequence' ) )->set_default_value( '.ssq-center-center{
390 position: absolute;
391 left: 50%;
392 top: 50%;
393 transform: translate(-50%, -50%);
394 text-shadow: 0 0 8px white;
395 text-align: center;
396 }
397 ' )->help_text( __( 'Enter custom CSS here.', 'scrollsequence' ) ),
398 Field::make( "multiselect", "scrollsequence_debug_multi", __( "Show Development Information", 'scrollsequence' ) )->add_options( $debug_multi_options_array ),
399 ) );
400 /*
401 * SIDE CONTEXT - ADVANCED SETTINGS
402 */
403 Container::make( 'post_meta', 'Custom Post Settings' )->where( 'post_type', '=', 'scrollsequence' )->set_context( 'side' )->set_priority( 'low' )->add_fields( array(
404 Field::make( 'color', 'scrollsequence_bodybgcolor', __( 'Body Background Color', 'scrollsequence' ) )->help_text( __( 'Set CSS attribute <i><strong>background-color</strong></i> of <i><strong>body.single-scrollsequence</strong></i> class.', 'scrollsequence' ) ),
405 // Field::make( 'color', 'scrollsequence_classic_content_after_bgcolor', __( 'Background Color - After Scrollsequence' ) )
406 // ->help_text('Use in case you want to have different background color after the scrollsequence is finished. Only active when there is content after the image sequence. ')
407 // ,
408 Field::make( 'checkbox', 'scrollsequence_show_sidebar', __( 'Show Sidebar', 'scrollsequence' ) )->set_option_value( 'yes' )->help_text( __( 'Experimental, take care', 'scrollsequence' ) ),
409 Field::make( 'checkbox', 'scrollsequence_show_footer', __( 'Show Footer', 'scrollsequence' ) )->set_option_value( 'yes' )->help_text( __( 'Experimental, take care. <br>(This setting displays footer element and changes z-index to 9999)', 'scrollsequence' ) ),
410 ) );
411 }
412
413 // END OF CARBON FIELD MAIN FUNCTION (CPT)
414 /**
415 * ROADM Alert Too Many Pages and Images
416 *
417 * @since 0.7.4
418 */
419 public function scrollsequence_admin_notice()
420 {
421 // Ak: I want to add an IF statement to add admin notice only to scrollsequence post php
422 global $post_type ;
423 global $pagenow ;
424
425 if ( $pagenow == 'post.php' && 'scrollsequence' == $post_type || $pagenow == 'post-new.php' && 'scrollsequence' == $post_type ) {
426 echo '<div class="notice notice-warning" id="scrollsequence_notice_toomanyimg" style="display:none" ><p>' . __( 'Warning: Image limit reached. For performance reasons, free version allows maximum of 100 images on a single page. Images marked with "X" will not be displayed.', 'scrollsequence' ) . ' <a href="' . admin_url( 'admin.php?page=scrollsequence-pricing' ) . '">' . __( 'Upgrade to display unlimited images in your Scrollsequence', 'scrollsequence' ) . '</a>.</p></div>' ;
427 echo '<div class="notice notice-warning" id="scrollsequence_notice_toomanypages" style="display:none" ><p>' . __( 'Warning: Scene limit reached. For performance reasons, free version allows maximum of 3 scenes.', 'scrollsequence' ) . ' <a href="' . admin_url( 'admin.php?page=scrollsequence-pricing' ) . '">' . __( 'Upgrade to display unlimited scenes in your Scrollsequence', 'scrollsequence' ) . ' </a>.</p></div>' ;
428 }
429
430 // Ak: end
431 }
432
433 /**
434 * Classic Content Editor Heading
435 *
436 * @since 0.9.94
437 */
438 /* OBSOLETE
439 <h2><strong> Shortcode options:</strong> </h2>
440 <p><i>[scrollsequence margintop="-200px"]</i> Animation will have a 200px overlap. Useful when you have a gap at the top where animation starts.</p>
441 <p><i>[scrollsequence marginbottom="-600px"]</i> Animation will have a 600px overlap. Useful when you want to seamlessly join content after the animation ends.</p>
442 */
443 public function scrollsequence_classic_content_html()
444 {
445 // Ak: I want to add an IF statement to add admin notice only to scrollsequence post php
446 global $post_type ;
447 global $pagenow ;
448 if ( $pagenow == 'post.php' && 'scrollsequence' == $post_type || $pagenow == 'post-new.php' && 'scrollsequence' == $post_type ) {
449 // IF Condition Changed 1.0.076
450 echo __( '<h1>Content Editor </h1>
451 <p><strong>Place shortcode <i>[scrollsequence]</i> anywhere in the classic content to control image sequence position.<br> If not specified <i>[scrollsequence]</i> shortcode will be placed at the start of content automatically, rendering the image sequence at the begining of the page. </strong></p>', 'scrollsequence' ) . '
452
453 ' ;
454 }
455 // Ak: end
456 }
457
458 /**
459 * Function that makes the scrollsequence shortcode happen..
460 *
461 * Shortcode: [scrollsequence id="###"]
462 *
463 *
464 * @since 0.9.95
465 */
466 public function scrollsequence_shortcode( $atts )
467 {
468 // Extract atts
469 extract( shortcode_atts( array(
470 'id' => get_the_id(),
471 'margintop' => 0,
472 'marginbottom' => 0,
473 'hide' => false,
474 ), $atts ) );
475 // Get info from database
476 $ssqInputZeroObject = array(
477 'debug' => carbon_get_post_meta( $id, 'scrollsequence_debug_multi' ),
478 'show_footer' => carbon_get_post_meta( $id, 'scrollsequence_show_footer' ),
479 'show_sidebar' => carbon_get_post_meta( $id, 'scrollsequence_show_sidebar' ),
480 'preloadPercentage' => esc_attr( get_option( 'ssq_option_preload_percentage', 0.12 ) ),
481 'ssqFyiId' => $id,
482 'siteUrl' => get_option( 'siteurl' ),
483 );
484 $ssqInputObject = array(
485 'ssqId' => $id,
486 'bodyBgColor' => carbon_get_post_meta( $id, 'scrollsequence_bodybgcolor' ),
487 'imageOpacity' => carbon_get_post_meta( $id, 'scrollsequence_image_opacity' ),
488 'scrub' => (double) carbon_get_post_meta( $id, 'scrollsequence_scrub' ),
489 'forceFullWidth' => carbon_get_post_meta( $id, 'scrollsequence_image_full_width' ),
490 'zIndex' => carbon_get_post_meta( $id, 'scrollsequence_image_zindex' ),
491 'triggerStart' => carbon_get_post_meta( $id, 'scrollsequence_trigger_start' ),
492 'triggerEnd' => carbon_get_post_meta( $id, 'scrollsequence_trigger_end' ),
493 'canvasDPR' => esc_attr( get_option( 'ssq_option_canvas_dpr', 'quality' ) ),
494 );
495 // Rename info from database in JS format
496 $ssqInputObject['page'] = array();
497 $ssqPageFromUI = carbon_get_post_meta( $id, 'scrollsequence_page' );
498 foreach ( $ssqPageFromUI as $x => $val ) {
499 $ssqInputObject['page'][$x]['alignX']['desktop'] = $ssqPageFromUI[$x]['scrollsequence_p_alignx_desktop'];
500 $ssqInputObject['page'][$x]['alignX']['mobile'] = $ssqPageFromUI[$x]['scrollsequence_p_alignx_mobile'];
501 $ssqInputObject['page'][$x]['alignY']['desktop'] = $ssqPageFromUI[$x]['scrollsequence_p_aligny_desktop'];
502 $ssqInputObject['page'][$x]['alignY']['mobile'] = $ssqPageFromUI[$x]['scrollsequence_p_aligny_mobile'];
503 // $ssqInputObject['page'][$x]['pageDuration']= (float)$ssqPageFromUI[$x]['scrollsequence_p_duration'];
504 $ssqInputObject['page'][$x]['imgDur'] = (double) $ssqPageFromUI[$x]['scrollsequence_p_imgdur'];
505 $ssqInputObject['page'][$x]['scaleTo']['desktop'] = $ssqPageFromUI[$x]['scrollsequence_p_scaleto_desktop'];
506 $ssqInputObject['page'][$x]['scaleTo']['mobile'] = $ssqPageFromUI[$x]['scrollsequence_p_scaleto_mobile'];
507 // Loop Through Anim
508 $ssqInputObject['page'][$x]['animEl'] = array();
509 // in case of empty
510 foreach ( $ssqPageFromUI[$x]['ssqnce_anim'] as $z => $animvar ) {
511 $ssqInputObject['page'][$x]['animEl'][$z] = $ssqPageFromUI[$x]['ssqnce_anim'][$z];
512 }
513 }
514 // If there is "hide" parameter -> enqueue mobile detect script and act based on parameter values.
515
516 if ( $hide ) {
517 $showDetectNotice = in_array( "detectdebug", carbon_get_post_meta( $id, 'scrollsequence_debug_multi' ) );
518 //echo '<!--Scrollsequence - Hide Parameter Exists: -->';
519 require_once 'mobile_detect/mobile_detect.php';
520 $detect = new Mobile_Detect();
521 // var_dump($detect);
522 // Any mobile device (phones or tablets).
523 if ( $detect->isMobile() && str_contains( strtolower( $hide ), 'ismobile' ) ) {
524 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isMobile </div>';
525 }
526 if ( !$detect->isMobile() && str_contains( strtolower( $hide ), 'isnotmobile' ) ) {
527 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isNotMobile </div>';
528 }
529 // Any tablet device.
530 if ( $detect->isTablet() && str_contains( strtolower( $hide ), 'istablet' ) ) {
531 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isTablet </div>';
532 }
533 if ( !$detect->isTablet() && str_contains( strtolower( $hide ), 'isnottablet' ) ) {
534 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isNotTablet </div>';
535 }
536 // Exclude tablets.
537 if ( $detect->isMobile() && !$detect->isTablet() && str_contains( strtolower( $hide ), 'isphone' ) ) {
538 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isPhone </div>';
539 }
540 if ( !($detect->isMobile() && !$detect->isTablet()) && str_contains( strtolower( $hide ), 'isnotphone' ) ) {
541 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isNotPhone </div>';
542 }
543 // Check for a specific platform with the help of the magic methods:
544 if ( $detect->isiOS() && str_contains( strtolower( $hide ), 'isios' ) ) {
545 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isiOs </div>';
546 }
547 if ( !$detect->isiOS() && str_contains( strtolower( $hide ), 'isnotios' ) ) {
548 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isNotiOs </div>';
549 }
550 if ( $detect->isAndroidOS() && str_contains( strtolower( $hide ), 'isandroidos' ) ) {
551 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isAndroidOs </div>';
552 }
553 if ( !$detect->isAndroidOS() && str_contains( strtolower( $hide ), 'isnotandroidos' ) ) {
554 return '<div class="scrollsequence-mobile-detect-message" ' . (( $showDetectNotice ? '' : 'style="display:none' )) . '"> Scrollsequence Debug - MobileDetect: Hide because device isNotAndroidOs </div>';
555 }
556 }
557
558 // FREE
559 foreach ( $ssqPageFromUI as $x => $val ) {
560 // Loop Through IMAGES
561 $ssqInputObject['page'][$x]['imagesFull'] = array( plugin_dir_url( __DIR__ ) . 'public/img/noimg.jpg' );
562 //if empty
563
564 if ( function_exists( 'get_rocket_cdn_url' ) ) {
565 foreach ( $ssqPageFromUI[$x]['scrollsequence_p_images'] as $y => $imgvar ) {
566 $ssqInputObject['page'][$x]['imagesFull'][$y] = get_rocket_cdn_url( wp_get_attachment_image_src( $ssqPageFromUI[$x]['scrollsequence_p_images'][$y], 'full' )[0] );
567 }
568 } else {
569 foreach ( $ssqPageFromUI[$x]['scrollsequence_p_images'] as $y => $imgvar ) {
570 $ssqInputObject['page'][$x]['imagesFull'][$y] = wp_get_attachment_image_src( $ssqPageFromUI[$x]['scrollsequence_p_images'][$y], 'full' )[0];
571 }
572 }
573
574 $ssqInputObject['page'][$x]['imagesFull'] = array_splice( $ssqInputObject['page'][$x]['imagesFull'], 0, 100 );
575 }
576 // Calculate lengths, spacers and absSpacers (SC is calculated in JS)
577 $ssqInputObject['pageLength'] = count( $ssqInputObject['page'] );
578 $ssqInputObject['scSpacer'] = 0;
579 $pageAbsSpacerTotal = 0;
580 foreach ( $ssqPageFromUI as $x => $val ) {
581 $ssqInputObject['page'][$x]['imagesLength'] = count( $ssqInputObject['page'][$x]['imagesFull'] );
582 $ssqInputObject['page'][$x]['animElLength'] = count( $ssqInputObject['page'][$x]['animEl'] );
583 $ssqInputObject['page'][$x]['pageSpacer'] = $ssqInputObject['page'][$x]['imagesLength'] * $ssqInputObject['page'][$x]['imgDur'];
584 $ssqInputObject['scSpacer'] = $ssqInputObject['scSpacer'] + $ssqInputObject['page'][$x]['pageSpacer'];
585 $ssqInputObject['page'][$x]['pageAbsBegin'] = $pageAbsSpacerTotal;
586 $pageAbsSpacerTotal = $pageAbsSpacerTotal + $ssqInputObject['page'][$x]['pageSpacer'];
587 $ssqInputObject['page'][$x]['pageAbsEnd'] = $pageAbsSpacerTotal;
588 }
589 // Sticky JS/CSS or Static - Deal with all here early on. - Since 1.3.0
590 $stickyOptionFromSettings = get_option( 'ssq_option_position_sticky', 'sticky-js' );
591 // second argument must be the same as default value, it needs to be here to cover if null
592
593 if ( carbon_get_post_meta( $id, 'scrollsequence_position' ) == 'sticky' && $stickyOptionFromSettings == 'sticky-js' ) {
594 // sticky js
595 $ssqInputObject['position'] = 'sticky-js';
596 $stickyStyle = 'position:relative;box-sizing: border-box;';
597 $ssqDomSpacer = $ssqInputObject['scSpacer'];
598 $ssqWrapStylePosition = '';
599 $absoluteScrollsequenceStyle = '';
600 } else {
601
602 if ( carbon_get_post_meta( $id, 'scrollsequence_position' ) == 'sticky' && $stickyOptionFromSettings == 'sticky-css' ) {
603 // sticky css
604 $ssqInputObject['position'] = 'sticky-css';
605 $stickyStyle = 'position: -webkit-sticky;position:sticky;top:0;box-sizing: border-box;';
606 $ssqDomSpacer = $ssqInputObject['scSpacer'];
607 $ssqWrapStylePosition = '';
608 $absoluteScrollsequenceStyle = '';
609 } else {
610
611 if ( carbon_get_post_meta( $id, 'scrollsequence_position' ) == 'absolute' && $stickyOptionFromSettings == 'sticky-js' ) {
612 // sticky js
613 $ssqInputObject['position'] = 'sticky-js';
614 $stickyStyle = 'position:relative;box-sizing: border-box;';
615 $ssqDomSpacer = $ssqInputObject['scSpacer'];
616 $ssqWrapStylePosition = 'position:absolute;';
617 $absoluteScrollsequenceStyle = 'style="display:block;position:relative;"';
618 } else {
619
620 if ( carbon_get_post_meta( $id, 'scrollsequence_position' ) == 'absolute' && $stickyOptionFromSettings == 'sticky-css' ) {
621 // sticky css
622 $ssqInputObject['position'] = 'sticky-css';
623 $stickyStyle = 'position: -webkit-sticky;position:sticky;top:0;box-sizing: border-box;';
624 $ssqDomSpacer = $ssqInputObject['scSpacer'];
625 $ssqWrapStylePosition = 'position:absolute;';
626 $absoluteScrollsequenceStyle = 'style="display:block;position:relative;"';
627 } else {
628 // static
629 //$ssqInputObject['carbongetpostmetascrollsequenceposition'] = carbon_get_post_meta( $id, 'scrollsequence_position');
630 //$ssqInputObject['get_optionssqoptionpositionsticky'] =$stickyOptionFromSettings;
631 $ssqInputObject['position'] = 'static';
632 $stickyStyle = 'position:relative;box-sizing: border-box; ';
633 $ssqDomSpacer = 0;
634 $ssqWrapStylePosition = '';
635 $absoluteScrollsequenceStyle = 'style="display:block;position:relative;"';
636 }
637
638 }
639
640 }
641
642 }
643
644 // Localize/Inline Script
645 static $ssqScCount = 0 ;
646
647 if ( !$ssqScCount ) {
648 // First run we need to declare variable and input
649 $inlineData = 'var ssqInput={};
650 ssqInput=' . json_encode( $ssqInputZeroObject ) . ';
651 ssqInput.sc=[];
652 ssqInput.sc[' . $ssqScCount . ']=' . json_encode( $ssqInputObject ) . ';';
653 } else {
654 // All other runs just input
655 $inlineData = 'ssqInput.sc[' . $ssqScCount . ']=' . json_encode( $ssqInputObject ) . ';';
656 }
657
658 wp_enqueue_script( 'scrollsequence-lib' );
659 // Prepare for returning onlyonece HTML
660
661 if ( !$ssqScCount ) {
662 // First run
663 $onlyonceHtml = '
664
665 <style>
666 .scrollsequence-pages-wrap {height:100vh}
667 .scrollsequence-page {position:absolute;display:none}
668
669 .gsap-marker-scroller-start {z-index:999999!important;}
670 </style>
671 <noscript>
672 <style>
673 .scrollsequence-wrap {height:initial!important;}
674 .scrollsequence-pages-wrap {height:initial}
675 .scrollsequence-page {position:relative;opacity:initial;display:block ;visibility:initial}
676 </style>
677 </noscript>
678
679 <div style="position: fixed;z-index:99999;bottom:50px;left: 100px;background:#383131b0;color:white; padding: 0.5rem; display:none" class="ssq-alert-container" id="ssqalert" >
680 </div>
681
682 ';
683 } else {
684 $onlyonceHtml = '';
685 }
686
687 //all other runs
688 // Style for each SC
689 $customCssVar = '';
690 if ( !empty(carbon_get_post_meta( $id, 'scrollsequence_custom_css' )) ) {
691 $customCssVar = '
692 <style>
693 ' . carbon_get_post_meta( $id, 'scrollsequence_custom_css' ) . '
694 </style>
695 ';
696 }
697 // end of if not empty
698 // Prepare for returning pages html
699 $pagesHtml = array();
700 foreach ( $ssqPageFromUI as $p => $pagevar ) {
701 /**
702 * Filter Stuff
703 * Since 1.1.2.
704 * Inspired from: https://wordpress.stackexchange.com/questions/134582/apply-filtersthe-content-content-alternative
705 * List of standard filters for the_content
706 * source: https://core.trac.wordpress.org/browser/tags/5.7.2/src/wp-includes/default-filters.php#L131
707 * search for "the_content" to find what things are applied as standard
708 */
709 $filterSsqPageContent = do_blocks( $ssqPageFromUI[$p]['scrollsequence_p_wysiwyg'] );
710 // priority 9 // Introduced 5.0
711 $filterSsqPageContent = wptexturize( $filterSsqPageContent );
712 // Introduced 0.71
713 $filterSsqPageContent = wpautop( $filterSsqPageContent );
714 // Introduced 0.71
715 $filterSsqPageContent = do_shortcode( $filterSsqPageContent );
716 // Introduced 2.5
717 $filterSsqPageContent = shortcode_unautop( $filterSsqPageContent );
718 // Introduced in 2.9
719 $filterSsqPageContent = prepend_attachment( $filterSsqPageContent );
720 // Introduced in 2.0
721 // $filterSsqPageContent = wp_filter_content_tags($filterSsqPageContent); // Introducted in 5.5 - cannot use (yet)
722 // $filterSsqPageContent = wp_replace_insecure_home_url($filterSsqPageContent); // Introducted WP 5.7 - cannot use (yet)
723 $filterSsqPageContent = convert_smilies( $filterSsqPageContent );
724 // priority 20? // Introduced longtimeago
725 // Page HTML
726 $pagesHtml[$p] = '
727 <div class="scrollsequence-page" id="ssq-page-' . $ssqScCount . '-' . $p . '" style="box-sizing: border-box;height:100vh;width:100%;overflow:hidden!important;">
728 ' . $filterSsqPageContent . '
729 </div>
730 ';
731 }
732 // return
733 $returnvar = '
734
735 <!-- Scrollsequence WP Plugin -->
736 <scrollsequence ' . $absoluteScrollsequenceStyle . '>
737 ' . $onlyonceHtml . $customCssVar . '
738 <section class="scrollsequence-wrap ssq-wrap-' . $ssqScCount . ' " id="ssq-uid-' . get_the_id() . '-' . $ssqScCount . '-' . $id . '" style="' . $ssqWrapStylePosition . ';height: calc(100vh + ' . $ssqDomSpacer . 'px);padding:0;margin:0; margin-top:' . $margintop . ';margin-bottom:' . $marginbottom . '; width:100%; max-width:initial;box-sizing: border-box;border:-1px dashed blue;">
739 <div class="scrollsequence-sticky" style="' . $stickyStyle . '">
740 <canvas class="scrollsequence-canvas" style="position:absolute;"></canvas>
741 <div class="scrollsequence-pages-wrap" style="position:relative; margin:0; padding:0; box-sizing: border-box;">
742 ' . implode( " ", $pagesHtml ) . '
743 </div>
744 </div><!-- .scrollsequence-sticky -->
745
746
747 </section><!-- .scrollsequence-wrap -->
748 ' . '<script class="scrollsequence-input-script">
749 ' . $inlineData . '
750 </script>
751 </scrollsequence>
752 ';
753 // Free
754 $ssqScCount++;
755
756 if ( $ssqScCount <= 1 ) {
757 return $returnvar;
758 } else {
759 return '<section><h5 style="border:2px solid; padding:20px">' . __( 'For performance reasons only one shortcode is allowed in Scrollsequence FREE.', 'scrollsequence' ) . '<br><br> <a href="' . admin_url( 'admin.php?page=scrollsequence-pricing' ) . '">' . __( 'Upgrade to PRO version for unlimited shortcodes.', 'scrollsequence' ) . '</a> </h5></section>';
760 }
761
762 // end of else count other than zero
763 // end of free
764 }
765
766 // end of scrollsequence_shortcode function
767 /**
768 * Add Columns to Custom Post Type List
769 *
770 *
771 */
772 function scrollsequence_admin_columns( $columns )
773 {
774 $columns = array(
775 'cb' => $columns['cb'],
776 'title' => __( 'Title', 'scrollsequence' ),
777 'ssq_shortcode' => __( 'Shortcode', 'scrollsequence' ),
778 'date' => __( 'Date', 'scrollsequence' ),
779 'author' => __( 'Author', 'scrollsequence' ),
780 );
781 return $columns;
782 }
783
784 function scrollsequence_admin_column_content( $column, $id )
785 {
786 if ( 'ssq_shortcode' == $column ) {
787 echo '[scrollsequence id="' . $id . '"]' ;
788 }
789 }
790
791 /**
792 * Admin Columns - FEATURED IMAGE
793 *
794 * Since 1.2.0
795 *
796 *
797 */
798 function ssq_add_thumbnail_column( $columns )
799 {
800 $columns['ssq_post_thumb'] = __( 'Featured Image', 'scrollsequence' );
801 return $columns;
802 }
803
804 function ssq_display_thumbnail_column( $column_name, $post_id )
805 {
806 switch ( $column_name ) {
807 case 'ssq_post_thumb':
808 $post_thumbnail_id = get_post_thumbnail_id( $post_id );
809
810 if ( $post_thumbnail_id ) {
811 $post_thumbnail_img = wp_get_attachment_image_src( $post_thumbnail_id, 'thumbnail' );
812 echo '<img width="64" src="' . $post_thumbnail_img[0] . '" />' ;
813 } else {
814 // no thumbnail, try to use something else
815 $idOfFirstImage = carbon_get_post_meta( get_the_ID(), 'scrollsequence_page' );
816 //var_dump($idOfFirstImage);
817 // Check that is array check that images is array and finally check that count of images is bigger than one.
818
819 if ( is_array( $idOfFirstImage ) && count( $idOfFirstImage ) > 0 && is_array( $idOfFirstImage[0]['scrollsequence_p_images'] ) && count( $idOfFirstImage[0]['scrollsequence_p_images'] ) > 0 ) {
820 // first image in sequence exists
821 echo '<img width="64" src="' . wp_get_attachment_image_src( $idOfFirstImage[0]['scrollsequence_p_images'][0], 'thumbnail' )[0] . '" />' ;
822 } else {
823 // there are no images here
824 echo 'No Image' ;
825 }
826
827 }
828
829 break;
830 }
831 }
832
833 /**
834 * Register Settings Options in Scrollsequence Options Dashboard
835 *
836 * @since 1.1.1
837 */
838 function scrollsequence_register_options_settings()
839 {
840 // whitelist options
841 register_setting( 'scrollsequence-settings-group', 'ssq_option_preload_percentage', array(
842 'default' => 0.12,
843 ) );
844 register_setting( 'scrollsequence-settings-group', 'ssq_option_position_sticky', array(
845 'default' => 'sticky-js',
846 ) );
847 // since 1.3.0
848 register_setting( 'scrollsequence-settings-group', 'ssq_option_canvas_dpr', array(
849 'default' => 'quality',
850 ) );
851 // since 1.3.3
852 // TODO
853 // register_setting( 'scrollsequence-settings-group', 'ssq_option_scroller_proxy' ); // not implemented yet
854 // register_setting( 'scrollsequence-settings-group', 'ssq_option_elementor_widget' ); // not implemented yet
855 }
856
857 /**
858 * DUPLICATE SCROLLSEQUENCE
859 * @snippet Duplicate posts and pages without plugins
860 * @author Misha Rudrastyh
861 * @url https://rudrastyh.com/wordpress/duplicate-post.html
862 *
863 */
864 // Add the duplicate link to action list for post_row_actions for "post" and custom post types
865 function ssq_duplicate_post_link( $actions, $post )
866 {
867 if ( !current_user_can( 'edit_posts' ) ) {
868 return $actions;
869 }
870 if ( $post->post_type !== 'scrollsequence' ) {
871 return $actions;
872 }
873 $url = wp_nonce_url( add_query_arg( array(
874 'action' => 'duplicate_scrollsequence_as_draft',
875 'post' => $post->ID,
876 ), 'admin.php' ), basename( __FILE__ ), 'duplicate_ssq_nonce' );
877 $actions['duplicate_ssq'] = '<a href="' . $url . '" title="' . __( 'Duplicate Scrollsequence' ) . '" rel="permalink">' . __( 'Duplicate' ) . '</a>';
878 return $actions;
879 }
880
881 /*
882 * Function creates post duplicate as a draft and redirects then to the edit post screen
883 */
884 function duplicate_scrollsequence_as_draft()
885 {
886 // check if post ID has been provided and action
887 if ( empty($_GET['post']) ) {
888 wp_die( 'No post to duplicate has been provided!' );
889 }
890 // Nonce verification
891 if ( !isset( $_GET['duplicate_ssq_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_ssq_nonce'], basename( __FILE__ ) ) ) {
892 return;
893 }
894 // Get the original post id
895 $post_id = absint( $_GET['post'] );
896 // And all the original post data then
897 $post = get_post( $post_id );
898 /*
899 * if you don't want current user to be the new post author,
900 * then change next couple of lines to this: $new_post_author = $post->post_author;
901 */
902 $current_user = wp_get_current_user();
903 $new_post_author = $current_user->ID;
904 // if post data exists (I am sure it is, but just in a case), create the post duplicate
905
906 if ( $post ) {
907 // new post data array
908 $args = array(
909 'comment_status' => $post->comment_status,
910 'ping_status' => $post->ping_status,
911 'post_author' => $new_post_author,
912 'post_content' => $post->post_content,
913 'post_excerpt' => $post->post_excerpt,
914 'post_name' => $post->post_name,
915 'post_parent' => $post->post_parent,
916 'post_password' => $post->post_password,
917 'post_status' => 'draft',
918 'post_title' => $post->post_title . '_duplicate',
919 'post_type' => $post->post_type,
920 'to_ping' => $post->to_ping,
921 'menu_order' => $post->menu_order,
922 );
923 // insert the post by wp_insert_post() function
924 $new_post_id = wp_insert_post( $args );
925 /*
926 * get all current post terms ad set them to the new post draft
927 */
928 $taxonomies = get_object_taxonomies( get_post_type( $post ) );
929 // returns array of taxonomy names for post type, ex array("category", "post_tag");
930 if ( $taxonomies ) {
931 foreach ( $taxonomies as $taxonomy ) {
932 $post_terms = wp_get_object_terms( $post_id, $taxonomy, array(
933 'fields' => 'slugs',
934 ) );
935 wp_set_object_terms(
936 $new_post_id,
937 $post_terms,
938 $taxonomy,
939 false
940 );
941 }
942 }
943 // duplicate all post meta
944 $post_meta = get_post_meta( $post_id );
945 if ( $post_meta ) {
946 foreach ( $post_meta as $meta_key => $meta_values ) {
947 if ( '_wp_old_slug' == $meta_key ) {
948 // do nothing for this meta key
949 continue;
950 }
951 foreach ( $meta_values as $meta_value ) {
952 add_post_meta( $new_post_id, $meta_key, $meta_value );
953 }
954 }
955 }
956 // finally, redirect to the edit post screen for the new draft
957 // wp_safe_redirect(
958 // add_query_arg(
959 // array(
960 // 'action' => 'edit',
961 // 'post' => $new_post_id
962 // ),
963 // admin_url( 'post.php' )
964 // )
965 // );
966 // exit;
967 // or we can redirect to all posts with a message
968 wp_safe_redirect( add_query_arg( array(
969 'post_type' => ( 'post' !== get_post_type( $post ) ? get_post_type( $post ) : false ),
970 'saved' => 'post_duplication_created',
971 ), admin_url( 'edit.php' ) ) );
972 exit;
973 } else {
974 wp_die( 'Post creation failed, could not find original post.' );
975 }
976
977 }
978
979 /*
980 * In case we decided to add admin notices
981 */
982 function ssq_duplication_admin_notice()
983 {
984 // Get the current screen
985 $screen = get_current_screen();
986 if ( 'edit' !== $screen->base ) {
987 return;
988 }
989 //Checks if settings updated
990 if ( isset( $_GET['saved'] ) && 'post_duplication_created' == $_GET['saved'] ) {
991 echo '<div class="notice notice-success is-dismissible"><p>' . __( 'Copy created.' ) . '</p></div>' ;
992 }
993 }
994
995 // end of duplicate
996 /**
997 * This function defines helpscout beacon
998 *
999 *
1000 */
1001 public function ssq_add_helpscout_beacon()
1002 {
1003 global $post_type ;
1004 //var_dump($post_type);
1005 global $pagenow ;
1006 //var_dump($pagenow);
1007
1008 if ( 'scrollsequence' == $post_type && ('post-new.php' === $pagenow || 'post.php' === $pagenow) || 'scrollsequence' == $post_type && 'edit.php' === $pagenow || 'admin.php' === $pagenow && isset( $_GET['page'] ) && $_GET['page'] === 'scrollsequence-dashboard' || 'admin.php' === $pagenow && isset( $_GET['page'] ) && $_GET['page'] === 'scrollsequence-account' || 'admin.php' === $pagenow && isset( $_GET['page'] ) && $_GET['page'] === 'scrollsequence-contact' ) {
1009 // Inline Script on admin screen - not ready yet, too few articles in the thing.
1010 ?>
1011 <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
1012 <script type="text/javascript">window.Beacon('init', '751bcab8-88ed-4f04-9255-788822978f93')</script>
1013 <?php
1014 }
1015
1016 }
1017
1018 }
1019 // end of class Scrollsequence_Admin