LLMS_Generator

LLMS_Generator class.


Source Source

File: includes/class.llms.generator.php

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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
class LLMS_Generator {
 
    /**
     * Courses generator subclass instance
     *
     * @var LLMS_Generator_Courses
     */
    protected $courses_generator;
 
    /**
     * Instance of WP_Error
     *
     * @var obj
     */
    public $error;
 
    /**
     * Array of generated objects.
     *
     * @var array
     */
    protected $generated = array();
 
    /**
     * Name of the Generator to use for generation
     *
     * @var string
     */
    protected $generator = '';
 
    /**
     * Raw contents passed into the generator's constructor
     *
     * @var array
     */
    protected $raw = array();
 
    /**
     * Construct a new generator instance with data
     *
     * @since 3.3.0
     * @since 4.7.0 Move most logic into helper functions.
     * @since 6.0.0 Removed loading of class files that don't instantiate their class in favor of autoloading.
     *
     * @param array|string $raw Array or a JSON string of raw content.
     * @return void
     */
    public function __construct( $raw ) {
 
        // Load generator class.
        $this->courses_generator = new LLMS_Generator_Courses();
 
        // Parse raw data.
        $this->raw = $this->parse_raw( $raw );
 
        // Instantiate an empty error object.
        $this->error = new WP_Error();
 
        // Add hooks.
        $this->add_hooks();
 
    }
 
    /**
     * Add actions and filters used by the class.
     *
     * @since 4.7.0
     *
     * @return void
     */
    protected function add_hooks() {
 
        // Watch creation of things, used on generation completion to return results of created objects.
        foreach ( array( 'access_plan', 'course', 'section', 'lesson', 'quiz', 'question', 'term', 'user' ) as $type ) {
            add_action( 'llms_generator_new_' . $type, array( $this, 'object_created' ) );
        }
 
    }
 
    /**
     * When called, generates raw content based on the defined generator
     *
     * @since 3.3.0
     * @since 3.30.2 Add before and after generation hooks.
     * @since 4.7.0 Return early if not generator is set.
     *
     * @return void
     */
    public function generate() {
 
        if ( empty( $this->generator ) ) {
            return $this->error->add( 'missing-generator', __( 'No generator supplied.', 'lifterlms' ) );
        }
 
        global $wpdb;
 
        $wpdb->hide_errors();
 
        $wpdb->query( 'START TRANSACTION' ); // db call ok; no-cache ok.
 
        /**
         * Action run immediately prior to a LifterLMS Generator running.
         *
         * @since 3.30.2
         *
         * @param LLMS_Generator $generator The generator instance.
         */
        do_action( 'llms_generator_before_generate', $this );
 
        try {
            call_user_func( $this->generator, $this->raw );
        } catch ( Exception $exception ) {
            $this->error->add( $this->get_error_code( $exception->getCode(), $this->generator[0] ), $exception->getMessage(), $exception->getTrace() );
        }
 
        /**
         * Action run immediately after a LifterLMS Generator running.
         *
         * @since 3.30.2
         *
         * @param LLMS_Generator $generator The generator instance.
         */
        do_action( 'llms_generator_after_generate', $this );
 
        if ( $this->is_error() ) {
            $wpdb->query( 'ROLLBACK' ); // db call ok; no-cache ok.
        } else {
            $wpdb->query( 'COMMIT' ); // db call ok; no-cache ok.
        }
 
    }
 
    /**
     * Retrieve a human-readable error code from a machine-readable error number
     *
     * @since 4.7.0
     * @since 4.9.0 Handle PHP core errors, warnings, notices, etc... with a human-readable error code.
     *
     * @param int $code  Error number.
     * @param obj $class Generator class instance.
     * @return string A human-readable error code.
     */
    protected function get_error_code( $code, $class ) {
 
        // See if the error code is a native php exception code constant.
        $ret = llms_php_error_constant_to_code( $code );
 
        // Code is not a native PHP exception code.
        if ( is_numeric( $ret ) ) {
 
            $reflect   = new ReflectionClass( $class );
            $constants = array_flip( $reflect->getConstants() );
            $ret       = isset( $constants[ $code ] ) ? $constants[ $code ] : 'ERROR_UNKNOWN';
 
        }
 
        /**
         * Filter the human-readable error retrieved from a given error code
         *
         * @since 4.9.0
         *
         * @param string $ret   The human-readable error code.
         * @param int    $code  The initial error code as an integer.
         * @param obj    $class Generator class instance.
         */
        return apply_filters( 'llms_generator_get_error_code', $ret, $code, $class );
 
    }
 
