Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
1441 ariadna 17
namespace core_cache;
1 efrain 18
 
1441 ariadna 19
use core\exception\coding_exception;
20
use cache_config_testing;
21
use cache_phpunit_factory;
1 efrain 22
 
23
/**
24
 * The cache factory class.
25
 *
26
 * This factory class is important because it stores instances of objects used by the cache API and returns them upon requests.
27
 * This allows us to both reuse objects saving on overhead, and gives us an easy place to "reset" the cache API in situations that
28
 * we need such as unit testing.
29
 *
30
 * @copyright  2012 Sam Hemelryk
31
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1441 ariadna 32
 * @package core_cache
1 efrain 33
 */
1441 ariadna 34
class factory {
1 efrain 35
    /** The cache has not been initialised yet. */
36
    const STATE_UNINITIALISED = 0;
37
    /** The cache is in the process of initialising itself. */
38
    const STATE_INITIALISING = 1;
39
    /** The cache is in the process of saving its configuration file. */
40
    const STATE_SAVING = 2;
41
    /** The cache is ready to use. */
42
    const STATE_READY = 3;
43
    /** The cache is currently updating itself */
44
    const STATE_UPDATING = 4;
45
    /** The cache encountered an error while initialising. */
46
    const STATE_ERROR_INITIALISING = 9;
47
    /** The cache has been disabled. */
48
    const STATE_DISABLED = 10;
49
    /** The cache stores have been disabled */
50
    const STATE_STORES_DISABLED = 11;
51
 
52
    /**
1441 ariadna 53
     * An instance of the factory class created upon the first request.
54
     * @var factory
1 efrain 55
     */
56
    protected static $instance;
57
 
58
    /**
59
     * An array containing caches created for definitions
60
     * @var array
61
     */
1441 ariadna 62
    protected $cachesfromdefinitions = [];
1 efrain 63
 
64
    /**
65
     * Array of caches created by parameters, ad-hoc definitions will have been used.
66
     * @var array
67
     */
1441 ariadna 68
    protected $cachesfromparams = [];
1 efrain 69
 
70
    /**
71
     * An array of stores organised by definitions.
72
     * @var array
73
     */
1441 ariadna 74
    protected $definitionstores = [];
1 efrain 75
 
76
    /**
77
     * An array of instantiated stores.
78
     * @var array
79
     */
1441 ariadna 80
    protected $stores = [];
1 efrain 81
 
82
    /**
83
     * An array of configuration instances
84
     * @var array
85
     */
1441 ariadna 86
    protected $configs = [];
1 efrain 87
 
88
    /**
89
     * An array of initialised definitions
90
     * @var array
91
     */
1441 ariadna 92
    protected $definitions = [];
1 efrain 93
 
94
    /**
95
     * An array of lock plugins.
96
     * @var array
97
     */
1441 ariadna 98
    protected $lockplugins = [];
1 efrain 99
 
100
    /**
101
     * The current state of the cache API.
102
     * @var int
103
     */
104
    protected $state = 0;
105
 
106
    /**
107
     * The current cache display helper.
108
     * @var core_cache\local\administration_display_helper
109
     */
110
    protected static $displayhelper = null;
111
 
112
    /**
1441 ariadna 113
     * Returns an instance of the factory class.
1 efrain 114
     *
1441 ariadna 115
     * @param bool $forcereload If set to true a new factory instance will be created and used.
116
     * @return factory
1 efrain 117
     */
118
    public static function instance($forcereload = false) {
119
        global $CFG;
120
        if ($forcereload || self::$instance === null) {
121
            // Initialise a new factory to facilitate our needs.
122
            if (defined('CACHE_DISABLE_ALL') && CACHE_DISABLE_ALL !== false) {
123
                // The cache has been disabled. Load disabledlib and start using the factory designed to handle this
124
                // situation. It will use disabled alternatives where available.
1441 ariadna 125
                self::$instance = new disabled_factory();
1 efrain 126
            } else if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING')) {
127
                // We're using the test factory.
1441 ariadna 128
                require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
1 efrain 129
                self::$instance = new cache_phpunit_factory();
130
                if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) {
131
                    // The cache stores have been disabled.
132
                    self::$instance->set_state(self::STATE_STORES_DISABLED);
133
                }
134
            } else if (!empty($CFG->alternative_cache_factory_class)) {
135
                $factoryclass = $CFG->alternative_cache_factory_class;
136
                self::$instance = new $factoryclass();
137
            } else {
138
                // We're using the regular factory.
1441 ariadna 139
                self::$instance = new factory();
1 efrain 140
                if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) {
141
                    // The cache stores have been disabled.
142
                    self::$instance->set_state(self::STATE_STORES_DISABLED);
143
                }
144
            }
