Completed
Branch FET-8365-add-indexes (3fce8d)
by
unknown
512:51 queued 496:29
created

EE_HABTM_Any_Relation   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 214
Duplicated Lines 8.41 %

Coupling/Cohesion

Components 1
Dependencies 4
Metric Value
wmc 15
lcom 1
cbo 4
dl 18
loc 214
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A _construct_finalize_set_models() 0 8 2
A get_join_table_fk_field_to() 0 9 2
B get_join_to_intermediate_model_statement() 0 29 1
B get_join_statement() 0 31 2
B add_relation_to() 9 46 4
B remove_relation_to() 9 37 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Joins any two models together via a has-and-belongs-to-many relation, using 
4
 * the esp_extra_join table.
5
 */
6
class EE_HABTM_Any_Relation extends EE_HABTM_Relation{	
7
	/**
8
	 *
9
	 * @var string
10
	 */
11
	protected $_alphabetically_first_model_name = null;
12
13
	/**
14
	 * Object representing the relationship between two models. HasAndBelongsToMany relations always use a join-table
15
	 * (and an ee joining-model.) This knows how to join the models,
16
	 * get related models across the relation, and add-and-remove the relationships.
17
	 * @param boolean $block_deletes for this type of relation, we block by default for now. if there are related models across this relation, block (prevent and add an error) the deletion of this model
18
	 * @param type $blocking_delete_error_message a customized error message on blocking deletes instead of the default
19
	 */
20
	function __construct( $block_deletes = true, $blocking_delete_error_message =''){
21
		parent::__construct( 'Extra_Join', $block_deletes, $blocking_delete_error_message);
22
	}
23
	function _construct_finalize_set_models($this_model_name, $other_model_name){
24
		if( $this_model_name < $other_model_name ) {
25
			$this->_alphabetically_first_model_name = $this_model_name;
26
		} else{
27
			$this->_alphabetically_first_model_name = $other_model_name;
28
		}
29
		return parent::_construct_finalize_set_models( $this_model_name, $other_model_name );
30
	}
31
	
32
	/**
33
	 * 
34
	 * @param string $model_name
35
	 * @param string $comparison_model_name
0 ignored issues
show
Documentation introduced by
There is no parameter named $comparison_model_name. Did you maybe mean $model_name?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
36
	 * @param string $id_or_name_field should be the string 'ID' or 'name' only
37
	 * @return EE_Model_Field_Base
38
	 */
39
	function get_join_table_fk_field_to( $model_name, $id_or_name_field ) {
40
		$order = null;
0 ignored issues
show
Unused Code introduced by
$order 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...
41
		if( $model_name === $this->_alphabetically_first_model_name ) {
42
			$order = 'first';
43
		} else {
44
			$order = 'second';
45
		}
46
		return $this->get_join_model()->field_settings_for( 'EXJ_' . $order . '_model_' . $id_or_name_field );
0 ignored issues
show
Bug introduced by
The method field_settings_for cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
47
	}
48
	/**
49
	 * Gets the SQL string for joining the main model's table containing the pk to the join table. Eg "LEFT JOIN real_join_table AS join_table_alias ON this_table_alias.pk = join_table_alias.fk_to_this_table"
50
	 * @param string $model_relation_chain like 'Event.Event_Venue.Venue'
51
	 * @return string of SQL
52
	 */
53
	function get_join_to_intermediate_model_statement($model_relation_chain){
54
		//create sql like
55
		//LEFT JOIN join_table AS join_table_alias ON this_table_alias.this_table_pk = join_table_alias.join_table_fk_to_this
56
		//LEFT JOIN other_table AS other_table_alias ON join_table_alias.join_table_fk_to_other = other_table_alias.other_table_pk
57
		//remember the model relation chain to the JOIN model, because we'll
58
		//need it for get_join_statement()
59
		$this->_model_relation_chain_to_join_model = $model_relation_chain;
60
		$this_table_pk_field = $this->get_this_model()->get_primary_key_field();
0 ignored issues
show
Bug introduced by
The method get_primary_key_field cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
61
		$join_table_fk_field_to_this_table = $this->get_join_table_fk_field_to( 
62
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
63
				'ID' );
64
		$field_with_model_name = $this->get_join_table_fk_field_to( 
65
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
66
				'name' );
67
		$this_table_alias = EE_Model_Parser::extract_table_alias_model_relation_chain_prefix($model_relation_chain, $this->get_this_model()->get_this_model_name()) . $this_table_pk_field->get_table_alias();
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
68
		$join_table_alias = EE_Model_Parser::extract_table_alias_model_relation_chain_prefix($model_relation_chain, $this->get_join_model()->get_this_model_name()) . $join_table_fk_field_to_this_table->get_table_alias();
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
69
		$join_table = $this->get_join_model()->get_table_for_alias($join_table_alias);
0 ignored issues
show
Bug introduced by
The method get_table_for_alias cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
70
		//phew! ok, we have all the info we need, now we can create the SQL join string
71
		$SQL = $this->_left_join(
72
					$join_table, 
73
					$join_table_alias, 
74
					$join_table_fk_field_to_this_table->get_table_column(), 
75
					$this_table_alias, 
76
					$this_table_pk_field->get_table_column(),
77
					$field_with_model_name->get_qualified_column()."='".$this->get_this_model()->get_this_model_name()."'" ) .
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
78
				$this->get_join_model()->_construct_internal_join_to_table_with_alias($join_table_alias);
0 ignored issues
show
Bug introduced by
The method _construct_internal_join_to_table_with_alias cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
79
80
		return $SQL;
81
	}
82
	/**
83
	 * Gets the SQL string for joining the join table to the other model's pk's table. Eg "LEFT JOIN real_other_table AS other_table_alias ON join_table_alias.fk_to_other_table = other_table_alias.pk"
84
	 * If you want to join between modelA -> joinModelAB -> modelB (eg, Event -> Event_Question_Group -> Question_Group),
85
	 * you shoudl prepend the result of this function with results from get_join_to_intermediate_model_statement(),
86
	 * so that you join first to the intermediate join table, and then to the other model's pk's table
87
	 * @param string $model_relation_chain like 'Event.Event_Venue.Venue'
88
	 * @return string of SQL
89
	 */
90
	function get_join_statement($model_relation_chain){
91
		if( $this->_model_relation_chain_to_join_model === NULL ){
92
			throw new EE_Error( sprintf( __( 'When using EE_HABTM_Relation to create a join, you must call get_join_to_intermediate_model_statement BEFORE get_join_statement', 'event_espresso' )));
93
		}
94
		$join_table_fk_field_to_this_table = $this->get_join_table_fk_field_to( 
95
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
96
				'ID' );
97
		$join_table_fk_field_to_other_table = $this->get_join_table_fk_field_to( 
98
				$this->get_other_model()->get_this_model_name(),
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
99
				'ID' );
100
		$field_with_other_model_name = $this->get_join_table_fk_field_to( 
101
				$this->get_other_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
102
				'name' );
103
		
104
		$join_table_alias = EE_Model_Parser::extract_table_alias_model_relation_chain_prefix($this->_model_relation_chain_to_join_model, $this->get_join_model()->get_this_model_name()) . $join_table_fk_field_to_this_table->get_table_alias();
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
105
		
106
		$other_table_pk_field = $this->get_other_model()->get_primary_key_field();
0 ignored issues
show
Bug introduced by
The method get_primary_key_field cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
107
		$other_table_alias = EE_Model_Parser::extract_table_alias_model_relation_chain_prefix($model_relation_chain, $this->get_other_model()->get_this_model_name()) . $other_table_pk_field->get_table_alias();
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
108
		$other_table = $this->get_other_model()->get_table_for_alias($other_table_alias);
0 ignored issues
show
Bug introduced by
The method get_table_for_alias cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
109
110
		$SQL = $this->_left_join(
111
					$other_table, 
112
					$other_table_alias, 
113
					$other_table_pk_field->get_table_column(), 
114
					$join_table_alias, 
115
					$join_table_fk_field_to_other_table->get_table_column(),
116
					$field_with_other_model_name->get_qualified_column()."='".$this->get_other_model()->get_this_model_name()."'" 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
117
				) . 
118
				$this->get_other_model()->_construct_internal_join_to_table_with_alias($other_table_alias);
0 ignored issues
show
Bug introduced by
The method _construct_internal_join_to_table_with_alias cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
119
		return $SQL;
120
	}
121
122
	/**
123
	 * Ensures there is an entry in the join table between these two models. Feel free to do this manually if you like.
124
	 * @param EE_Base_Class/int $this_obj_or_id
0 ignored issues
show
Documentation introduced by
The doc-type EE_Base_Class/int could not be parsed: Unknown type name "EE_Base_Class/int" 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...
125
	 * @param EE_Base_Class/int $other_obj_or_id
0 ignored issues
show
Documentation introduced by
The doc-type EE_Base_Class/int could not be parsed: Unknown type name "EE_Base_Class/int" 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...
126
	 * @param array             $extra_join_model_fields_n_values col=>val pairs that are used as extra conditions for checking existing values and for setting new rows if no exact matches.
127
	 * @return EE_Base_Class
128
	 */
129
	 function add_relation_to($this_obj_or_id, $other_obj_or_id, $extra_join_model_fields_n_values = array() ){
130
		 $this_model_obj = $this->get_this_model()->ensure_is_obj($this_obj_or_id, true);
0 ignored issues
show
Bug introduced by
The method ensure_is_obj cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
131
		 $other_model_obj = $this->get_other_model()->ensure_is_obj($other_obj_or_id, true);
0 ignored issues
show
Bug introduced by
The method ensure_is_obj cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
132
		//check if such a relationship already exists
133
		$join_model_fk_to_this_model = $this->get_join_table_fk_field_to( 
134
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
135
				'ID' );
136
		$join_model_name_field_to_this_model = $this->get_join_table_fk_field_to( 
137
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
138
				'name' );
139
		$join_model_fk_to_other_model = $this->get_join_table_fk_field_to(
140
				$this->get_other_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
141
				'ID' );
142
		$join_model_name_field_to_other_model = $this->get_join_table_fk_field_to(
143
				$this->get_other_model()->get_this_model_name(),
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
144
				'name' );
145
146
		$cols_n_values =  array(
147
				$join_model_fk_to_this_model->get_name() => $this_model_obj->ID(),
148
				$join_model_name_field_to_this_model->get_name() => $this_model_obj->get_model()->get_this_model_name(),
149
				$join_model_fk_to_other_model->get_name() => $other_model_obj->ID(),
150
				$join_model_name_field_to_other_model->get_name() => $other_model_obj->get_model()->get_this_model_name() );
151
152
		//if $where_query exists lets add them to the query_params.
153 View Code Duplication
		if ( !empty( $extra_join_model_fields_n_values ) ) {
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...
154
		   //make sure we strip any of the join model names from the $where_query cause we don't need that in here (why? because client code may have used the same conditionals for get_all_related which DOES need the join model name)
155
		   //make sure we strip THIS models name from the query param
156
		   foreach ( $extra_join_model_fields_n_values as $query_param => $val ) {
157
			   $query_param = str_replace($this->get_join_model()->get_this_model_name().".","", $query_param);
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
158
			   $parsed_query[$query_param] = $val;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$parsed_query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $parsed_query = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
159
		   }
160
		   $cols_n_values = array_merge( $cols_n_values, $parsed_query );
0 ignored issues
show
Bug introduced by
The variable $parsed_query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
161
		}
162
163
		$query_params = array( $cols_n_values );
164
165
166
		$existing_entry_in_join_table = $this->get_join_model()->get_one($query_params);
0 ignored issues
show
Bug introduced by
The method get_one cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
167
		//if there is already an entry in the join table, indicating a relationship, we're done
168
		 //again, if you want more sophisticated logic or insertions (handling more columns than just 2 foreign keys to
169
		 //the other tables, use the joining model directly!
170
		if( ! $existing_entry_in_join_table ){
171
			$this->get_join_model()->insert($cols_n_values);
0 ignored issues
show
Bug introduced by
The method insert cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
172
		}
173
		return $other_model_obj;
174
	 }
175
	/**
176
	 * Deletes any rows in the join table that have foreign keys matching the other model objects specified
177
	 * @param EE_Base_Class/int $this_obj_or_id
0 ignored issues
show
Documentation introduced by
The doc-type EE_Base_Class/int could not be parsed: Unknown type name "EE_Base_Class/int" 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...
178
	 * @param EE_Base_Class/int $other_obj_or_id
0 ignored issues
show
Documentation introduced by
The doc-type EE_Base_Class/int could not be parsed: Unknown type name "EE_Base_Class/int" 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...
179
	 * * @param array           $where_query col=>val pairs that are used as extra conditions for checking existing values and for removing existing rows if exact matches exist.
180
	 * @return EE_Base_Class
181
	 */
182
	 function remove_relation_to($this_obj_or_id, $other_obj_or_id, $where_query = array() ){
183
		 $this_model_obj = $this->get_this_model()->ensure_is_obj($this_obj_or_id, true);
0 ignored issues
show
Bug introduced by
The method ensure_is_obj cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
184
		 $other_model_obj = $this->get_other_model()->ensure_is_obj($other_obj_or_id, true);
0 ignored issues
show
Bug introduced by
The method ensure_is_obj cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
185
		//check if such a relationship already exists
186
		$join_model_fk_to_this_model = $this->get_join_table_fk_field_to( 
187
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
188
				'ID' );
189
		$join_model_name_field_to_this_model = $this->get_join_table_fk_field_to( 
190
				$this->get_this_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_this_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
191
				'name' );
192
		$join_model_fk_to_other_model = $this->get_join_table_fk_field_to(
193
				$this->get_other_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
194
				'ID' );
195
		$join_model_name_field_to_other_model = $this->get_join_table_fk_field_to(
196
				$this->get_other_model()->get_this_model_name(), 
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_other_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
197
				'name' );
198
199
		$cols_n_values =  array(
200
				$join_model_fk_to_this_model->get_name() => $this_model_obj->ID(),
201
				$join_model_name_field_to_this_model->get_name() => $this_model_obj->get_model()->get_this_model_name(),
202
				$join_model_fk_to_other_model->get_name() => $other_model_obj->ID(),
203
				$join_model_name_field_to_other_model->get_name() => $other_model_obj->get_model()->get_this_model_name() );
204
205
		//if $where_query exists lets add them to the query_params.
206 View Code Duplication
		if ( !empty( $where_query ) ) {
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...
207
		 	//make sure we strip any of the join model names from the $where_query cause we don't need that in here (why? because client code may have used the same conditionals for get_all_related which DOES need the join model name)
208
		 	//make sure we strip THIS models name from the query param
209
		 	foreach ( $where_query as $query_param => $val ) {
210
				$query_param = str_replace($this->get_join_model()->get_this_model_name().".","", $query_param);
0 ignored issues
show
Bug introduced by
The method get_this_model_name cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
211
				$parsed_query[$query_param] = $val;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$parsed_query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $parsed_query = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
212
			}
213
		 	$cols_n_values = array_merge( $cols_n_values, $parsed_query );
0 ignored issues
show
Bug introduced by
The variable $parsed_query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
214
		}
215
216
		$existing_entry_in_join_table = $this->get_join_model()->delete( array($cols_n_values) );
0 ignored issues
show
Bug introduced by
The method delete cannot be called on $this->get_join_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Unused Code introduced by
$existing_entry_in_join_table 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...
217
		return $other_model_obj;
218
	 }
219
}
220