source: trunk/prototype/Sync.php @ 6328

Revision 6328, 5.2 KB checked in by natan, 9 years ago (diff)

Ticket #2786 - Permitir transações separadas ao persistir uma lista de objetos - Corrigido

Line 
1<?php
2
3
4$accept = $_SERVER["HTTP_ACCEPT"];
5
6if( !isset( $args ) )
7    parse_str( file_get_contents('php://input'), $args );
8
9if(!function_exists('parseURI'))
10{
11    function parseURI( $URI )
12    {
13    //     $regex = "#^([a-zA-Z0-9-_]+)\(([a-zA-Z0-9-_]+)\)://(.*)|([a-zA-Z0-9-_]+)://(.*)$#";//TODO: checar essa RegExp
14        $regex = "#^([a-zA-Z0-9-_]+)://(.*)$#";
15
16        preg_match( $regex, $URI, $matches );
17
18        if( !$matches || empty($matches) )
19            return( array(false, $URI, false) );
20
21        return( $matches );
22    }
23}
24
25if(!function_exists('formatURI'))
26{
27    function formatURI( $concept = false, $id = false, $service = false )
28    {
29        return $concept ? $id ? $service ?
30
31               $concept.'://'.$id.'('.$service.')':
32
33               $concept.'://'.$id:
34
35               $concept:
36
37               false;
38    }
39}
40
41///Conversor Para utf8 ante de codificar para json pois o json so funciona com utf8
42if(!function_exists('toUtf8'))
43{
44    function toUtf8($data)
45    {
46        if(!is_array($data))
47          return mb_convert_encoding( $data , 'UTF-8' , 'UTF-8 , ISO-8859-1' );
48
49        $return = array();
50
51        foreach ($data as $i => $v)
52          $return[toUtf8($i)] = toUtf8($v);
53
54        return $return;
55    }
56}
57
58require_once 'api/controller.php';
59
60$mounted = array(); $synced = array();
61
62if(!function_exists('prepare'))
63{
64    function prepare( $concept, $id, $dt, &$data, &$oldIds, &$mounted, &$synced )
65    {
66        $oldIds[] = $id;
67
68        if( $dt === 'false' ||
69            $dt ===  false )
70            return( false );
71
72        if( !preg_match( '#^([a-zA-Z0-9-_]+)\(.*\)$#', $id ) )
73            $dt['id'] = $id;
74        elseif( isset($dt['id']) && $dt['id'] === $id )
75            unset($dt['id']);
76
77        $links = Controller::links( $concept );
78
79        foreach( $links as $linkName => $linkTarget )
80        {
81                    if( isset( $dt[$linkName] ) )
82                    {
83                            if( $notArray = Controller::hasOne( $concept, $linkName ) )
84                                    $dt[$linkName] = array( $dt[$linkName] );
85
86                            foreach( $dt[$linkName] as $i => $d )
87                            {
88                                    $currentURI = formatURI($links[$linkName], $d);
89
90                                    if( isset( $mounted[ $currentURI ] ) )
91                                    {
92                                            unset( $dt[$linkName][$i] );
93                                    }
94                                    elseif( isset( $synced[ $d ] ) )
95                                    {
96                                            $dt[$linkName][$i] = $synced[ $d ];
97                                    }
98                                    elseif( isset($data[ $currentURI ]) )
99                                    {
100                                            $value = $data[$currentURI];
101                                            unset( $data[ $currentURI ] );
102
103                                            $mounted[ $currentURI ] = true;
104
105                                            $dt[$linkName][$i] = prepare( $links[$linkName], $d, $value, $data, $oldIds, $mounted, $synced );
106                                    }
107                            }
108
109                            if( empty( $dt[$linkName] ) )
110                                    unset( $dt[$linkName] );
111                            elseif( $notArray )
112                                    $dt[$linkName] = $dt[$linkName][0];
113                    }
114        }
115
116        return( $dt );
117    }
118}
119
120$return = array();
121
122if( !isset( $args[0] ) )
123    $args = array( $args );
124
125Controller::addFallbackHandler( 0, function($e, $URI){
126
127    throw new Exception( $e->getMessage(), 100, $e );
128
129} );
130
131Controller::addFallbackHandler( 100, function( $e, $URI ){
132
133    Controller::rollback( $URI );
134    throw $e;
135
136});
137
138foreach( $args as $i => $data )
139{
140    foreach( $data as $uri => $dt )
141    {
142          if( !isset($data[$uri]) )
143                  continue;
144
145          list( , $concept, $id ) = parseURI( $uri );
146
147          unset( $data[$uri] );
148          $mounted[$uri] = true;
149
150          $oldIds = array();
151
152          $dt = prepare( $concept, $id, $dt, $data, $oldIds, $mounted, $synced );
153
154          try{
155              $result = Controller::put( array( 'concept' => $concept, 'id' => $id ), $dt );
156          }
157          catch( Exception $e ){
158              $return[ $uri ] = toUtf8( $e->getMessage() );
159              unset( $data[$uri] );
160              continue;
161          }
162
163          if( !$result )
164          {
165              $return[ $uri ] = 'ROLLBACK';
166              unset( $data[$uri] );
167              continue;
168          }
169
170          foreach( $result as $ii => $tx )
171          {
172              if( !isset($tx['order']) )
173                    continue;
174
175                  $oldId = $oldIds[ $tx['order'] ];
176
177                  if( isset( $oldId ) && $oldId )
178                  {
179                      $synced[ $oldId ] = $tx['id'];
180                      unset( $oldIds[ $tx['order'] ] );
181                  }
182
183                  $oldURI = formatURI( $tx['concept'], $oldId );
184                  unset( $data[$oldURI] );
185
186                  $return[ $oldURI ] = !$tx['rollback'] ? $dt ?
187                                       array( 'id' => $tx['id'] ) : false : 'ROLLBACK';
188          }
189    }
190
191    foreach( $data as $oldURI => $oldVal )
192      $return[ $oldURI ] = 'ROLLBACK';
193}
194
195
196echo json_encode( $return );
197
198Controller::closeAll();
199
200//         ob_start();
201//         print "\n";
202//         print "result: ";
203//         print_r( $result );
204//         $output = ob_get_clean();
205//         file_put_contents( "/tmp/prototype.log", $output , FILE_APPEND );
Note: See TracBrowser for help on using the repository browser.