145
        }
146
        return self::$instance;
147
    }
148
 
149
    /**
150
     * Protected constructor, please use the static instance method.
151
     */
152
    protected function __construct() {
153
        // Nothing to do here.
154
    }
155
 
156
    /**
157
     * Resets the arrays containing instantiated caches, stores, and config instances.
158
     */
159
    public static function reset() {
160
        $factory = self::instance();
161
        $factory->reset_cache_instances();
1441 ariadna 162
        $factory->configs = [];
163
        $factory->definitions = [];
164
        $factory->definitionstores = [];
165
        $factory->lockplugins = []; // MUST be null in order to force its regeneration.
1 efrain 166
        // Reset the state to uninitialised.
167
        $factory->state = self::STATE_UNINITIALISED;
168
    }
169
 
170
    /**
171
     * Resets the stores, clearing the array of created stores.
172
     *
173
     * Cache objects still held onto by the code that initialised them will remain as is
174
     * however all future requests for a cache/store will lead to a new instance being re-initialised.
175
     */
176
    public function reset_cache_instances() {
1441 ariadna 177
        $this->cachesfromdefinitions = [];
178
        $this->cachesfromparams = [];
179
        $this->stores = [];
1 efrain 180
    }
181
 
182
    /**
183
     * Creates a cache object given the parameters for a definition.
184
     *
185
     * If a cache has already been created for the given definition then that cache instance will be returned.
186
     *
187
     * @param string $component
188
     * @param string $area
189
     * @param array $identifiers
190
     * @param string $unused Used to be data source aggregate however that was removed and this is now unused.
1441 ariadna 191
     * @return application_cache|session_cache|request_cache
1 efrain 192
     */
1441 ariadna 193
    public function create_cache_from_definition($component, $area, array $identifiers = [], $unused = null) {
194
        $identifierstring = empty($identifiers) ? '' : '/' . http_build_query($identifiers);
195
        $definitionname = $component . '/' . $area . $identifierstring;
1 efrain 196
        if (isset($this->cachesfromdefinitions[$definitionname])) {
197
            $cache = $this->cachesfromdefinitions[$definitionname];
198
            return $cache;
199
        }
200
        $definition = $this->create_definition($component, $area);
201
        // Identifiers are cached as part of the cache creation, so we store a cloned version of the cache.
202
        $cacheddefinition = clone($definition);
203
        $cacheddefinition->set_identifiers($identifiers);
204
        $cache = $this->create_cache($cacheddefinition);
205
 
206
        // Loaders are always held onto to speed up subsequent requests.
207
        $this->cachesfromdefinitions[$definitionname] = $cache;
208
        return $cache;
209
    }
210
 
211
    /**
212
     * Creates an ad-hoc cache from the given param.
213
     *
214
     * If a cache has already been created using the same params then that cache instance will be returned.
215
     *
216
     * @param int $mode
217
     * @param string $component
218
     * @param string $area
219
     * @param array $identifiers
220
     * @param array $options An array of options, available options are:
221
     *   - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
222
     *   - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
223
     *   - staticacceleration : If set to true the cache will hold onto data passing through it.
224
     *   - staticaccelerationsize : The maximum number of items to hold onto for acceleration purposes.
1441 ariadna 225
     * @return application_cache|session_cache|request_cache
1 efrain 226
     */
1441 ariadna 227
    public function create_cache_from_params($mode, $component, $area, array $identifiers = [], array $options = []) {
228
        $identifierstring = empty($identifiers) ? '' : '_' . http_build_query($identifiers);
1 efrain 229
        $key = "{$mode}_{$component}_{$area}{$identifierstring}";
230
        if (isset($this->cachesfromparams[$key])) {
231
            return $this->cachesfromparams[$key];
232
        }
233
        // Regular cache definitions are cached inside create_definition().  This is not the case for Adhoc definitions
234
        // using load_adhoc().  They are built as a new object on each call.
235
        // We do not need to clone the definition because we know it's new.
1441 ariadna 236
        $definition = definition::load_adhoc($mode, $component, $area, $options);
1 efrain 237
        $definition->set_identifiers($identifiers);
238
        $cache = $this->create_cache($definition);
239
        $this->cachesfromparams[$key] = $cache;
240
        return $cache;
241
    }
