Completed
Push — master ( 209b6d...6da443 )
by Askupa
01:29
created

Manager::enqueue_editor_style()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
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
    /**
13
     * Undocumented variable
14
     *
15
     * @var array The list of registered shortcodes
16
     */
17
    private $shortcodes = array();
18
    
19
    /**
20
     * Returns the *Singleton* instance of this class.
21
     *
22
     * @return Singleton The *Singleton* instance.
23
     */
24
    public static function get_instance()
25
    {
26
        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...
27
        {
28
            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...
29
        }
30
        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 30 which is incompatible with the return type documented by Amarkal\Shortcode\Manager::get_instance of type Amarkal\Shortcode\Singleton.
Loading history...
31
    }
32
    
33
    /**
34
     * Register a shortcode 
35
     *
36
     * @param [array] $args
0 ignored issues
show
Documentation introduced by
The doc-type [array] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
37
     * @return void
38
     */
39
    public function register_shortcode( $args )
40
    {
41
        $config = $this->prepare_config($args);
42
43
        if($this->shortcode_exists($args['id']))
44
        {
45
            throw new \RuntimeException("A shortcode with id '{$args['id']}' has already been registered");
46
        }
47
48
        $this->shortcodes[$args['id']] = $config;
49
    }
50
    
51
    /**
52
     * Enqueue the shortcode script and print the JSON object
53
     *
54
     * @param [array] $plugins_array
0 ignored issues
show
Documentation introduced by
The doc-type [array] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
55
     * @return void
56
     */
57
    public function enqueue_script($plugins_array)
58
    {
59
        // Printing the JSON object ensures that it will be available whenever 
60
        // the visual editor is present.
61
        echo "<script id='amarkal-shortcode-json' type='application/json'>{$this->prepare_json_object()}</script>";
62
        
63
        // This script must be included after the JSON object, since it refers
64
        // to it, and so the JSON must be readily available.
65
        $plugins_array['amarkal_shortcode'] = \Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/js/dist/amarkal-shortcode.min.js');
66
        return $plugins_array;
67
    }
68
69
    /**
70
     * Enqueue the popup stylesheet. This needs to be separated from the editor
71
     * stylesheet since it is not part of the editor.
72
     *
73
     * @return void
74
     */
75
    public function enqueue_popup_style()
76
    {
77
        \wp_enqueue_style('amarkal-shortcode',\Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/css/dist/amarkal-shortcode-popup.min.css'));
78
    }
79
80
    /**
81
     * Enqueue the editor stylesheet.
82
     *
83
     * @return void
84
     */
85
    public function enqueue_editor_style()
86
    {
87
        \add_editor_style(\Amarkal\Core\Utility::path_to_url(__DIR__.'/assets/css/dist/amarkal-shortcode-editor.min.css'));
88
    }
89
    
90
    /**
91
     * Create a JSON object that will be printed in the admin section
92
     * to be used by the TinyMCE plugin code.
93
     */
94
    private function prepare_json_object()
95
    {
96
        $json = array();
97
        foreach($this->shortcodes as $id => $shortcode)
98
        {
99
            $popup = new Popup($shortcode['fields']);
100
            $json[$id] = $shortcode;
101
            $json[$id]['html'] = $popup->render();
102
        }
103
        return json_encode($json);
104
    }
105
    
106
    /**
107
     * Default shortcode arguments
108
     */
109
    private function default_args()
110
    {
111
        return array(
112
            'id'                => null,
113
            'title'             => '',
114
            'template'          => null,
115
            'cmd'               => '',
116
            'width'             => 550,
117
            'height'            => 450,
118
            'fields'            => array(),
119
            'show_placeholder'  => true,
120
            'placeholder_class' => null,
121
            'placeholder_icon'  => null,
122
            'placeholder_visible_field' => null
123
        );
124
    }
125
    
126
    /**
127
     * Check if a shortcode with the given ID has already been registered
128
     */
129
    private function shortcode_exists( $id )
130
    {
131
        return array_key_exists($id, $this->shortcodes);
132
    }
133
    
134
    /**
135
     * Validate that the provided arguments have the required arguments as
136
     * specified in self::required_args()
137
     */
138
    private function validate_args( $args )
139
    {
140
        foreach($this->required_args() as $arg)
141
        {
142
            if(!array_key_exists($arg, $args))
143
            {
144
                throw new \RuntimeException("Missing required argument '$arg'");
145
            }
146
        }
147
    }
148
149
    /**
150
     * Prepare a shortcode configuration array based on the given arguments
151
     *
152
     * @param [array] $args
0 ignored issues
show
Documentation introduced by
The doc-type [array] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
153
     * @return array
154
     */
155
    private function prepare_config( $args )
156
    {
157
        $this->validate_args($args);
158
        $config = array_merge($this->default_args(), $args);
159
160
        if($config['template'] === null)
161
        {
162
            $config['template'] = $this->generate_template($config['id'],$config['fields']);
163
        }
164
165
        return $config;
166
    }
167
168
    /**
169
     * Genereate a basic shortcode template based on the given set 
170
     * of shortcode fields.
171
     *
172
     * @param [string] $tag
0 ignored issues
show
Documentation introduced by
The doc-type [string] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
173
     * @param [array] $fields
0 ignored issues
show
Documentation introduced by
The doc-type [array] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
174
     * @return string
175
     */
176
    private function generate_template($tag, $fields)
177
    {
178
        $template = "[$tag";
179
        $self_enclosing = true;
180
181
        foreach($fields as $field)
182
        {
183
            $name = $field['name'];
184
            if('content' !== $name)
185
            {
186
                $template .= " $name=\"{{{$name}}}\"";
187
            }
188
            else $self_enclosing = false;
189
        }
190
191
        if($self_enclosing)
192
        {
193
            $template .= "/]";
194
        }
195
        else {
196
            $template .= "]{{content}}[/$tag]";
197
        }
198
        
199
        return "<p>$template</p>";
200
    }
201
    
202
    /**
203
     * A list of required arguments
204
     */
205
    private function required_args()
206
    {
207
        return array('id','title','fields');
208
    }
209
210
    /**
211
     * Private constructor to prevent instantiation
212
     */
213
    private function __construct() 
214
    {
215
        \add_filter('mce_external_plugins',array($this,'enqueue_script'));
216
        \add_action('admin_init', array($this,'enqueue_editor_style'));
217
        \add_action('admin_enqueue_scripts', array($this,'enqueue_popup_style'));
218
        \add_action('wp_enqueue_scripts', array($this,'enqueue_popup_style'));
219
    }
220
}