Completed
Push — master ( eef885...465d0c )
by
unknown
30:08 queued 12:49
created

Comment_Class::update()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 47
Code Lines 28

Duplication

Lines 18
Ratio 38.3 %

Importance

Changes 0
Metric Value
cc 7
eloc 28
nc 6
nop 1
dl 18
loc 47
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * Gestion des commentaires (POST, PUT, GET, DELETE)
4
 *
5
 * @author Jimmy Latour <[email protected]>
6
 * @since 1.0.0.0
7
 * @version 1.3.0.0
8
 * @copyright 2015-2017
9
 * @package wpeo_model
10
 * @subpackage class
11
 */
12
13
namespace eoxia;
14
15
if ( ! defined( 'ABSPATH' ) ) { exit; }
16
17
if ( ! class_exists( '\eoxia\Comment_Class' ) ) {
18
	/**
19
	 * Gestion des commentaires (POST, PUT, GET, DELETE)
20
	 */
21
	class Comment_Class extends Singleton_Util {
22
		/**
23
		 * Le nom du modèle à utiliser.
24
		 *
25
		 * @var string
26
		 */
27
		protected $model_name = 'comment_model';
28
29
		/**
30
		 * La clé principale pour enregistrer les meta données.
31
		 *
32
		 * @var string
33
		 */
34
		protected $meta_key = '_comment';
35
36
		/**
37
		 * Le type du commentaire
38
		 *
39
		 * @var string
40
		 */
41
		protected $comment_type	= '';
42
43
		/**
44
		 * Uniquement utile pour DigiRisk...
45
		 *
46
		 * @var string
47
		 */
48
		protected $identifier_helper = 'comment';
49
50
		/**
51
		 * Fonction de callback après avoir récupérer le modèle en mode GET.
52
		 *
53
		 * @var array
54
		 */
55
		protected $after_get_function = array( '\eoxia\construct_current_date' );
56
57
		/**
58
		 * Fonction de callback avant d'insérer les données en mode POST.
59
		 *
60
		 * @var array
61
		 */
62
		protected $before_post_function = array( '\eoxia\convert_date' );
63
64
		/**
65
		 * Fonction de callback avant de dispatcher les données en mode POST.
66
		 *
67
		 * @var array
68
		 */
69
		protected $before_model_post_function = array();
70
71
		/**
72
		 * Fonction de callback après avoir inséré les données en mode POST.
73
		 *
74
		 * @var array
75
		 */
76
		protected $after_post_function = array();
77
78
		/**
79
		 * Fonction de callback avant de mêttre à jour les données en mode PUT.
80
		 *
81
		 * @var array
82
		 */
83
		protected $before_put_function = array( '\eoxia\convert_date' );
84
85
		/**
86
		 * Fonction de callback avant de dispatcher les données en mode PUT.
87
		 *
88
		 * @var array
89
		 */
90
		protected $before_model_put_function = array();
91
92
		/**
93
		 * Fonction de callback après avoir mis à jour les données en mode PUT.
94
		 *
95
		 * @var array
96
		 */
97
		protected $after_put_function = array();
98
99
		/**
100
		 * Le constructeur pour Singleton_Util
101
		 *
102
		 * @since 1.0.0.0
103
		 * @version 1.3.0.0
104
		 *
105
		 * @return void
106
		 */
107
		protected function construct() {}
108
109
		/**
110
		 * Permet de récupérer le schéma avec les données du modèle par défault.
111
		 *
112
		 * @since 1.0.0.0
113
		 * @version 1.3.0.0
114
		 *
115
		 * @return Comment_Model
116
		 */
117
		public function get_schema() {
118
			$model_name = $this->model_name;
119
			$model = new $model_name( array() );
120
			return $model->get_model();
121
		}
122
123
		/**
124
		 * Récupères les données selon le modèle définis.
125
		 *
126
		 * @since 1.0.0.0
127
		 * @version 1.3.0.0
128
		 *
129
		 * @param array   $args Les paramètres de get_comments @https://codex.wordpress.org/Function_Reference/get_comments.
130
		 * @param boolean $single Si on veut récupérer un tableau, ou qu'une seule entrée.
131
		 *
132
		 * @return Comment_Model
133
		 */
134
		public function get( $args = array(
135
				'post_id' => 0,
136
				'parent' => 0,
137
			),
138
			$single = false ) {
139
140
			$array_model = array();
0 ignored issues
show
Unused Code introduced by
$array_model is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
141
			$array_comment = array();
142
143
			if ( ! empty( $this->comment_type ) ) {
144
				$args['type'] = $this->comment_type;
145
				$args['status'] = '-34070';
146
			}
147
148
			if ( empty( $args['status'] ) && ! empty( $this->status ) ) {
149
				$args['status'] = $this->status;
0 ignored issues
show
Bug introduced by
The property status does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
150
			}
151
152
			if ( ! empty( $args['id'] ) ) {
153
				$array_comment[] = get_comment( $args['id'], ARRAY_A );
154
			} elseif ( isset( $args['schema'] ) ) {
155
				$array_comment[] = array();
156
			} else {
157
				$array_comment = get_comments( $args );
158
			}
159
160
			$list_comment = array();
161
162
			if ( ! empty( $array_comment ) ) {
163
				foreach ( $array_comment as $key => $comment ) {
164
					$comment = (array) $comment;
165
166
					if ( ! empty( $comment['comment_ID'] ) ) {
167
						$list_meta = get_comment_meta( $comment['comment_ID'] );
168
						foreach ( $list_meta as &$meta ) {
169
							$meta = array_shift( $meta );
170
						}
171
172
						$comment = array_merge( $comment, $list_meta );
173
174
						if ( ! empty( $comment[ $this->meta_key ] ) ) {
175
							$comment = array_merge( $comment, json_decode( $comment[ $this->meta_key ], true ) );
176
							unset( $comment[ $this->meta_key ] );
177
						}
178
					}
179
180
					$model_name = $this->model_name;
181
					$list_comment[ $key ] = new $model_name( $comment );
182
					$list_comment[ $key ] = Model_Util::exec_callback( $list_comment[ $key ], $this->after_get_function );
183
				}
184
			} else {
185
				$model_name = $this->model_name;
186
				$list_comment[0] = new $model_name( array() );
187
				$list_comment[0] = Model_Util::exec_callback( $list_comment[0], $this->after_get_function );
188
			} // End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
189
190
			if ( true === $single && 1 === count( $list_comment ) ) {
191
				$list_comment = $list_comment[0];
192
			}
193
194
			return $list_comment;
195
		}
196
197
		/**
198
		 * Appelle la méthode update.
199
		 *
200
		 * @since 1.0.0.0
201
		 * @version 1.3.0.0
202
		 *
203
		 * @param  Array $data Les données.
204
		 * @return Array $data Les données
205
		 */
206
		public function create( $data ) {
207
			return $this->update( $data );
208
		}
209
210
		/**
211
		 * Insère ou met à jour les données dans la base de donnée.
212
		 *
213
		 * @since 1.0.0.0
214
		 * @version 1.3.0.0
215
		 *
216
		 * @param  Array $data Les données a insérer ou à mêttre à jour.
217
		 * @return Object      L'objet construit grâce au modèle.
218
		 */
219
		public function update( $data ) {
220
			$data = (array) $data;
221
			$model_name = $this->model_name;
222
223
			if ( empty( $data['id'] ) ) {
224
				$data = Model_Util::exec_callback( $data, $this->before_model_post_function );
225
				$data = new $model_name( $data, array( false ) );
226
227
				// Ajout du comment type et du status.
228
				// @todo: Enlevez ce truc bizarre.
229
				if ( empty( $data->type ) ) {
230
					$data->type = $this->comment_type;
231
					$data->status = '-34070';
232
				}
233
234
				$data = Model_Util::exec_callback( $data, $this->before_post_function );
235
236
				if ( ! empty( $data->error ) && $data->error ) {
237
					return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by eoxia\Comment_Class::update of type object.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
238
				}
239
240
				$data->id = wp_insert_comment( $data->do_wp_object() );
241
242
				$data = Model_Util::exec_callback( $data, $this->after_post_function );
243 View Code Duplication
			} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244
				$data = Model_Util::exec_callback( $data, $this->before_model_put_function );
245
				$current_data = $this->get( array(
246
					'id' => $data['id'],
247
				), true );
248
249
				$obj_merged = (object) array_merge( (array) $current_data, (array) $data );
250
				$data = new $model_name( (array) $obj_merged );
251
				$data = Model_Util::exec_callback( $data, $this->before_put_function );
252
253
				if ( ! empty( $data->error ) && $data->error ) {
254
					return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by eoxia\Comment_Class::update of type object.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
255
				}
256
257
				wp_update_comment( $data->do_wp_object() );
258
259
				$data = Model_Util::exec_callback( $data, $this->after_put_function );
260
			} // End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
261
262
			Save_Meta_Class::g()->save_meta_data( $data, 'update_comment_meta', $this->meta_key );
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class eoxia\Singleton_Util as the method save_meta_data() does only exist in the following sub-classes of eoxia\Singleton_Util: eoxia\Save_Meta_Class. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
263
264
			return $data;
265
		}
266
267
		/**
268
		 * Renvoie le type du commentaire
269
		 *
270
		 * @since 1.0.0.0
271
		 * @version 1.3.0.0
272
		 *
273
		 * @return string Le type du commentaire.
274
		 */
275
		public function get_type() {
276
			return $this->comment_type;
277
		}
278
279
		/**
280
		 * Pourquoi cette function ?
281
		 *
282
		 * @todo: Pourquoi cette function ?
283
		 *
284
		 * @since 1.0.0.0
285
		 * @version 1.3.0.0
286
		 *
287
		 * @return string Le type du commentaire.
288
		 */
289
		public function get_post_type() {
290
			return $this->get_type();
291
		}
292
293
		/**
294
		 * Utile uniquement pour DigiRisk.
295
		 *
296
		 * @since 1.0.0.0
297
		 * @version 1.3.0.0
298
		 *
299
		 * @return string L'identifiant des commentaires pour DigiRisk.
300
		 */
301
		public function get_identifier_helper() {
302
			return $this->identifier_helper;
303
		}
304
	}
305
} // End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
306