Bin will be removed on June 1, 2014 in favor of http://gist.github.com. Please save all your pastes before then. So long, and thanks for all the fish!×
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
/**
 * Saves model hasAndBelongsToMany data to the database.
 *
 * @param array $joined Data to save
 * @param mixed $id ID of record in this model
 * @access private
 */
    function __saveMulti($joined, $id, &$db) {
        foreach ($joined as $assoc => $data) {
 
            if (isset($this->hasAndBelongsToMany[$assoc])) {
                list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']);
 
                $isUUID = !empty($this->{$join}->primaryKey) && (
                        $this->{$join}->_schema[$this->{$join}->primaryKey]['length'] == 36 && (
                        $this->{$join}->_schema[$this->{$join}->primaryKey]['type'] === 'string' ||
                        $this->{$join}->_schema[$this->{$join}->primaryKey]['type'] === 'binary'
                    )
                );
 
                $newData = $newValues = array();
                $primaryAdded = false;
 
                $fields =  array(
                    $db->name($this->hasAndBelongsToMany[$assoc]['foreignKey']),
                    $db->name($this->hasAndBelongsToMany[$assoc]['associationForeignKey'])
                );
 
                $idField = $db->name($this->{$join}->primaryKey);
                if ($isUUID && !in_array($idField, $fields)) {
                    $fields[] = $idField;
                    $primaryAdded = true;
                }
 
 
                $oldLinks = array();
                $toDeleteLinks = array();
 
                if ($this->hasAndBelongsToMany[$assoc]['unique']) {
                    $conditions = array_merge(
                        array($join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id),
                        (array)$this->hasAndBelongsToMany[$assoc]['conditions']
                    );
                    $links = $this->{$join}->find('all', array(
                        'conditions' => $conditions,
                        'recursive' => empty($this->hasAndBelongsToMany[$assoc]['conditions']) ? -1 : 0,
                        'fields' => $this->hasAndBelongsToMany[$assoc]['associationForeignKey']
                    ));
 
                    $associationForeignKey = "{$join}." . $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
                    $oldLinks = Set::extract($links, "{n}.{$associationForeignKey}");
                   
                    $toDeleteLinks = array();
                   
                    $newLinks = array();
                    foreach((array)$data as $row){
                        $newLink = null;
                       
                        if ((is_string($row) && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
                            $newLink = $row;
                        } elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
                            if(isset($row[$this->{$join}->primaryKey])){
                                continue;
                            }
                            $newLink = $row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
                        } elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
                            if(isset($row[$join][$this->{$join}->primaryKey])){
                                continue;
                            }
                            $newLink = $row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
                        }
                       
                        if(!$newLink){
                            continue;
                        }
                       
                        $newLinks[] = $newLink;
                    }
                    $newLinks = array_unique($newLinks);
                   
                    $toDeleteLinks = array_diff($oldLinks,$newLinks);
                   
                    if (!empty($toDeleteLinks)) {
                        $conditions[$associationForeignKey] = $toDeleteLinks;
                        $db->delete($this->{$join}, $conditions);
                    }
                }
 
                foreach ((array)$data as $row) {
                    if ((is_string($row) && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
                        if(in_array($row,$oldLinks)){
                            continue;
                        }
                        $values = array(
                            $db->value($id, $this->getColumnType($this->primaryKey)),
                            $db->value($row)
                        );
                        if ($isUUID && $primaryAdded) {
                            $values[] = $db->value(String::uuid());
                        }
                        $values = implode(',', $values);
                        $newValues[] = "({$values})";
                        unset($values);
                    } elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
                        if(in_array($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']],$oldLinks)
                            && !isset($row[$this->{$join}->primaryKey]) ){
                            continue;
                        }
                        $newData[] = $row;
                    } elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
                        if(in_array($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']],$oldLinks)
                             && !isset($row[$join][$this->{$join}->primaryKey]) ){
                            continue;
                        }
                        $newData[] = $row[$join];
                    }
                }
               
 
                if (!empty($newData)) {
                    foreach ($newData as $data) {
                        $data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
                        $this->{$join}->create($data);
                        $this->{$join}->save();
                    }
                }
 
                if (!empty($newValues)) {
                    $fields =  implode(',', $fields);
                    $db->insertMulti($this->{$join}, $fields, $newValues);
                }
               
            }
        }
    }