    /**
     * Retrieves a multi-dimensional array of content generated by the most class
     *
     * @since 4.7.0
     *
     * @return array Returns an associative array where the keys are the object type and the values are an array of integers representing the generated object IDs.
     */
    public function get_generated_content() {
        return $this->generated;
    }
 
    /**
     * Retrieve the array of generated course ids
     *
     * @since 3.7.3
     * @since 3.14.8 Unknown.
     * @since 4.7.0 Access generated posts from the `$generated` property in favor of the removed `$posts` property.
     *
     * @return array
     */
    public function get_generated_courses() {
        if ( isset( $this->generated['course'] ) ) {
            return $this->generated['course'];
        }
        return array();
    }
 
    /**
     * Get an array of valid LifterLMS generators
     *
     * @since 3.3.0
     * @since 3.14.8 Unknown.
     * @since 4.7.0 Load generators from `LLMS_Generator_Courses()`.
     * @since 4.13.0 Use `clone_course()` method for cloning courses in favor of `genrate_course()`.
     *
     * @return array
     */
    protected function get_generators() {
 
        /**
         * Filter the list of available generators.
         *
         * @since Unknown
         *
         * @param array[] $generators Array of generators. Array key is the generator name and the array value is a callable function.
         */
        return apply_filters(
            'llms_generators',
            array(
                'LifterLMS/BulkCourseExporter'    => array( $this->courses_generator, 'generate_courses' ),
                'LifterLMS/BulkCourseGenerator'   => array( $this->courses_generator, 'generate_courses' ),
                'LifterLMS/SingleCourseCloner'    => array( $this->courses_generator, 'clone_course' ),
                'LifterLMS/SingleCourseExporter'  => array( $this->courses_generator, 'generate_course' ),
                'LifterLMS/SingleCourseGenerator' => array( $this->courses_generator, 'generate_course' ),
                'LifterLMS/SingleLessonCloner'    => array( $this->courses_generator, 'clone_lesson' ),
            )
        );
    }
 
    /**
     * Get the results of the generate function
     *
     * @since 3.3.0
     * @since 4.7.0 Return generated stats from `$this->stats()` instead of from removed `$stats` property.
     *
     * @return int[]|WP_Error Array of stats on success and an error object on failure.
     */
    public function get_results() {
 
        if ( $this->is_error() ) {
            return $this->error;
        }
 
        return $this->get_stats();
 
    }
 
    /**
     * Get "stats" about the generated content.
     *
     * @since 4.7.0
     *
     * @return array
     */
    public function get_stats() {
 
        $stats = array();
        foreach ( $this->generated as $type => $ids ) {
            $stats[ $type ] = count( $ids );
        }
 
        // Add old plural keys that were guaranteed to exist.
        $backwards_compat = array(
            'course'      => 'courses',
            'section'     => 'sections',
            'lesson'      => 'lessons',
            'access_plan' => 'plans',
            'quiz'        => 'quizzes',
            'question'    => 'questions',
            'term'        => 'terms',
            'user'        => 'authors',
        );
        foreach ( $backwards_compat as $curr => $old ) {
            $stats[ $old ] = isset( $stats[ $curr ] ) ? $stats[ $curr ] : 0;
        }
 
        return $stats;
 
    }
 
    /**
     * Determines if there was an error during the running of the generator
     *
     * @since 3.3.0
     * @since 3.16.11 Unknown.
     *
     * @return boolean Returns `true` when there was an error and `false` if there's no errors.
     */
    public function is_error() {
        return ( 0 !== count( $this->error->get_error_messages() ) );
    }
 
    /**
     * Determine if a generator is a valid generator.
     *
     * @since 3.36.3
     *
     * @param string $generator Generator name.
     * @return bool
     */
    protected function is_generator_valid( $generator ) {
 
        return in_array( $generator, array_keys( $this->get_generators() ), true );
 
    }
 