242
 
243
    /**
244
     * Common public method to create a cache instance given a definition.
245
     *
246
     * This is used by the static make methods.
247
     *
1441 ariadna 248
     * @param definition $definition
249
     * @return application_cache|session_cache|store
1 efrain 250
     * @throws coding_exception
251
     */
1441 ariadna 252
    public function create_cache(definition $definition) {
1 efrain 253
        $class = $definition->get_cache_class();
1441 ariadna 254
        $stores = helper::get_stores_suitable_for_definition($definition);
1 efrain 255
        foreach ($stores as $key => $store) {
256
            if (!$store::are_requirements_met()) {
257
                unset($stores[$key]);
258
            }
259
        }
260
        if (count($stores) === 0) {
261
            // Hmm still no stores, better provide a dummy store to mimic functionality. The dev will be none the wiser.
262
            $stores[] = $this->create_dummy_store($definition);
263
        }
264
        $loader = null;
265
        if ($definition->has_data_source()) {
266
            $loader = $definition->get_data_source();
267
        }
268
        while (($store = array_pop($stores)) !== null) {
269
            $loader = new $class($definition, $store, $loader);
270
        }
271
        return $loader;
272
    }
273
 
274
    /**
275
     * Creates a store instance given its name and configuration.
276
     *
277
     * If the store has already been instantiated then the original object will be returned. (reused)
278
     *
279
     * @param string $name The name of the store (must be unique remember)
280
     * @param array $details
1441 ariadna 281
     * @param definition $definition The definition to instantiate it for.
282
     * @return boolean|store
1 efrain 283
     */
1441 ariadna 284
    public function create_store_from_config($name, array $details, definition $definition) {
1 efrain 285
        if (!array_key_exists($name, $this->stores)) {
286
            // Properties: name, plugin, configuration, class.
287
            $class = $details['class'];
288
            if (!$class::are_requirements_met()) {
289
                return false;
290
            }
291
            $store = new $class($details['name'], $details['configuration']);
292
            $this->stores[$name] = $store;
293
        }
1441 ariadna 294
        /* @var store $store */
1 efrain 295
        $store = $this->stores[$name];
296
        // We check are_requirements_met although we expect is_ready is going to check as well.
297
        if (!$store::are_requirements_met() || !$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) {
298
            return false;
299
        }
300
        // We always create a clone of the original store.
301
        // If we were to clone a store that had already been initialised with a definition then
302
        // we'd run into a myriad of issues.
303
        // We use a method of the store to create a clone rather than just creating it ourselves
304
        // so that if any store out there doesn't handle cloning they can override this method in
305
        // order to address the issues.
306
        $store = $this->stores[$name]->create_clone($details);
307
        $store->initialise($definition);
308
        $definitionid = $definition->get_id();
309
        if (!isset($this->definitionstores[$definitionid])) {
1441 ariadna 310
            $this->definitionstores[$definitionid] = [];
1 efrain 311
        }
312
        $this->definitionstores[$definitionid][] = $store;
313
        return $store;
314
    }
315
 
316
    /**
317
     * Returns an array of cache stores that have been initialised for use in definitions.
1441 ariadna 318
     * @param definition $definition
1 efrain 319
     * @return array
320
     */
1441 ariadna 321
    public function get_store_instances_in_use(definition $definition) {
1 efrain 322
        $id = $definition->get_id();
323
        if (!isset($this->definitionstores[$id])) {
1441 ariadna 324
            return [];
1 efrain 325
        }
326
        return $this->definitionstores[$id];
327
    }
328
 
329
    /**
330
     * Returns the cache instances that have been used within this request.
331
     * @since Moodle 2.6
332
     * @return array
333
     */
334
    public function get_caches_in_use() {
335
        return $this->cachesfromdefinitions;
336
    }
337
 
338
    /**
339
     * Gets all adhoc caches that have been used within this request.
340
     *
1441 ariadna 341
     * @return store[] Caches currently in use
1 efrain 342
     */
