Completed
Push — master ( 06771b...115968 )
by Askupa
01:21
created

Manager::prepare_json_object()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Amarkal\Shortcode;
4
5
class Manager
6
{
7
    /**
8
     * @var Singleton The reference to *Singleton* instance of this class
9
     */
10
    private static $instance;
11
    
12
    private $shortcodes = array();
13
    
14
    /**
15
     * Returns the *Singleton* instance of this class.
16
     *
17
     * @return Singleton The *Singleton* instance.
18
     */
19
    public static function get_instance()
20
    {
21
        if( null === static::$instance ) 
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
22
        {
23
            static::$instance = new static();
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
Documentation Bug introduced by
It seems like new static() of type this<Amarkal\Shortcode\Manager> is incompatible with the declared type object<Amarkal\Shortcode\Singleton> of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
24
        }
25
        return static::$instance;
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
Bug Compatibility introduced by
The expression static::$instance; of type Amarkal\Shortcode\Manage...kal\Shortcode\Singleton adds the type Amarkal\Shortcode\Manager to the return on line 25 which is incompatible with the return type documented by Amarkal\Shortcode\Manager::get_instance of type Amarkal\Shortcode\Singleton.
Loading history...
26
    }
27
    
28
    public function register_shortcode( $args )
29
    {
30
        $this->validate_args($args);
31
        if($this->shortcode_exists($args['id']))
32
        {
33
            throw new \RuntimeException("A shortcode with id '{$args['id']}' has already been registered");
34
        }
35
        $this->shortcodes[$args['id']] = array_merge($this->default_args(), $args);
36
    }
37
    
38
    public function print_json_object($plugin_array)
39
    {
40
        
41
        return $plugin_array;
42
    }
43
    
44
    public function enqueue_script($plugins_array)
45
    {
46
        // Printing the JSON object ensures that it will be available whenever 
47
        // the visual editor is present.
48
        echo "<script id='amarkal-shortcode-json' type='application/json'>{$this->prepare_json_object()}</script>";
49
        
50
        // This script must be included after the JSON object, since it refers
51
        // to it, and so the JSON must be readily available.
52
        $plugins_array['amarkal_shortcode'] = \Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/js/dist/amarkal-shortcode.min.js');
53
        return $plugins_array;
54
    }
55
56
    public function enqueue_popup_style()
57
    {
58
        \wp_enqueue_style('amarkal-shortcode',\Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/css/dist/amarkal-shortcode-popup.min.css'));
59
    }
60
61
    public function enqueue_editor_style()
62
    {
63
        \add_editor_style(\Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/css/dist/amarkal-shortcode-editor.min.css'));
64
    }
65
    
66
    /**
67
     * Create a JSON object that will be printed in the admin section
68
     * to be used by the TinyMCE plugin code.
69
     */
70
    private function prepare_json_object()
71
    {
72
        $json = array();
73
        foreach($this->shortcodes as $id => $shortcode)
74
        {
75
            $popup = new Popup($shortcode['fields']);
76
            $json[$id] = $shortcode;
77
            $json[$id]['html'] = $popup->render();
78
        }
79
        return json_encode($json);
80
    }
81
    
82
    /**
83
     * Default shortcode arguments
84
     */
85
    private function default_args()
86
    {
87
        return array(
88
            'id'                => null,
89
            'title'             => '',
90
            'template'          => null,
91
            'cmd'               => '',
92
            'width'             => 550,
93
            'height'            => 450,
94
            'fields'            => array(),
95
            'show_placeholder'  => true,
96
            'placeholder_class' => null
97
        );
98
    }
99
    
100
    /**
101
     * Check if a shortcode with the given ID has already been registered
102
     */
103
    private function shortcode_exists( $id )
104
    {
105
        return array_key_exists($id, $this->shortcodes);
106
    }
107
    
108
    /**
109
     * Validate that the provided arguments have the required arguments as
110
     * specified in self::required_args()
111
     */
112
    private function validate_args( $args )
113
    {
114
        foreach($this->required_args() as $arg)
115
        {
116
            if(!array_key_exists($arg, $args))
117
            {
118
                throw new \RuntimeException("Missing required argument '$arg'");
119
            }
120
        }
121
    }
122
    
123
    /**
124
     * A list of required arguments
125
     */
126
    private function required_args()
127
    {
128
        return array('id','template','fields');
129
    }
130
131
    /**
132
     * Private constructor to prevent instantiation
133
     */
134
    private function __construct() 
135
    {
136
        \add_filter('mce_external_plugins',array($this,'enqueue_script'));
137
        \add_action('admin_init', array($this,'enqueue_editor_style'));
138
        \add_action('admin_enqueue_scripts', array($this,'enqueue_popup_style'));
139
        \add_action('wp_enqueue_scripts', array($this,'enqueue_popup_style'));
140
    }
141
}