    /**
     * Record the generation of an object
     *
     * @since 4.7.0
     *
     * @param LLMS_Post_Model|array|WP_User $object Created object or array.
     * @return void
     */
    public function object_created( $object ) {
 
        switch ( current_action() ) {
 
            case 'llms_generator_new_access_plan':
            case 'llms_generator_new_course':
            case 'llms_generator_new_section':
            case 'llms_generator_new_lesson':
            case 'llms_generator_new_quiz':
            case 'llms_generator_new_question':
                $this->record_generation( $object->get( 'id' ), $object->get( 'type' ) );
                break;
 
            case 'llms_generator_new_user':
                $this->record_generation( $object, 'user' );
                break;
 
            case 'llms_generator_new_term':
                $this->record_generation( $object['term_id'], 'term' );
                break;
 
        }
 
    }
 
    /**
     * Parse raw data
     *
     * @since 4.7.0
     *
     * @param string|array|obj $raw Accepts a JSON string, array, or object of raw data to pass to a generator.
     * @return array
     */
    protected function parse_raw( $raw ) {
 
        if ( is_string( $raw ) ) {
            $raw = json_decode( $raw, true );
        }
 
        return (array) $raw;
 
    }
 
    /**
     * Records a generated post id
     *
     * @since 3.14.8
     * @since 4.7.0 Modified method access from `private` to `protected`.
     *               Add IDs to the `generated` variable in favor of `posts`.
     *
     * @param int    $id  WP Post ID of the generated post.
     * @param string $key Key of the stat to increment.
     * @return void
     */
    protected function record_generation( $id, $key ) {
 
        // Remove LifterLMS Prefix from the key (if it exists).
        $key = str_replace( 'llms_', '', $key );
 
        // Add an array if it doesn't already exist.
        if ( ! isset( $this->generated[ $key ] ) ) {
            $this->generated[ $key ] = array();
        }
 
        // Record the ID.
        $this->generated[ $key ][] = $id;
 
    }
 
    /**
     * Configure the default post status for generated posts at runtime
     *
     * @since 3.7.3
     * @since 4.7.0 Call `set_default_post_status()` from the configured generator.
     *
     * @param string $status Any valid WP Post Status.
     * @return void
     */
    public function set_default_post_status( $status ) {
        call_user_func( array( $this->generator[0], 'set_default_post_status' ), $status );
    }
 
    /**
     * Sets the generator to use for the current instance
     *
     * @since 3.3.0
     * @since 3.36.3 Fix error causing `null` to be returned instead of expected `WP_Error`.
     *               Return the generator name on success instead of void.
     *
     * @param string $generator Generator string, eg: "LifterLMS/SingleCourseExporter"
     * @return string|WP_Error Name of the generator on success, otherwise an error object.
     */
    public function set_generator( $generator = null ) {
 
        // Interpret the generator from the raw data.
        if ( empty( $generator ) ) {
 
            // No generator can be interpreted.
            if ( ! isset( $this->raw['_generator'] ) ) {
 
                $this->error->add( 'missing-generator', __( 'The supplied file cannot be processed by the importer.', 'lifterlms' ) );
                return $this->error;
 
            }
 
            // Set the generator using the interpreted data.
            return $this->set_generator( $this->raw['_generator'] );
 
        }
 
        // Invalid generator.
        if ( ! $this->is_generator_valid( $generator ) ) {
            $this->error->add( 'invalid-generator', __( 'The supplied generator is invalid.', 'lifterlms' ) );
            return $this->error;
        }
 
        // Set the generator.
        $generators      = $this->get_generators();
        $this->generator = $generators[ $generator ];
 
        // Return the generator name.
        return $generator;
 
    }
 
}

Top ↑

Methods Methods


Top ↑

Changelog Changelog

Changelog
Version Description
6.0.0 Removed deprecated items.
  • LLMS_Generator::add_custom_values() method
  • LLMS_Generator::format_date() method
  • LLMS_Generator::get_author_id_from_raw() method
  • LLMS_Generator::get_default_post_status() method
  • LLMS_Generator::get_generated_posts() method
  • LLMS_Generator::increment() method
3.36.3 New method: is_generator_valid() Bugfix: Fix return of set_generator().
3.30.2 Added hooks and made numerous private functions public to expand extendability.
3.3.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.