343
    public function get_adhoc_caches_in_use() {
344
        return $this->cachesfromparams;
345
    }
346
 
347
    /**
348
     * Creates a cache config instance with the ability to write if required.
349
     *
350
     * @param bool $writer If set to true an instance that can update the configuration will be returned.
1441 ariadna 351
     * @return config|config_writer
1 efrain 352
     */
353
    public function create_config_instance($writer = false) {
354
        global $CFG;
355
 
356
        // The class to use.
1441 ariadna 357
        $class = config::class;
1 efrain 358
        // Are we running tests of some form?
359
        $testing = (defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING');
360
 
361
        // Check if this is a PHPUnit test and redirect to the phpunit config classes if it is.
362
        if ($testing) {
1441 ariadna 363
            require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
1 efrain 364
            // We have just a single class for PHP unit tests. We don't care enough about its
365
            // performance to do otherwise and having a single method allows us to inject things into it
366
            // while testing.
1441 ariadna 367
            $class = cache_config_testing::class;
1 efrain 368
        }
369
 
370
        // Check if we need to create a config file with defaults.
371
        $needtocreate = !$class::config_file_exists();
372
 
373
        if ($writer || $needtocreate) {
374
            if (!$testing) {
375
                $class .= '_writer';
376
            }
377
        }
378
 
379
        $error = false;
380
        if ($needtocreate) {
381
            // Create the default configuration.
382
            // Update the state, we are now initialising the cache.
383
            self::set_state(self::STATE_INITIALISING);
1441 ariadna 384
            /** @var config_writer $class */
1 efrain 385
            $configuration = $class::create_default_configuration();
386
            if ($configuration !== true) {
387
                // Failed to create the default configuration. Disable the cache stores and update the state.
388
                self::set_state(self::STATE_ERROR_INITIALISING);
1441 ariadna 389
                $this->configs[$class] = new $class();
1 efrain 390
                $this->configs[$class]->load($configuration);
391
                $error = true;
392
            }
393
        }
394
 
395
        if (!array_key_exists($class, $this->configs)) {
396
            // Create a new instance and call it to load it.
1441 ariadna 397
            $this->configs[$class] = new $class();
1 efrain 398
            $this->configs[$class]->load();
399
        }
400
 
401
        if (!$error) {
402
            // The cache is now ready to use. Update the state.
403
            self::set_state(self::STATE_READY);
404
        }
405
 
406
        // Return the instance.
407
        return $this->configs[$class];
408
    }
409
 
410
    /**
411
     * Creates a definition instance or returns the existing one if it has already been created.
412
     * @param string $component
413
     * @param string $area
414
     * @param string $unused This used to be data source aggregate - however that functionality has been removed and
415
     *        this argument is now unused.
1441 ariadna 416
     * @return definition
1 efrain 417
     * @throws coding_exception If the definition cannot be found.
418
     */
419
    public function create_definition($component, $area, $unused = null) {
1441 ariadna 420
        $id = $component . '/' . $area;
1 efrain 421
        if (!isset($this->definitions[$id])) {
422
            // This is the first time this definition has been requested.
423
            if ($this->is_initialising()) {
424
                // We're initialising the cache right now. Don't try to create another config instance.
425
                // We'll just use an ad-hoc cache for the time being.
1441 ariadna 426
                $definition = definition::load_adhoc(store::MODE_REQUEST, $component, $area);
1 efrain 427
            } else {
428
                // Load all the known definitions and find the desired one.
429
                $instance = $this->create_config_instance();
430
                $definition = $instance->get_definition_by_id($id);
431
                if (!$definition) {
432
                    // Oh-oh the definition doesn't exist.
433
                    // There are several things that could be going on here.
434
                    // We may be installing/upgrading a site and have hit a definition that hasn't been used before.
435
                    // Of the developer may be trying to use a newly created definition.
436
                    if ($this->is_updating()) {
437
                        // The cache is presently initialising and the requested cache definition has not been found.
438
                        // This means that the cache initialisation has requested something from a cache (I had recursive nightmares about this).
439
                        // To serve this purpose and avoid errors we are going to make use of an ad-hoc cache rather than
440
                        // search for the definition which would possibly cause an infitite loop trying to initialise the cache.
1441 ariadna 441
                        $definition = definition::load_adhoc(store::MODE_REQUEST, $component, $area);
1 efrain 442
                    } else {
443
                        // Either a typo of the developer has just created the definition and is using it for the first time.
444
                        $this->reset();
445
                        $instance = $this->create_config_instance(true);
446
                        $instance->update_definitions();
447
                        $definition = $instance->get_definition_by_id($id);
448
                        if (!$definition) {
1441 ariadna 449
                            throw new coding_exception('The requested cache definition does not exist.' . $id, $id);
1 efrain 450
                        }
451
                        if (!$this->is_disabled()) {
452
                            debugging('Cache definitions reparsed causing cache reset in order to locate definition.
453
                                You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER);
454
                        }
1441 ariadna 455
                        $definition = definition::load($id, $definition);
1 efrain 456
                    }
457
                } else {
1441 ariadna 458
                    $definition = definition::load($id, $definition);
1 efrain 459
                }
460
            }
461
            $this->definitions[$id] = $definition;
462
        }
463
        return $this->definitions[$id];
464
    }
465
 
466
    /**
467
     * Creates a dummy store object for use when a loader has no potential stores to use.
468
     *
1441 ariadna 469
     * @param definition $definition
470
     * @return dummy_cachestore
1 efrain 471
     */
1441 ariadna 472
    protected function create_dummy_store(definition $definition) {
473
        $store = new dummy_cachestore();
1 efrain 474
        $store->initialise($definition);
475
        return $store;
476
    }
477
 
478
    /**
479
     * Returns a lock instance ready for use.
480
     *
481
     * @param array $config
1441 ariadna 482
     * @return lockable_cache_interface
1 efrain 483
     */
484
    public function create_lock_instance(array $config) {
485
        global $CFG;
486
        if (!array_key_exists('name', $config) || !array_key_exists('type', $config)) {
487
            throw new coding_exception('Invalid cache lock instance provided');
488
        }
489
        $name = $config['name'];
490
        $type = $config['type'];
491
        unset($config['name']);
492
        unset($config['type']);
493
 
494
        if (!isset($this->lockplugins[$type])) {
495
            $pluginname = substr($type, 10);
1441 ariadna 496
            $file = $CFG->dirroot . "/cache/locks/{$pluginname}/lib.php";
1 efrain 497
            if (file_exists($file) && is_readable($file)) {
498
                require_once($file);
499
            }
500
            if (!class_exists($type)) {
501
                throw new coding_exception('Invalid lock plugin requested.');
502
            }
503
            $this->lockplugins[$type] = $type;
504
        }
505
        if (!array_key_exists($type, $this->lockplugins)) {
506
            throw new coding_exception('Invalid cache lock type.');
507
        }
508
        $class = $this->lockplugins[$type];
509
        return new $class($name, $config);
510
    }
511
 
512
    /**
513
     * Returns the current state of the cache API.
514
     *
515
     * @return int
516
     */
517
    public function get_state() {
518
        return $this->state;
519
    }
520
 
521
    /**
522
     * Updates the state fo the cache API.
523
     *
524
     * @param int $state
525
     * @return bool
526
     */
527
    public function set_state($state) {
528
        if ($state <= $this->state) {
529
            return false;
530
        }
531
        $this->state = $state;
532
        return true;
533
    }
534
 
535
    /**
536
     * Informs the factory that the cache is currently updating itself.
537
     *
538
     * This forces the state to upgrading and can only be called once the cache is ready to use.
539
     * Calling it ensure we don't try to reinstantite things when requesting cache definitions that don't exist yet.
540
     */
541
    public function updating_started() {
542
        if ($this->state !== self::STATE_READY) {
543
            return false;
544
        }
545
        $this->state = self::STATE_UPDATING;
546
        return true;
547
    }
548
 
549
    /**
550
     * Informs the factory that the upgrading has finished.
551
     *
552
     * This forces the state back to ready.
553
     */
554
    public function updating_finished() {
555
        $this->state = self::STATE_READY;
556
    }
557
 
558
    /**
559
     * Returns true if the cache API has been disabled.
560
     *
561
     * @return bool
562
     */
563
    public function is_disabled() {
564
        return $this->state === self::STATE_DISABLED;
565
    }
566
 
567
    /**
568
     * Returns true if the cache is currently initialising itself.
569
     *
570
     * This includes both initialisation and saving the cache config file as part of that initialisation.
571
     *
572
     * @return bool
573
     */
574
    public function is_initialising() {
575
        return $this->state === self::STATE_INITIALISING || $this->state === self::STATE_SAVING;
576
    }
577
 
578
    /**
579
     * Returns true if the cache is currently updating itself.
580
     *
581
     * @return bool
582
     */
583
    public function is_updating() {
584
        return $this->state === self::STATE_UPDATING;
585
    }
586
 
587
    /**
588
     * Disables as much of the cache API as possible.
589
     *
590
     * All of the magic associated with the disabled cache is wrapped into this function.
591
     * In switching out the factory for the disabled factory it gains full control over the initialisation of objects
592
     * and can use all of the disabled alternatives.
593
     * Simple!
594
     *
595
     * This function has been marked as protected so that it cannot be abused through the public API presently.
596
     * Perhaps in the future we will allow this, however as per the build up to the first release containing
597
     * MUC it was decided that this was just to risky and abusable.
598
     */
599
    protected static function disable() {
1441 ariadna 600
        self::$instance = new disabled_factory();
1 efrain 601
    }
602
 
603
    /**
604
     * Returns true if the cache stores have been disabled.
605
     *
606
     * @return bool
607
     */
608
    public function stores_disabled() {
609
        return $this->state === self::STATE_STORES_DISABLED || $this->is_disabled();
610
    }
611
 
612
    /**
613
     * Disables cache stores.
614
     *
615
     * The cache API will continue to function however none of the actual stores will be used.
616
     * Instead the dummy store will be provided for all cache requests.
617
     * This is useful in situations where you cannot be sure any stores are working.
618
     *
619
     * In order to re-enable the cache you must call the cache factories static reset method:
620
     * <code>
621
     * // Disable the cache factory.
1441 ariadna 622
     * factory::disable_stores();
1 efrain 623
     * // Re-enable the cache factory by resetting it.
1441 ariadna 624
     * factory::reset();
1 efrain 625
     * </code>
626
     */
627
    public static function disable_stores() {
628
        // First reset to clear any static acceleration array.
629
        $factory = self::instance();
630
        $factory->reset_cache_instances();
631
        $factory->set_state(self::STATE_STORES_DISABLED);
632
    }
633
 
634
    /**
635
     * Returns an instance of the current display_helper.
636
     *
1441 ariadna 637
     * @return administration_helper
1 efrain 638
     */
1441 ariadna 639
    public static function get_administration_display_helper(): administration_helper {
1 efrain 640
        if (is_null(self::$displayhelper)) {
641
            self::$displayhelper = new \core_cache\local\administration_display_helper();
642
        }
643
        return self::$displayhelper;
644
    }
645
 
646
    /**
1441 ariadna 647
     * Gets the config_writer to use when caching is disabled.
648
     * This should only be called from disabled_factory.
1 efrain 649
     *
1441 ariadna 650
     * @return config_writer
1 efrain 651
     */
1441 ariadna 652
    public static function get_disabled_writer(): config_writer {
1 efrain 653
        global $CFG;
654
 
655
        // Figure out if we are in a recursive loop using late static binding.
656
        // This happens when get_disabled_writer is not overridden. We just want the default.
657
        $loop = false;
658
        if (!empty($CFG->alternative_cache_factory_class)) {
659
            $loop = get_called_class() === $CFG->alternative_cache_factory_class;
660
        }
661
 
662
        if (!$loop && !empty($CFG->alternative_cache_factory_class)) {
663
            // Get the class to use from the alternative factory.
664
            $factoryinstance = new $CFG->alternative_cache_factory_class();
665
            return $factoryinstance::get_disabled_writer();
666
        } else {
1441 ariadna 667
            // We got here from disabled_factory.
1 efrain 668
            // We should use the default writer here.
669
            // Make sure we have a default config if needed.
1441 ariadna 670
            if (!config::config_file_exists()) {
671
                config_writer::create_default_configuration(true);
1 efrain 672
            }
673
 
1441 ariadna 674
            return new config_writer();
1 efrain 675
        }
676
    }
677
}
1441 ariadna 678
 
679
// Alias this class to the old name.
680
// This file will be autoloaded by the legacyclasses autoload system.
681
// In future all uses of this class will be corrected and the legacy references will be removed.
682
class_alias(factory::class, \cache_factory::class);