Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ComponentFactory.php « Plugin « core - github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d79a2f2959e89edad931f862aecb14d3d122c209 (plain)
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
<?php
/**
 * Matomo - free/libre analytics platform
 *
 * @link https://matomo.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */
namespace Piwik\Plugin;

use Piwik\Log;
use Piwik\Plugin\Manager as PluginManager;
use Exception;

/**
 * Factory class with methods to find and instantiate Plugin components.
 */
class ComponentFactory
{
    /**
     * Create a component instance that exists within a specific plugin. Uses the component's
     * unqualified class name and expected base type.
     *
     * This method will only create a class if it is located within the component type's
     * associated subdirectory.
     *
     * @param string $pluginName The name of the plugin the component is expected to belong to,
     *                           eg, `'DevicesDetection'`.
     * @param string $componentClassSimpleName The component's class name w/o namespace, eg,
     *                                         `"GetKeywords"`.
     * @param string $componentTypeClass The fully qualified class name of the component type, eg,
     *                                   `"Piwik\Plugin\Report"`.
     * @return mixed|null A new instance of the desired component or null if not found. If the
     *                    plugin is not loaded or activated or the component is not located in
     *                    in the sub-namespace specified by `$componentTypeClass::COMPONENT_SUBNAMESPACE`,
     *                    this method will return null.
     */
    public static function factory($pluginName, $componentClassSimpleName, $componentTypeClass)
    {
        if (empty($pluginName) || empty($componentClassSimpleName)) {
            Log::debug("ComponentFactory::%s: empty plugin name or component simple name requested (%s, %s)",
                __FUNCTION__, $pluginName, $componentClassSimpleName);

            return null;
        }

        $plugin = self::getActivatedPlugin(__FUNCTION__, $pluginName);
        if (empty($plugin)) {
            return null;
        }

        $subnamespace = $componentTypeClass::COMPONENT_SUBNAMESPACE;
        $desiredComponentClass = 'Piwik\\Plugins\\' . $pluginName . '\\' . $subnamespace . '\\' . $componentClassSimpleName;

        $components = $plugin->findMultipleComponents($subnamespace, $componentTypeClass);
        foreach ($components as $class) {
            if ($class === $desiredComponentClass) {
                return new $class();
            }
        }

        Log::debug("ComponentFactory::%s: Could not find requested component (args = ['%s', '%s', '%s']).",
            __FUNCTION__, $pluginName, $componentClassSimpleName, $componentTypeClass);

        return null;
    }

    /**
     * Finds a component instance that satisfies a given predicate.
     *
     * @param string $componentTypeClass The fully qualified class name of the component type, eg,
     *                                   `"Piwik\Plugin\Report"`.
     * @param string $pluginName|false The name of the plugin the component is expected to belong to,
     *                                 eg, `'DevicesDetection'`.
     * @param callback $predicate
     * @return mixed The component that satisfies $predicate or null if not found.
     */
    public static function getComponentIf($componentTypeClass, $pluginName, $predicate)
    {
        $pluginManager = PluginManager::getInstance();

        // get components to search through
        $subnamespace = $componentTypeClass::COMPONENT_SUBNAMESPACE;
        if (empty($pluginName)) {
            $components = $pluginManager->findMultipleComponents($subnamespace, $componentTypeClass);
        } else {
            $plugin = self::getActivatedPlugin(__FUNCTION__, $pluginName);
            if (empty($plugin)) {
                return null;
            }

            $components = $plugin->findMultipleComponents($subnamespace, $componentTypeClass);
        }

        // find component that satisfieds predicate
        foreach ($components as $class) {
            $component = new $class();
            if ($predicate($component)) {
                return $component;
            }
        }

        Log::debug("ComponentFactory::%s: Could not find component that satisfies predicate (args = ['%s', '%s', '%s']).",
            __FUNCTION__, $componentTypeClass, $pluginName, get_class($predicate));

        return null;
    }

    /**
     * @param string $function
     * @param string $pluginName
     * @return null|\Piwik\Plugin
     */
    private static function getActivatedPlugin($function, $pluginName)
    {
        $pluginManager = PluginManager::getInstance();
        try {
            if (!$pluginManager->isPluginActivated($pluginName)) {
                Log::debug("ComponentFactory::%s: component for deactivated plugin ('%s') requested.",
                    $function, $pluginName);

                return null;
            }

            return $pluginManager->getLoadedPlugin($pluginName);
        } catch (Exception $e) {
            Log::debug($e);

            return null;
        }
    }
}