PluginProbe
Gridable / trunk
Gridable vtrunk
1.2.12 1.2.11 trunk 0.1.0 0.5.0 1.0.0 1.1.0 1.2.0 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9
gridable / public / class-gridable-public.php

class-gridable-public.php in Gridable trunk, at public/class-gridable-public.php

339 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 /**
7 * The public-facing functionality of the plugin.
8 *
9 * @link https://pixelgrade.com
10 * @since 1.0.0
11 *
12 * @package Gridable
13 * @subpackage Gridable/public
14 */
15
16 /**
17 * The public-facing functionality of the plugin.
18 *
19 * Defines the plugin name, version, and two examples hooks for how to
20 * enqueue the admin-specific stylesheet and JavaScript.
21 *
22 * @package Gridable
23 * @subpackage Gridable/public
24 * @author Pixelgrade <contact@pixelgrade.com>
25 */
26 class Gridable_Public {
27
28 /**
29 * The ID of this plugin.
30 *
31 * @since 1.0.0
32 * @access private
33 * @var string $gridable The ID of this plugin.
34 */
35 private $gridable;
36
37 /**
38 * The version of this plugin.
39 *
40 * @since 1.0.0
41 * @access private
42 * @var string $version The current version of this plugin.
43 */
44 private $version;
45
46 private $last_row_pos = 0;
47
48 /**
49 * Initialize the class and set its properties.
50 *
51 * @since 1.0.0
52 *
53 * @param string $gridable The name of the plugin.
54 * @param string $version The version of this plugin.
55 */
56 public function __construct( $gridable, $version ) {
57 $this->gridable = $gridable;
58 $this->version = $version;
59 }
60
61 /**
62 * Render the [row]
63 *
64 * This function allows themes to overwrite row templates
65 * in `theme_name/temaplates/gridable/row.php` (filtrable path)
66 *
67 * @param $atts
68 * @param $content
69 *
70 * @return string
71 */
72 public function add_row_shortcode( $atts, $content ) {
73 $tag = 'row';
74
75 $atts = array_merge( (array) $atts, shortcode_atts( array(
76 'cols_nr' => '',
77 ), (array) $atts, $tag ) );
78
79 $cols_nr = 1;
80
81 if ( ! empty( $atts['cols_nr'] ) ) {
82 $cols_nr = (int) $atts['cols_nr'];
83 }
84
85 $classes = apply_filters( "gridable_row_class", array( "gridable", "gridable--row" ), $cols_nr, $atts, $content );
86
87 $classes = array_map( 'esc_attr', $classes );
88
89 $class = join( ' ', array_unique( $classes ) );
90
91 // get sh template
92 $template = $this->get_localed_sh_templated( $tag );
93 // load it
94 ob_start();
95 require $template;
96 return ob_get_clean();
97 }
98
99 /**
100 * Render the [col]
101 *
102 * This function allows themes to overwrite col templates
103 * in `theme_name/temaplates/gridable/col.php` (filtrable path)
104 *
105 * @param $atts
106 * @param $content
107 *
108 * @return string
109 */
110 public function add_column_shortcode( $atts, $content ) {
111 $tag = 'col';
112
113 $atts = array_merge( (array) $atts, shortcode_atts( array(
114 'size' => '',
115 ), (array) $atts, $tag ) );
116
117 $size = 1;
118 if ( ! empty( $atts['size'] ) ) {
119 $size = (int) $atts['size'];
120 }
121
122 $size = apply_filters( "gridable_column_size", $size );
123
124 $classes = apply_filters( "gridable_column_class", array( 'gridable--col', 'col-' . $size ), $size, $atts, $content );
125
126 $classes = array_map( 'esc_attr', $classes );
127
128 $class = join( ' ', array_unique( $classes ) );
129
130 // get sh template
131 $template = $this->get_localed_sh_templated( $tag );
132 // load it
133 ob_start();
134 require $template;
135 return ob_get_clean();
136 }
137
138 /**
139 * This function will try to return the right template for a given tag
140 * If the template exists in theme it will have priority
141 * Else the plugin default from partials will be returned
142 * @param $tag
143 *
144 * @return bool|string
145 */
146 public function get_localed_sh_templated( $tag ) {
147
148 if ( empty( $tag ) ) {
149 return false;
150 }
151
152 /**
153 * Template localization between plugin and theme
154 */
155 $theme_path = apply_filters( 'gridable_theme_templates_path_filter', 'template-parts/gridable/', $tag );
156 $theme_path = $theme_path . $tag . '.php';
157 $located = locate_template( $theme_path, false, false );
158
159 if ( ! $located ) {
160 $located = dirname( __FILE__ ) . '/partials/' . $tag . '.php';
161 }
162
163 return $located;
164 }
165
166 /**
167 * Register the stylesheets for the public-facing side of the site.
168 *
169 * @since 1.0.0
170 */
171 public function enqueue_styles() {
172 // @TODO Write documentation for this
173 if ( ! apply_filters( 'gridable_load_public_style', '__return_true' ) ) {
174 return;
175 }
176
177 /**
178 * This function is provided for demonstration purposes only.
179 *
180 * An instance of this class should be passed to the run() function
181 * defined in Gridable_Loader as all of the hooks are defined
182 * in that particular class.
183 *
184 * The Gridable_Loader will then create the relationship
185 * between the defined hooks and the functions defined in this
186 * class.
187 */
188
189 wp_enqueue_style( $this->gridable, plugin_dir_url( __FILE__ ) . 'css/gridable-style.css', array(), $this->version, 'all' );
190 }
191
192 /**
193 * This function strips unclosed p tags at a beggining and at the end of a row
194 * @param $content
195 * @param $atts
196 *
197 * @return string
198 */
199 public function gridable_fix_lost_p_tags( $content, $atts ) {
200 $first_4_chars = substr( $content, 0, 4 );
201
202 $last_3_chars = substr( $content, -3, 4 );
203
204 if ( '</p>' === $first_4_chars ) {
205 $content = substr( $content, 5 );
206 }
207
208 if ( '<p>' === $last_3_chars ) {
209 $content = substr( $content, 0, -4 );
210 }
211
212 return $content;
213 }
214
215 public function gridable_add_empty_column_class( $classes, $size, $atts, $content ) {
216
217 if ( empty( $content ) ) {
218 $classes[] = 'empty_column';
219 }
220
221 return $classes;
222 }
223
224 /**
225 * Try to allow one level of nested rows
226 * @param $content
227 *
228 * @return mixed
229 */
230 public function parse_content_for_nested_rows( $content, $rec = false ) {
231 $rows_matches = array();
232
233 preg_match_all( '#' . get_shortcode_regex( array( 'row' ) ) . '#ims', $content, $rows_matches );
234
235 /**
236 * Basically in the first group of matches are the plain row texts
237 * If a row contains another row, we should render it before.
238 */
239 if ( ! empty( $rows_matches[0] ) ) {
240
241 // iterate through each row and check if anyone has a nested row
242 foreach ( $rows_matches[0] as $key => $match ) {
243
244 $row_pos = strpos( $rows_matches[0][$key], '[row cols_nr="', 5 );
245
246 // if there is another row inside render it first
247 if ( $row_pos !== false ) {
248 // make a clone of the original row
249 $temp_row = $match;
250 // if this row has an inner row, let's render it and replace it in the clone row
251 preg_match( '#' . get_shortcode_regex( array( 'row' ) ) . '#', $match, $smatch );
252 if ( substr_count( $smatch[0], '[row ' ) > 1 ) {
253 $inner_rows = array();
254
255 // right now the row form is [row] content [row]content[/row]
256 // if we render the available rows we will have a nested-free row
257 $remove_starting_row = '~\[' . $smatch[1] . $smatch[2] . $smatch[3] . '\]~';
258 $temp_content = preg_replace( $remove_starting_row, '', $smatch[0], 1 );
259
260 preg_match_all( '#' . get_shortcode_regex( array( 'row' ) ) . '#ms', $temp_content, $inner_rows );
261
262 // there may be more than one inner row, catch'em all
263 foreach ( $inner_rows[0] as $inner_row ) {
264 $temp_row = str_replace( $inner_row, do_shortcode( $inner_row ), $temp_row );
265 }
266 }
267
268 // now we have a [row] content <div class="row"></div>
269 // the closing [/row] is definetly somewhere after
270 $content = str_replace( $match, $temp_row, $content );
271 } elseif ( ! $rec ) {
272 $content = $this->parse_content_for_nested_rows( $content, true );
273 }
274 }
275 }
276
277 return $content;
278 }
279
280 /**
281 * Register the JavaScript for the public-facing side of the site.
282 *
283 * @since 1.0.0
284 */
285 public function enqueue_scripts() {
286
287 /**
288 * This function is provided for demonstration purposes only.
289 *
290 * An instance of this class should be passed to the run() function
291 * defined in Gridable_Loader as all of the hooks are defined
292 * in that particular class.
293 *
294 * The Gridable_Loader will then create the relationship
295 * between the defined hooks and the functions defined in this
296 * class.
297 */
298
299 wp_enqueue_script( $this->gridable, plugin_dir_url( __FILE__ ) . 'js/gridable-scripts.js', array( 'jquery' ), $this->version, false );
300
301 }
302
303 /**
304 * Sanitizes attribute fragments provided by Gridable extension filters.
305 *
306 * @since 1.2.10
307 *
308 * @param string $attributes Raw attribute fragment.
309 * @return string Sanitized attribute fragment.
310 */
311 public function sanitize_attribute_fragment( $attributes ) {
312 $attributes = trim( (string) $attributes );
313
314 if ( '' === $attributes ) {
315 return '';
316 }
317
318 $allowed_html = array(
319 'div' => array(
320 'aria-*' => true,
321 'class' => true,
322 'data-*' => true,
323 'id' => true,
324 'role' => true,
325 'style' => true,
326 'title' => true,
327 ),
328 );
329 $sanitized = wp_kses( '<div ' . $attributes . '></div>', $allowed_html );
330
331 if ( preg_match( '/^<div\\s+([^>]*)><\\/div>$/', $sanitized, $matches ) ) {
332 return $matches[1];
333 }
334
335 return '';
336 }
337
338 }
339