| 1 |
<?php |
| 2 |
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- Legacy CTL_* class name kept for compatibility. |
| 3 |
/** |
| 4 |
* CTL Shortcode. |
| 5 |
* |
| 6 |
* @package CTL |
| 7 |
*/ |
| 8 |
|
| 9 |
/** |
| 10 |
* Do not access the page directly |
| 11 |
*/ |
| 12 |
if ( ! defined( 'ABSPATH' ) ) { |
| 13 |
exit; |
| 14 |
} |
| 15 |
|
| 16 |
|
| 17 |
/** |
| 18 |
* Create shortcode class if class not exists |
| 19 |
*/ |
| 20 |
if ( ! class_exists( 'CTL_Shortcode' ) ) { |
| 21 |
|
| 22 |
/** |
| 23 |
* Class Shortcode. |
| 24 |
*/ |
| 25 |
class CTL_Shortcode { |
| 26 |
|
| 27 |
/** |
| 28 |
* Shortcode assets object variable |
| 29 |
* |
| 30 |
* @var object |
| 31 |
*/ |
| 32 |
public $ctl_asset_obj = array(); |
| 33 |
|
| 34 |
/** |
| 35 |
* Configure settings array |
| 36 |
* |
| 37 |
* @var settings |
| 38 |
*/ |
| 39 |
public $settings = array(); |
| 40 |
|
| 41 |
/** |
| 42 |
* Shortcode attribute array configure |
| 43 |
* |
| 44 |
* @var attribute |
| 45 |
*/ |
| 46 |
public $attributes = array(); |
| 47 |
|
| 48 |
|
| 49 |
/** |
| 50 |
* Constructor |
| 51 |
* |
| 52 |
* @param object $settings_obj timeline settings object. |
| 53 |
*/ |
| 54 |
public function __construct( $settings_obj ) { |
| 55 |
$this->settings = $settings_obj->ctl_get_settings(); |
| 56 |
// register actions. |
| 57 |
add_action( 'init', array( $this, 'ctl_register_shortcode' ) ); |
| 58 |
// layout files loader. |
| 59 |
$this->ctl_layout_loader(); |
| 60 |
|
| 61 |
$this->ctl_asset_obj = new CTL_Assets_Loader(); |
| 62 |
|
| 63 |
// Preview Ajax request instance |
| 64 |
CTL_Ajax_Handler::get_instance(); |
| 65 |
} |
| 66 |
|
| 67 |
/** |
| 68 |
* Load all layouts files |
| 69 |
*/ |
| 70 |
public function ctl_layout_loader() { |
| 71 |
require_once CTL_PLUGIN_DIR . 'includes/shortcodes/class-ctl-loop-helpers.php'; |
| 72 |
require_once CTL_PLUGIN_DIR . 'includes/shortcodes/class-ctl-layout-manager.php'; |
| 73 |
require_once CTL_PLUGIN_DIR . 'includes/shortcodes/class-ctl-assets-loader.php'; |
| 74 |
require_once CTL_PLUGIN_DIR . 'includes/shortcodes/class-ctl-styles-generator.php'; |
| 75 |
require_once CTL_PLUGIN_DIR . 'includes/shortcodes/class-ctl-ajax-handler.php'; |
| 76 |
} |
| 77 |
|
| 78 |
/** |
| 79 |
* Add shortcode |
| 80 |
*/ |
| 81 |
public function ctl_register_shortcode() { |
| 82 |
add_shortcode( 'cool-timeline', array( $this, 'ctl_shortcode_handler' ) ); |
| 83 |
|
| 84 |
} |
| 85 |
/** |
| 86 |
* Set shortcode attribute |
| 87 |
* render shortcode block |
| 88 |
* |
| 89 |
* @param array $atts shortcode attributes. |
| 90 |
* @param string $content shortcode content. |
| 91 |
*/ |
| 92 |
public function ctl_shortcode_handler( $atts ) { |
| 93 |
/** |
| 94 |
* Demo shortcode attributes |
| 95 |
* [cool-timeline layout="default" skin="default" show-posts="10" date-format="F j" icons="NO" animation="none" story-content="short" order="DESC" ] |
| 96 |
*/ |
| 97 |
|
| 98 |
// animations,animation. |
| 99 |
|
| 100 |
$default_attr = array( |
| 101 |
// Main configuration attributes. |
| 102 |
'post_per_page' => 10, |
| 103 |
'layout' => '', |
| 104 |
'order' => '', |
| 105 |
'story-content' => '', |
| 106 |
'animation' => '', |
| 107 |
'date-format' => '', |
| 108 |
'icons' => 'YES', |
| 109 |
'show-posts' => '', |
| 110 |
'skin' => 'default', |
| 111 |
'items' => '', |
| 112 |
); |
| 113 |
|
| 114 |
// Set shortcode attribute. |
| 115 |
$this->attributes = shortcode_atts( $default_attr, $atts ); |
| 116 |
|
| 117 |
$this->attributes = $this->attributes_migration( $this->attributes, $atts ); |
| 118 |
|
| 119 |
// Shortcode type define. |
| 120 |
$this->attributes['ctl_type'] = 'story_timeline'; |
| 121 |
|
| 122 |
CTL_Helpers::has_shortcode_added( get_the_ID(), $this->attributes['layout'] ); |
| 123 |
|
| 124 |
// load timeline global assets. |
| 125 |
$this->ctl_asset_obj->ctl_global_assets( $this->attributes ); |
| 126 |
|
| 127 |
$this->attributes['config'] = $this->ctl_config_layouts( $this->attributes ); |
| 128 |
$paged = 1; |
| 129 |
// include pagination arguments. |
| 130 |
if ( get_query_var( 'paged' ) ) { |
| 131 |
$paged = get_query_var( 'paged' ); |
| 132 |
} elseif ( get_query_var( 'page' ) ) { |
| 133 |
$paged = get_query_var( 'page' ); |
| 134 |
} |
| 135 |
$this->attributes['paged'] = $paged; |
| 136 |
$wp_query = $this->ctl_query_object(); |
| 137 |
// timeline html based on layout. |
| 138 |
$layout_manager_object = new CTL_Layout_Manager( $this->attributes, $wp_query, $this->settings ); |
| 139 |
$output = $layout_manager_object->render_layout(); |
| 140 |
return $output; |
| 141 |
} |
| 142 |
|
| 143 |
/** |
| 144 |
* Wp_query to get all stories. |
| 145 |
*/ |
| 146 |
public function ctl_query_object() { |
| 147 |
$attributes = $this->attributes; |
| 148 |
$show_posts = ! empty( $attributes['show-posts'] ) ? $attributes['show-posts'] : $attributes['post_per_page']; |
| 149 |
$show_posts = ( '-1' === trim( (string) $show_posts ) ) ? -1 : max( 1, absint( $show_posts ) ); |
| 150 |
$order = ! empty( $attributes['order'] ) ? strtoupper( sanitize_key( $attributes['order'] ) ) : strtoupper( sanitize_key( $this->settings['story_orders'] ) ); |
| 151 |
$order = in_array( $order, array( 'ASC', 'DESC' ), true ) ? $order : 'DESC'; |
| 152 |
|
| 153 |
$query_args = array( |
| 154 |
'post_type' => 'cool_timeline', |
| 155 |
'post_status' => array( 'publish', 'future' ), |
| 156 |
'order' => $order, |
| 157 |
'meta_key' => 'ctl_story_timestamp', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key |
| 158 |
'orderby' => 'meta_value_num', |
| 159 |
'posts_per_page' => $show_posts, |
| 160 |
'paged' => max( 1, absint( $attributes['paged'] ) ), |
| 161 |
); |
| 162 |
|
| 163 |
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound |
| 164 |
$query_args = apply_filters( 'ctp_story_query_args', $query_args, $attributes ); |
| 165 |
return new WP_Query( $query_args ); |
| 166 |
} |
| 167 |
|
| 168 |
/** |
| 169 |
* Configure layout based on the settings. |
| 170 |
* |
| 171 |
* @param object $attributes shortcode attributes. |
| 172 |
*/ |
| 173 |
public function ctl_config_layouts( $attributes ) { |
| 174 |
$config_arr = array(); |
| 175 |
$main_wrapper_cls = 'ctl-wrapper'; |
| 176 |
$wrapper_cls = array( 'cool-timeline-wrapper' ); |
| 177 |
$ctl_animation = ''; |
| 178 |
$config_arr['data_attribute'] = array(); |
| 179 |
|
| 180 |
$layout = $this->ctl_set_val( $attributes['layout'], 'default' ); |
| 181 |
$skin = $this->ctl_set_val( $attributes['skin'], 'default' ); |
| 182 |
// create wrapper class based upon layout. |
| 183 |
switch ( $layout ) { |
| 184 |
case 'one-side': |
| 185 |
$wrapper_cls[] = 'ctl-one-sided'; |
| 186 |
$wrapper_cls['ctl_design_cls'] = 'ctl-vertical-wrapper'; |
| 187 |
break; |
| 188 |
case 'compact': |
| 189 |
$wrapper_cls[] = 'ctl-both-sided'; |
| 190 |
$wrapper_cls[] = 'ctl-vertical-wrapper'; |
| 191 |
$wrapper_cls['ctl_design_cls'] = 'ctl-compact-wrapper'; |
| 192 |
break; |
| 193 |
case 'horizontal': |
| 194 |
$wrapper_cls[] = 'ctl-horizontal'; |
| 195 |
$wrapper_cls['ctl_design_cls'] = 'ctl-horizontal-wrapper'; |
| 196 |
$wrapper_cls[] = 'ctl-horizontal-timeline'; |
| 197 |
break; |
| 198 |
default: |
| 199 |
$wrapper_cls[] = 'ctl-both-sided'; |
| 200 |
$wrapper_cls['ctl_design_cls'] = 'ctl-vertical-wrapper'; |
| 201 |
break; |
| 202 |
} |
| 203 |
|
| 204 |
if ( 'clean' === $skin ) { |
| 205 |
$wrapper_cls[] = 'ctl-clean-skin'; |
| 206 |
} |
| 207 |
// create here a deprcated logic. |
| 208 |
|
| 209 |
// Deprecated animations attribute setting if the user has configured the shortcode with animations attribute. |
| 210 |
$ctl_animation = $attributes['animation']; |
| 211 |
|
| 212 |
if ( in_array( $ctl_animation, CTL_Helpers::get_deprecated_animations(), true ) ) { |
| 213 |
$ctl_animation = 'fade-in'; |
| 214 |
} |
| 215 |
|
| 216 |
if ( 'horizontal' === $layout ) { |
| 217 |
$config_arr['data_attribute'][] = 'data-items="' . esc_attr( $this->attributes['items'] ) . '"'; |
| 218 |
} |
| 219 |
|
| 220 |
$config_arr['layout'] = esc_attr( $layout ); |
| 221 |
$config_arr['active_skin'] = esc_attr( $skin ); |
| 222 |
$config_arr['main_wrp_cls'] = esc_attr( $main_wrapper_cls ); |
| 223 |
$config_arr['wrapper_cls'] = $wrapper_cls; |
| 224 |
$config_arr['wrapper_id'] = wp_unique_id( 'cool_timeline_' ); |
| 225 |
$config_arr['animation'] = ! empty( $ctl_animation ) ? esc_attr( $ctl_animation ) : 'none'; |
| 226 |
return $config_arr; |
| 227 |
} |
| 228 |
|
| 229 |
public function attributes_migration( $attr, $shortcode_attr ) { |
| 230 |
$shortcode_attr = empty( $shortcode_attr ) ? array() : $shortcode_attr; |
| 231 |
if ( ( 'horizontal' === $attr['layout'] && ! array_key_exists( 'items', $shortcode_attr ) ) || ( array_key_exists( 'items', $shortcode_attr ) && empty( $shortcode_attr['items'] ) ) ) { |
| 232 |
$attr['items'] = isset( $attr['show-posts'] ) ? max( 1, absint( $attr['show-posts'] ) ) : absint( $this->settings['post_per_page'] ); |
| 233 |
$attr['show-posts'] = '-1'; |
| 234 |
} |
| 235 |
if ( isset( $attr['date-format'] ) && 'default' === $attr['date-format'] ) { |
| 236 |
$attr['date-format'] = 'F j'; |
| 237 |
} |
| 238 |
return $attr; |
| 239 |
} |
| 240 |
|
| 241 |
/** |
| 242 |
* Configure default values |
| 243 |
* |
| 244 |
* @param string $value shortcode attribute new value. |
| 245 |
* @param string $default shortcode attribute default value. |
| 246 |
*/ |
| 247 |
public function ctl_set_val( $value, $default ) { |
| 248 |
if ( isset( $value ) && ! empty( $value ) ) { |
| 249 |
return $value; |
| 250 |
} |
| 251 |
return $default; |
| 252 |
} |
| 253 |
} |
| 254 |
|
| 255 |
} |
| 256 |
|