class-pdf-content.php
8.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
<?php
/**
* The main file for building PDF style and html content.
*
* @file
* @package Learndash_Certificate_Builer
*/
namespace LearnDash_Certificate_Builder\Component\Pdf;
use LearnDash_Certificate_Builder\Component\Builder\Pdf\Blocks\Fallback;
use LearnDash_Certificate_Builder\Component\Pdf\Builder\Html_Builder;
use LearnDash_Certificate_Builder\Component\Pdf\Builder\Style_Builder;
use Mpdf\Mpdf;
/**
* Class Pdf_Content
*
* @package LearnDash_Certificate_Builder\Component\Pdf
*/
class Pdf_Content {
/**
* The certificate POST ID
*
* @var int
*/
public $id;
/**
* The background image
*
* @var string
*/
public $background_image;
/**
* The font name
*
* @var string
*/
public $font;
/**
* If we use the custom font or core font
*
* @var bool
*/
public $use_font = false;
/**
* The margin in rem
*
* @var float
*/
public $spacing = 1;
/**
* The container height in pixel, we use this for re-calculate
*
* @var int
*/
public $page_height = 0;
/**
* The container width in pixel
*
* @var int
*/
public $page_width = 0;
/** The container width, in percent
*
* @var int
*/
public $container_width = 70;
/**
* PDF size
*
* @var string
*/
public $page_size = 'Letter';
/**
* PDF orientation
*
* @var string
*/
public $page_orientation = 'L';
/**
* The PDF page height
*
* @var Mpdf
*/
public $mpdf;
/**
* The styler builder
*
* @var Style_Builder
*/
public $style_builder;
/**
* The html styler
*
* @var Html_Builder
*/
public $html_builder;
/**
* The root block
*
* @var array
*/
private $root;
/**
* The course ID, when in view mode
*
* @var int
*/
public $course_id;
/**
* Contain the default colors
*
* @var array
*/
public $default_colors_palette = array();
/**
* Pdf_Content constructor.
*
* @param array $blocks The root block.
* @param Mpdf $mpdf The MPDF instance.
*/
public function __construct( $blocks, $mpdf ) {
$root = array_shift( $blocks );
$this->style_builder = new Style_Builder();
$this->html_builder = new Html_Builder();
$this->extract_info( $root );
$this->mpdf = $mpdf;
$this->mpdf->_setPageSize( $this->page_size, $this->page_orientation );
$root = $this->fix_block_position( $root );
unset( $root['attrs']['positions'] );
$this->root = $root;
$this->style_builder->add( 'body', 'background-image', 'url("' . $this->background_image . '")' );
$this->style_builder->add( 'body', 'background-position', 'top left' );
$this->style_builder->add( 'body', 'background-repeat', 'no-repeat' );
$this->style_builder->add( 'body', 'background-image-resize', '6' );
$this->style_builder->add( 'body', 'background-image-resolution', 'from-image' );
$this->style_builder->add( 'body', 'font-size', '18px' );
$this->style_builder->add( 'body', 'line-height', '1' );
if ( $this->use_font ) {
$this->style_builder->add( 'body', 'font-family', "'{$this->font}'" );
} else {
$this->style_builder->add( 'body', 'font-family', "'freeserif'" );
}
if ( isset( $root['attrs']['rtl'] ) && true === $root['attrs']['rtl'] ) {
$this->mpdf->SetDirectionality( 'rtl' );
}
// init the style for the wrapper too.
$this->style_builder->add( 'wrap', 'width', $this->container_width . '%' );
$this->style_builder->add( 'wrap', 'margin', '0px auto' );
$this->style_builder->add( 'wrap', 'position', 'relative' );
$this->style_builder->add( '.cb-block', 'margin-bottom', $this->spacing . 'rem' );
$this->style_builder->add( '.learndash-block-inner', 'margin-bottom', $this->spacing . 'rem' );
}
/**
* Init the colors class
*/
public function init_colors() {
global $_wp_theme_features;
$color_palette = array();
// now we add the defined colors from theme.
if ( isset( $_wp_theme_features['editor-color-palette'] ) && is_array( $_wp_theme_features['editor-color-palette'] ) ) {
$color_palette = $_wp_theme_features['editor-color-palette'];
}
$color_palette = array_merge( $color_palette, array( $this->default_colors_palette ) );
foreach ( $color_palette as $palette ) {
foreach ( $palette as $color ) {
$this->style_builder->add( '.has-' . $color['slug'] . '-color', 'color', $color['color'] );
$this->style_builder->add( '.has-' . $color['slug'] . '-background-color', 'background-color', $color['color'] );
foreach ( $palette as $c ) {
if ( $c['slug'] === $color['slug'] ) {
continue;
}
$this->style_builder->add(
'.has-' . $color['slug'] . '-to-' . $c['slug'] . '-gradient-background',
'background',
'linear-gradient(-160deg, ' . $color['color'] . ', ' . $c['color'] . ')'
);
}
}
}
}
/**
* Convert the block into HTML ready
*
* @param Style_Builder $style_builder The style builder class.
* @param Html_Builder $html_builder The html builder class.
* @param array $root The root block.
*/
public function build_html_structure( $style_builder = null, $html_builder = null, $root = null ) {
$is_nested = false;
if ( is_null( $root ) ) {
$root = $this->root;
} else {
// this is rendering inside a columns.
$is_nested = true;
}
if ( is_null( $style_builder ) ) {
$style_builder = $this->style_builder;
}
if ( is_null( $html_builder ) ) {
$html_builder = $this->html_builder;
}
foreach ( $root['innerBlocks'] as $key => &$block ) {
// we will call the class with the block name.
$class_name = str_replace( '/', '_', ucwords( $block['blockName'], '/' ) );
$class_name = str_replace( '-', '_', ucwords( $class_name, '-' ) );
$namespace = 'LearnDash_Certificate_Builder\\Component\\Builder\\Pdf\Blocks\\';
$class_name = $namespace . $class_name;
if ( ! class_exists( $class_name ) ) {
// fallback to render.
$class = new Fallback( $block, $style_builder, $html_builder, $this );
$class->run();
continue;
}
$class = new $class_name( $block, $style_builder, $html_builder, $this );
if ( $is_nested && ( count( $root['innerBlocks'] ) - 1 ) === $key && 'core/columns' !== $block['blockName'] ) {
$class->style->add( $block['id'], 'margin-bottom', '0' );
}
$class->is_nested = $is_nested;
$class->run();
do_action( 'learndash_certificate_builder_after_block_processed', $class, $key );
}
}
/**
* Extract and filter the block attributes.
*
* @param array $parent The root block.
*/
protected function extract_info( $parent ) {
$attrs = $parent['attrs'];
$attrs = shortcode_atts(
array(
'id' => 0,
'backgroundImage' => '',
'font' => '',
'useFont' => false,
'pageSize' => 'Letter',
'pageOrientation' => 'L',
'pageHeight' => 0,
'pageWidth' => 0,
'containerWidth' => 70,
'spacing' => 1,
'positions' => array(),
),
$attrs
);
$this->id = absint( $attrs['id'] );
// image should be local.
$this->background_image = wp_get_attachment_image_url( $this->id, 'full' );
if ( false === $this->background_image ) {
// false back to URL.
$this->background_image = $attrs['backgroundImage'];
if ( empty( $this->background_image ) ) {
wp_die( esc_html__( 'A background image is required.', 'learndash-certificate-builder' ) );
}
}
$this->font = esc_html( $attrs['font'] );
$this->use_font = filter_var( $attrs['useFont'], FILTER_VALIDATE_BOOLEAN );
$this->page_size = $attrs['pageSize'];
if ( ! in_array( $this->page_size, array( 'Letter', 'A4' ), true ) ) {
$this->page_size = 'Letter';
}
$this->page_orientation = $attrs['pageOrientation'];
if ( ! in_array( $this->page_orientation, array( 'L', 'P' ), true ) ) {
$this->page_orientation = 'L';
}
$this->page_height = absint( $attrs['pageHeight'] );
$this->page_width = absint( $attrs['pageWidth'] );
$this->container_width = absint( $attrs['containerWidth'] );
$this->spacing = floatval( $attrs['spacing'] );
}
/**
* This will merge the positions into the block
*
* @param array $root The block.
*
* @return array
*/
protected function fix_block_position( $root ) {
foreach ( $root['innerBlocks'] as $key => &$block ) {
// randomly id.
$el_id = uniqid( 'block_' );
$block['id'] = $el_id;
if ( isset( $block['innerBlocks'] ) && count( $block['innerBlocks'] ) ) {
// this should be always have positions, it is a must.
$block = $this->fix_block_position( $block );
}
}
return $root;
}
}