| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace HexMakina\Crudites\Grammar\Query; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use HexMakina\Crudites\Crudites; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use HexMakina\Crudites\CruditesException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use HexMakina\BlackBox\Database\TableInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | trait ClauseJoin | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |     protected $joined_tables = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |     abstract public function backTick($field, $table_name = null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     abstract public function addBinding($field, $value, $table_name, $bind_label = null): string; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |      * Adds a joined table to the query. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |      * @param string $join_table_name The name of the table to join. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |      * @param string $join_table_alias The alias for the joined table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |      * @throws \InvalidArgumentException If the alias is already allocated for a different table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     public function addJoinedTable($join_table_name, $join_table_alias) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |         if(!isset($this->joined_tables[$join_table_alias])){ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |             $this->joined_tables[$join_table_alias] = $join_table_name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         elseif ($this->joined_tables[$join_table_alias] !== $join_table_name){ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |             throw new \InvalidArgumentException(sprintf(__FUNCTION__.'(): ALIAS `%s` ALREADY ALLOCATED FOR TABLE  `%s`', $join_table_alias, $join_table_name)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |     public function join($table_names, $joins, $join_type = '') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |         list($join_table_name,$join_table_alias) = self::processParamTableNames($table_names); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |         if (preg_match('#^(INNER|LEFT|RIGHT|FULL)(\sOUTER)?#i', $join_type) !== 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |             $join_type = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         $this->addJoinedTable($join_table_name, $join_table_alias); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |         $raw_join = $this->generateJoin($join_type, $join_table_name, $join_table_alias, $joins); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         $this->joinRaw($raw_join); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 51 |  |  |     public function joinRaw($sql) | 
            
                                                                        
                            
            
                                    
            
            
                | 52 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 53 |  |  |         return $this->addClause('join', $sql); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     protected function generateJoin($join_type, $join_table_name, $join_table_alias = null, $join_fields = []): string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         $join_table_alias ??= $join_table_name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         $join_parts = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         foreach ($join_fields as $join_field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             $table = array_shift($join_field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             $field = array_shift($join_field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |              | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             if (!isset($table, $field, $join_field[0])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |                 throw new \InvalidArgumentException('INVALID_JOIN_FIELDS'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |             $right_operand = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |             // 4 join params -> t.f = t.f | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |             if (isset($join_field[1])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                 $right_operand = $this->backTick($join_field[1], $join_field[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |             }  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |             // 3 join params -> t.f = v | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |             else{  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |                 $value = $join_field[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |                 // join bind label | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |                 $bind_label = sprintf(':jbl_%s_%s', $join_table_alias, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |                 // vd($bind_label, 'bind_label'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |                 $this->addBinding($field, $value, $join_table_alias, $bind_label); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |                 $right_operand = $bind_label; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |        | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |             $join_parts[] = sprintf('%s = %s', $this->backTick($field, $table), $right_operand); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         return sprintf('%s JOIN `%s` %s ON %s', $join_type, $join_table_name, $join_table_alias, implode(' AND ', $join_parts)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |      * @return mixed[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |     public function joinedTables(): array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |         return $this->joined_tables; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |      * @return mixed[]|string[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     private static function processParamTableNames($table_names): array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         // it's an array with two indexes, all fine | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |         if (is_array($table_names) && isset($table_names[1]) && !isset($table_names[2])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |             return $table_names; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         if (is_array($table_names) && !isset($table_names[1])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             $table_names = current($table_names); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         if (is_string($table_names)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             return [$table_names, $table_names]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         throw new \InvalidArgumentException('INVALID_PARAM_TABLE_NAMES'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 122 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 123 |  |  |  |