PluginProbe
Sharing Image / 3.7
Sharing Image v3.7
3.10 trunk 2.0 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0 3.1 3.2 3.3 All 29 releases
← All changes | classes/class-generator.php +343 -229 2.03.7 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Poster generator class
3 + * Poster generator class.
4 4 *
5 5 * @package sharing-image
6 6 * @author Anton Lukin
7 7 */
@@ -16,141 +16,46 @@
16 16 die;
17 17 }
18 18
19 19 /**
20 - * Poster generator class
20 + * Generator class.
21 21 *
22 22 * @class Generator
23 23 */
24 24 class Generator {
25 25 /**
26 - * The instance of Settings class.
26 + * Check requred template values.
27 27 *
28 - * @var instance
29 - */
30 - private $settings;
31 -
32 - /**
33 - * Generator constructor.
34 - */
35 - public function __construct() {
36 - $this->settings = new Settings();
37 - }
38 -
39 - /**
40 - * Compose image using picker data.
28 + * @param array $template List of template settings.
41 29 *
42 - * @param array $picker Picker data from metabox.
43 - *
44 - * @return array|WP_Error Poster url, width and height or WP_Error on failure.
30 + * @return bool Whether all required values isset.
45 31 */
46 - public function compose( $picker ) {
47 - if ( ! isset( $picker['template'] ) ) {
48 - return new WP_Error( 'validate', esc_html__( 'Template id cannot be empty', 'sharing-image' ) );
49 - }
32 + public static function check_required( $template ) {
33 + $required = array( 'width', 'height', 'fill' );
50 34
51 - $id = absint( $picker['template'] );
35 + // Count intersected values.
36 + $prepared = count( self::prepare_args( $template, $required ) );
52 37
53 - // Get templates list from settings.
54 - $templates = $this->settings->get_templates();
55 -
56 - if ( ! isset( $templates[ $id ] ) ) {
57 - return new WP_Error( 'validate', esc_html__( 'Wrong template id', 'sharing-image' ) );
38 + if ( count( $required ) === $prepared ) {
39 + return true;
58 40 }
59 41
60 - $fieldset = array();
61 -
62 - if ( isset( $picker['fieldset'][ $id ] ) ) {
63 - $fieldset = $picker['fieldset'][ $id ];
64 - }
65 -
66 - $template = $this->prepare_template( $templates[ $id ], $fieldset );
67 -
68 - if ( ! $this->check_required( $template ) ) {
69 - return new WP_Error( 'generate', esc_html__( 'Wrong template settings', 'sharing-image' ) );
70 - }
71 -
72 - list( $path, $url ) = $this->get_upload_file();
73 -
74 - // Generate image and save it to given path.
75 - $poster = $this->create_poster( $template, $path );
76 -
77 - if ( is_wp_error( $poster ) ) {
78 - return $poster;
79 - }
80 -
81 - $result = array(
82 - 'poster' => $url,
83 - 'width' => $template['width'],
84 - 'height' => $template['height'],
85 - );
86 -
87 - return $result;
42 + return false;
88 43 }
89 44
90 45 /**
91 - * Show image for settings page using template data.
92 - *
93 - * @param array $template Templates data from settings page.
94 - * @param int $index Template index.
95 - *
96 - * @return void|WP_Error WP_Error on failure.
97 - */
98 - public function show( $template, $index ) {
99 - $template = $this->prepare_template( $template, null, $index );
100 -
101 - if ( ! $this->check_required( $template ) ) {
102 - return new WP_Error( 'generate', esc_html__( 'Wrong template settings', 'sharing-image' ) );
103 - }
104 -
105 - // Generate image and show it immediately.
106 - $poster = $this->create_poster( $template );
107 -
108 - if ( is_wp_error( $poster ) ) {
109 - return $poster;
110 - }
111 -
112 - exit; // It's ok to exit here. Just cause we show an image above.
113 - }
114 -
115 - /**
116 - * Save image for settings page using template data.
117 - *
118 - * @param array $template Templates data from settings page.
119 - * @param int $index Template index.
120 - *
121 - * @return string|WP_Error Generated poster url or WP_Error on failure.
122 - */
123 - public function save( $template, $index ) {
124 - $template = $this->prepare_template( $template, null, $index );
125 -
126 - if ( ! $this->check_required( $template ) ) {
127 - return new WP_Error( 'generate', esc_html__( 'Wrong template settings', 'sharing-image' ) );
128 - }
129 -
130 - list( $path, $url ) = $this->get_upload_file();
131 -
132 - // Generate image and save it.
133 - $poster = $this->create_poster( $template, $path );
134 -
135 - if ( is_wp_error( $poster ) ) {
136 - return $poster;
137 - }
138 -
139 - return $url;
140 - }
141 -
142 - /**
143 46 * Prepare template before creating poster.
144 47 * Used to fill fieldset texts and background image.
145 48 *
146 - * @param array $template List of template data.
147 - * @param array $fieldset Optional. Fieldset data from picker.
148 - * @param integer $index Optional. Template index from editor.
49 + * @param array $template List of template data.
50 + * @param array $fieldset Optional. Fieldset data from widget.
51 + * @param string $index Optional. Template index from editor.
52 + * @param int $screen_id Optional. Post or term ID from admin screen.
53 + * @param string $context Optional. Screen ID context field. Can be settings, post or term.
149 54 *
150 55 * @return array List of template data.
151 56 */
152 - private function prepare_template( $template, $fieldset = array(), $index = null ) {
57 + public static function prepare_template( $template, $fieldset = array(), $index = null, $screen_id = 0, $context = 'settings' ) {
153 58 $layers = array();
154 59
155 60 if ( isset( $template['layers'] ) ) {
156 61 $layers = $template['layers'];
@@ -155,54 +60,40 @@
155 60 if ( isset( $template['layers'] ) ) {
156 61 $layers = $template['layers'];
157 62 }
158 63
159 - foreach ( $layers as $i => &$layer ) {
160 - if ( empty( $layer['type'] ) || 'text' !== $layer['type'] ) {
161 - continue;
64 + foreach ( $layers as $key => &$layer ) {
65 + if ( 'settings' === $context && ! empty( $template['debug'] ) ) {
66 + $layer['debug'] = true;
162 67 }
163 68
164 - if ( empty( $layer['dynamic'] ) ) {
69 + if ( empty( $layer['type'] ) || empty( $layer['dynamic'] ) ) {
165 70 continue;
166 71 }
167 72
168 - $layer['content'] = null;
73 + switch ( $layer['type'] ) {
74 + case 'image':
75 + $layer = self::prepare_image_layer( $layer, $fieldset, $key, $context );
76 + break;
169 77
170 - if ( isset( $layer['sample'] ) ) {
171 - $layer['content'] = $layer['sample'];
78 + case 'text':
79 + $layer = self::prepare_text_layer( $layer, $fieldset, $key, $context );
80 + break;
172 81 }
173 -
174 - if ( isset( $fieldset['captions'][ $i ] ) ) {
175 - $layer['content'] = $fieldset['captions'][ $i ];
176 - }
177 82 }
178 83
179 84 $template['layers'] = $layers;
180 85
181 - if ( 'dynamic' === $template['background'] ) {
182 - if ( null !== $index ) {
183 - $template['image'] = sprintf( SHARING_IMAGE_DIR . 'assets/images/%d.jpg', ( $index % 12 ) + 1 );
184 - }
185 -
186 - if ( ! empty( $fieldset['attachment'] ) ) {
187 - $template['image'] = get_attached_file( $fieldset['attachment'] );
188 - }
189 - }
190 -
191 - if ( 'permanent' === $template['background'] ) {
192 - if ( ! empty( $template['attachment'] ) ) {
193 - $template['image'] = get_attached_file( $template['attachment'] );
194 - }
195 - }
196 -
197 86 /**
198 87 * Filters template before generation.
199 88 *
200 - * @param array $template List of template data.
201 - * @param array $fieldset Fieldset data from picker.
202 - * @param integer $index Template index from editor.
89 + * @param array $template List of template data.
90 + * @param array $fieldset Fieldset data from widget or sidebars.
91 + * @param string $index Template index from editor.
92 + * @param int $screen_id Post or term ID from admin screen.
93 + * @param string $context Screen ID context field. Can be settings, post or term.
203 94 */
204 - return apply_filters( 'sharing_image_prepare_template', $template, $fieldset, $index );
95 + return apply_filters( 'sharing_image_prepare_template', $template, $fieldset, $index, $screen_id, $context );
205 96 }
206 97
207 98 /**
208 99 * Create poster using template data.
@@ -211,35 +102,30 @@
211 102 * @param string $path Optional. File path to save.
212 103 *
213 104 * @return void|WP_Error WP_Error on failure.
214 105 */
215 - private function create_poster( $template, $path = null ) {
106 + public static function create_poster( $template, $path = null ) {
216 107 try {
217 108 $poster = new PosterEditor();
218 109
219 110 // Set color canvas options.
220 - $options = array( 'color' => $template['fill'] );
111 + $options = array(
112 + 'color' => $template['fill'],
113 + 'opacity' => 0,
114 + );
221 115
222 116 // Create empty poster.
223 117 $poster->canvas( $template['width'], $template['height'], $options );
224 118
225 - // Recreate poster with image if exists.
226 - if ( ! empty( $template['image'] ) ) {
227 - $poster->make( $template['image'] )->fit( $template['width'], $template['height'] );
228 - }
229 -
230 119 if ( ! empty( $template['layers'] ) ) {
231 - $poster = $this->append_layers( $poster, $template['layers'] );
120 + $poster = self::append_layers( $poster, $template['layers'] );
232 121 }
233 122
234 - $settings = $this->settings;
235 -
236 - if ( null === $path ) {
237 - return $poster->show( $settings->get_file_format(), $settings->get_quality() );
123 + if ( is_null( $path ) ) {
124 + return $poster->show( Config::get_file_format(), Config::get_quality() );
238 125 }
239 126
240 - $poster->save( $path, $settings->get_quality() );
241 -
127 + $poster->save( $path, Config::get_quality() );
242 128 } catch ( Exception $e ) {
243 129 return new WP_Error( 'generate', $e->getMessage() );
244 130 }
245 131 }
@@ -244,8 +130,34 @@
244 130 }
245 131 }
246 132
247 133 /**
134 + * Get upload file path and url.
135 + *
136 + * @return array Server file path and url to uploaded image.
137 + */
138 + public static function get_upload_file() {
139 + // Get uploads directory url and path array.
140 + list( $path, $url ) = Config::get_upload_dir();
141 +
142 + // Create random file name with proper extension.
143 + $name = wp_unique_filename( $path, uniqid() . '.' . Config::get_file_format() );
144 +
145 + $file = array(
146 + trailingslashit( $path ) . $name,
147 + trailingslashit( $url ) . $name,
148 + );
149 +
150 + /**
151 + * Filters upload file path and url
152 + *
153 + * @param array $file Server file path and url to image.
154 + * @param string $name Unique file name.
155 + */
156 + return apply_filters( 'sharing_image_get_upload_file', $file, $name );
157 + }
158 +
159 + /**
248 160 * Append layers to image.
249 161 *
250 162 * @param PosterEditor $poster Instance of PosterEditor class.
251 163 * @param array $layers List of layers options.
@@ -251,10 +163,10 @@
251 163 * @param array $layers List of layers options.
252 164 *
253 165 * @return PosterEditor PosterEditor instance.
254 166 */
255 - private function append_layers( $poster, $layers ) {
256 - $layers = array_reverse( $layers );
167 + private static function append_layers( $poster, $layers ) {
168 + $boundary = array();
257 169
258 170 foreach ( $layers as $layer ) {
259 171 if ( empty( $layer['type'] ) ) {
260 172 continue;
@@ -261,21 +173,21 @@
261 173 }
262 174
263 175 switch ( $layer['type'] ) {
264 176 case 'filter':
265 - $poster = $this->draw_filter( $poster, $layer );
177 + $poster = self::draw_filter( $poster, $layer );
266 178 break;
267 179
268 180 case 'rectangle':
269 - $poster = $this->draw_rectangle( $poster, $layer );
181 + $poster = self::draw_rectangle( $poster, $layer, $boundary );
270 182 break;
271 183
272 - case 'text':
273 - $poster = $this->draw_text( $poster, $layer );
184 + case 'image':
185 + $poster = self::draw_image( $poster, $layer, $boundary );
274 186 break;
275 187
276 - case 'image':
277 - $poster = $this->draw_image( $poster, $layer );
188 + case 'text':
189 + $poster = self::draw_text( $poster, $layer, $boundary );
278 190 break;
279 191 }
280 192 }
281 193
@@ -282,8 +194,70 @@
282 194 return $poster;
283 195 }
284 196
285 197 /**
198 + * Prepare image layer template.
199 + *
200 + * @param array $layer Image layer data.
201 + * @param array $fieldset Fieldset data from widget or sidebar.
202 + * @param string $key Layer key.
203 + * @param string $context Screen ID context field. Can be settings, post or term.
204 + *
205 + * @return array List of image layer data.
206 + */
207 + private static function prepare_image_layer( $layer, $fieldset, $key, $context ) {
208 + if ( 'settings' !== $context ) {
209 + unset( $layer['attachment'] );
210 + }
211 +
212 + if ( ! empty( $fieldset[ $key ] ) ) {
213 + $layer['attachment'] = $fieldset[ $key ];
214 + }
215 +
216 + return $layer;
217 + }
218 +
219 + /**
220 + * Prepare text layer template.
221 + *
222 + * @param array $layer Text layer data.
223 + * @param array $fieldset Fieldset data from widget or sidebar.
224 + * @param string $key Layer key.
225 + * @param string $context Screen ID context field. Can be settings, post or term.
226 + *
227 + * @return array List of text layer data.
228 + */
229 + private static function prepare_text_layer( $layer, $fieldset, $key, $context ) {
230 + $layer['content'] = null;
231 +
232 + if ( isset( $layer['sample'] ) && 'settings' === $context ) {
233 + $layer['content'] = $layer['sample'];
234 + }
235 +
236 + if ( isset( $fieldset[ $key ] ) ) {
237 + $layer['content'] = $fieldset[ $key ];
238 + }
239 +
240 + if ( isset( $layer['textconvert'] ) && 'default' !== $layer['textconvert'] ) {
241 + if ( 'uppercase' === $layer['textconvert'] ) {
242 + if ( function_exists( 'mb_strtoupper' ) ) {
243 + $layer['content'] = mb_strtoupper( $layer['content'] );
244 + } else {
245 + $layer['content'] = strtoupper( $layer['content'] );
246 + }
247 + } elseif ( 'lowercase' === $layer['textconvert'] ) {
248 + if ( function_exists( 'mb_strtolower' ) ) {
249 + $layer['content'] = mb_strtolower( $layer['content'] );
250 + } else {
251 + $layer['content'] = strtolower( $layer['content'] );
252 + }
253 + }
254 + }
255 +
256 + return $layer;
257 + }
258 +
259 + /**
286 260 * Draw filter layer
287 261 *
288 262 * @param PosterEditor $poster Instance of PosterEditor class.
289 263 * @param array $layer Filter layer options.
@@ -289,9 +263,9 @@
289 263 * @param array $layer Filter layer options.
290 264 *
291 265 * @return PosterEditor PosterEditor instance.
292 266 */
293 - private function draw_filter( $poster, $layer ) {
267 + private static function draw_filter( $poster, $layer ) {
294 268 if ( ! empty( $layer['grayscale'] ) ) {
295 269 $poster->grayscale();
296 270 }
297 271
@@ -316,20 +290,21 @@
316 290
317 291 /**
318 292 * Draw rectangle layer.
319 293 *
320 - * @param PosterEditor $poster Instance of PosterEditor class.
321 - * @param array $layer Rectangle layer options.
294 + * @param PosterEditor $poster Instance of PosterEditor class.
295 + * @param array $layer Rectangle layer options.
296 + * @param array $boundary Optional. List of previous layer boundaries.
322 297 *
323 298 * @return PosterEditor PosterEditor instance.
324 299 */
325 - private function draw_rectangle( $poster, $layer ) {
300 + private static function draw_rectangle( $poster, $layer, &$boundary = array() ) {
326 301 // Both x and y should be set.
327 302 if ( ! isset( $layer['x'], $layer['y'] ) ) {
328 303 return $poster;
329 304 }
330 305
331 - $args = $this->prepare_args( $layer, array( 'color', 'opacity', 'thickness' ) );
306 + $args = self::prepare_args( $layer, array( 'color', 'opacity', 'thickness' ) );
332 307
333 308 if ( ! empty( $layer['outline'] ) ) {
334 309 $args['outline'] = true;
335 310 }
@@ -334,18 +309,27 @@
334 309 $args['outline'] = true;
335 310 }
336 311
337 312 if ( ! isset( $layer['width'] ) ) {
338 - $layer['width'] = 0;
313 + $layer['width'] = 1;
339 314 }
340 315
341 316 if ( ! isset( $layer['height'] ) ) {
342 - $layer['height'] = 0;
317 + $layer['height'] = 1;
343 318 }
344 319
320 + // Update layer position and dimensions.
321 + $layer = self::update_layer_position( $layer, $boundary );
322 + $layer = self::update_layer_dimensions( $layer, $poster );
323 +
345 324 // Draw rectangle.
346 325 $poster->rectangle( $layer['x'], $layer['y'], $layer['width'], $layer['height'], $args );
347 326
327 + // Set boundary from layer dimensions.
328 + foreach ( array( 'x', 'y', 'width', 'height' ) as $param ) {
329 + $boundary[ $param ] = $layer[ $param ];
330 + }
331 +
348 332 return $poster;
349 333 }
350 334
351 335 /**
@@ -350,46 +334,78 @@
350 334
351 335 /**
352 336 * Draw image layer
353 337 *
354 - * @param PosterEditor $poster Instance of PosterEditor class.
355 - * @param object $layer Option name.
338 + * @param PosterEditor $poster Instance of PosterEditor class.
339 + * @param array $layer Image layer options.
340 + * @param array $boundary Optional. List of previous layer boundaries.
356 341 *
357 342 * @return PosterEditor PosterEditor instance.
358 343 */
359 - private function draw_image( $poster, $layer ) {
360 - // Attachment id is required.
344 + private static function draw_image( $poster, $layer, &$boundary = array() ) {
361 345 if ( ! isset( $layer['attachment'] ) ) {
362 346 return $poster;
363 347 }
364 348
365 - $args = $this->prepare_args( $layer, array( 'x', 'y', 'width', 'height' ) );
349 + $image = new PosterEditor();
366 350
367 - // Get attachment file by id.
368 - $image = get_attached_file( $layer['attachment'] );
351 + // Update layer position and dimensions.
352 + $layer = self::update_layer_position( $layer, $boundary );
353 + $layer = self::update_layer_dimensions( $layer, $poster );
369 354
370 - // Insert image to poster.
371 - $poster->insert( $image, $args );
355 + $args = self::prepare_args( $layer, array( 'x', 'y', 'opacity' ) );
372 356
373 - return $poster;
357 + // Try to get file from attachment id.
358 + $file = get_attached_file( $layer['attachment'] );
359 +
360 + if ( empty( $file ) ) {
361 + return $poster;
362 + }
363 +
364 + // Create new editor instance by attachment id.
365 + $attachment = $image->make( $file );
366 +
367 + return $poster->insert( self::resize_attachment( $attachment, $layer ), $args, $boundary );
374 368 }
375 369
376 370 /**
377 371 * Draw text layer.
378 372 *
379 - * @param PosterEditor $poster Instance of PosterEditor class.
380 - * @param array $layer Rectangle layer options.
373 + * @param PosterEditor $poster Instance of PosterEditor class.
374 + * @param array $layer Text layer options.
375 + * @param array $boundary Optional. List of previous layer boundaries.
381 376 *
382 377 * @return PosterEditor PosterEditor instance.
383 378 */
384 - private function draw_text( $poster, $layer ) {
385 - $args = $this->prepare_args( $layer, array( 'x', 'y', 'width', 'height', 'fontsize', 'color', 'lineheight', 'opacity', 'horizontal', 'vertical' ) );
379 + private static function draw_text( $poster, $layer, &$boundary = array() ) {
380 + $allowed = array(
381 + 'x',
382 + 'y',
383 + 'width',
384 + 'height',
385 + 'fontsize',
386 + 'color',
387 + 'lineheight',
388 + 'opacity',
389 + 'horizontal',
390 + 'vertical',
391 + 'debug',
392 + );
386 393
394 + // Update layer position and dimensions.
395 + $layer = self::update_layer_position( $layer, $boundary );
396 + $layer = self::update_layer_dimensions( $layer, $poster );
397 +
398 + // Prepare common layer args.
399 + $args = self::prepare_args( $layer, $allowed );
400 +
387 401 // Try to set font file by name or attachment path.
388 - $args['fontpath'] = $this->get_fontpath( $layer );
402 + $args['fontpath'] = self::get_fontpath( $layer );
389 403
404 + $boundary = self::set_empty_boundary( $args );
405 +
390 406 if ( ! empty( $layer['content'] ) ) {
391 - $poster->text( $layer['content'], $args );
407 + $poster->text( $layer['content'], $args, $boundary );
392 408 }
393 409
394 410 return $poster;
395 411 }
@@ -394,8 +410,80 @@
394 410 return $poster;
395 411 }
396 412
397 413 /**
414 + * Set empty boundary list to reset boundary for empty layers.
415 + *
416 + * @since 3.0
417 + *
418 + * @param array $args List of common layer args.
419 + */
420 + private static function set_empty_boundary( $args ) {
421 + $boundary = array(
422 + 'x' => 0,
423 + 'y' => 0,
424 + 'width' => 0,
425 + 'height' => 0,
426 + );
427 +
428 + if ( isset( $args['x'] ) ) {
429 + $boundary['x'] = $args['x'];
430 + }
431 +
432 + if ( isset( $args['y'] ) ) {
433 + $boundary['y'] = $args['y'];
434 + }
435 +
436 + return $boundary;
437 + }
438 +
439 + /**
440 + * Smart resizing of image layer attachment according to selected options.
441 + *
442 + * @param PosterEditor $attachment Instance of PosterEditor class.
443 + * @param array $layer Layer settings.
444 + *
445 + * @return PosterEditor PosterEditor instance.
446 + */
447 + private static function resize_attachment( $attachment, $layer ) {
448 + $width = null;
449 +
450 + if ( isset( $layer['width'] ) ) {
451 + $width = $layer['width'];
452 + }
453 +
454 + $height = null;
455 +
456 + if ( isset( $layer['height'] ) ) {
457 + $height = $layer['height'];
458 + }
459 +
460 + // Reduce the image size if width or height dimensions are not specified.
461 + if ( is_null( $width ) || is_null( $height ) ) {
462 + return $attachment->downsize( $width, $height );
463 + }
464 +
465 + if ( 'top' === $layer['resize'] ) {
466 + return $attachment->fit( $width, $height, 'top' );
467 + }
468 +
469 + if ( 'bottom' === $layer['resize'] ) {
470 + return $attachment->fit( $width, $height, 'bottom' );
471 + }
472 +
473 + if ( 'ignore' === $layer['resize'] ) {
474 + return $attachment->resize( $width, $height );
475 + }
476 +
477 + if ( 'crop' === $layer['resize'] ) {
478 + return $attachment->crop( $width, $height );
479 + }
480 +
481 + // Fit center by default.
482 + return $attachment->fit( $width, $height );
483 + }
484 +
485 + /**
398 486 * Get font file path by layer data.
399 487 *
400 488 * @param array $layer Layer data.
401 489 * @param string $path Default file path.
@@ -401,11 +489,11 @@
401 489 * @param string $path Default file path.
402 490 *
403 491 * @return string Filtered path to font file.
404 492 */
405 - private function get_fontpath( $layer, $path = '' ) {
493 + private static function get_fontpath( $layer, $path = '' ) {
406 494 if ( isset( $layer['fontname'] ) ) {
407 - $path = sprintf( SHARING_IMAGE_DIR . 'assets/fonts/%s.ttf', $layer['fontname'] );
495 + $path = sprintf( SHARING_IMAGE_DIR . 'fonts/%s.ttf', $layer['fontname'] );
408 496 }
409 497
410 498 if ( isset( $layer['fontfile'] ) ) {
411 499 $path = get_attached_file( $layer['fontfile'] );
@@ -420,61 +508,87 @@
420 508 return apply_filters( 'sharing_image_get_fontpath', $path, $layer );
421 509 }
422 510
423 511 /**
424 - * Generate upload file path and url.
512 + * Update layer position using boundary settings.
425 513 *
426 - * @return array Server file path and url to uploaded image.
514 + * @param array $layer List of layer options.
515 + * @param array $boundary List of previous layer boundaries.
516 + *
517 + * @return array List of layer settings.
427 518 */
428 - private function get_upload_file() {
429 - // Get uploads directory url and path array.
430 - list( $path, $url ) = $this->settings->get_upload_dir();
519 + private static function update_layer_position( $layer, $boundary ) {
520 + if ( empty( $layer['boundary'] ) || 'absolute' === $layer['boundary'] ) {
521 + return $layer;
522 + }
431 523
432 - // Create random file name with proper extension.
433 - $name = wp_unique_filename( $path, uniqid() . '.' . $this->settings->get_file_format() );
524 + // Check if boundary sizes exist.
525 + foreach ( array( 'x', 'y', 'width', 'height' ) as $size ) {
526 + if ( ! isset( $boundary[ $size ] ) ) {
527 + return $layer;
528 + }
529 + }
434 530
435 - $file = array(
436 - trailingslashit( $path ) . $name,
437 - trailingslashit( $url ) . $name,
438 - );
531 + $x = $layer['x'] + $boundary['width'] + $boundary['x'];
532 + $y = $layer['y'] + $boundary['height'] + $boundary['y'];
439 533
440 - /**
441 - * Filters upload file path and url
442 - *
443 - * @param array $file Server file path and url to image.
444 - * @param string $name Unique file name.
445 - */
446 - return apply_filters( 'sharing_image_get_upload_file', $file, $name );
534 + switch ( $layer['boundary'] ) {
535 + case 'horizontally':
536 + $layer['x'] = $x;
537 + break;
538 +
539 + case 'vertically':
540 + $layer['y'] = $y;
541 + break;
542 +
543 + default:
544 + $layer['x'] = $x;
545 + $layer['y'] = $y;
546 + }
547 +
548 + return $layer;
447 549 }
448 550
449 551 /**
450 - * Prepare args and remove not-allowed keys.
552 + * Update layer sizes for negative dimensions.
451 553 *
452 - * @param array $args List of source arguments.
453 - * @param array $allowed List of allowed keys.
554 + * @param array $layer List of layer options.
555 + * @param PosterEditor $poster Instance of PosterEditor class.
454 556 *
455 - * @return array List of prepared args.
557 + * @return array List of layer settings.
456 558 */
457 - private function prepare_args( $args, $allowed ) {
458 - return wp_array_slice_assoc( $args, $allowed );
559 + private static function update_layer_dimensions( $layer, $poster ) {
560 + if ( ! isset( $layer['width'] ) ) {
561 + $layer['width'] = 0;
562 + }
563 +
564 + if ( ! isset( $layer['height'] ) ) {
565 + $layer['height'] = 0;
566 + }
567 +
568 + $width = absint( $poster->width() );
569 +
570 + if ( $layer['width'] <= 0 ) {
571 + $layer['width'] = $width + $layer['width'] - $layer['x'];
572 + }
573 +
574 + $height = absint( $poster->height() );
575 +
576 + if ( $layer['height'] <= 0 ) {
577 + $layer['height'] = $height + $layer['height'] - $layer['y'];
578 + }
579 +
580 + return $layer;
459 581 }
460 582
461 583 /**
462 - * Check requred template values.
584 + * Prepare args and remove not-allowed keys.
463 585 *
464 - * @param array $template List of template settings.
586 + * @param array $args List of source arguments.
587 + * @param array $allowed List of allowed keys.
465 588 *
466 - * @return bool Whether all required values isset.
589 + * @return array List of prepared args.
467 590 */
468 - private function check_required( $template ) {
469 - $required = array( 'width', 'height', 'fill' );
470 -
471 - // Count intersected values.
472 - $prepared = count( $this->prepare_args( $template, $required ) );
473 -
474 - if ( count( $required ) === $prepared ) {
475 - return true;
476 - }
477 -
478 - return false;
591 + private static function prepare_args( $args, $allowed ) {
592 + return wp_array_slice_assoc( $args, $allowed );
479 593 }
480 594 }