/**
  * @test
  */
 function entryは複数まとめて保存可能()
 {
     $emapper = new EntryMapper(self::$pdo);
     $entry = new Entry();
     $entry->author = 'Mr. Dummy';
     $entry->title = 'Hello';
     $entry->content = 'Hello, World!';
     $entry->published = new DateTime();
     $entry2 = new Entry();
     $entry2->author = 'Mr. Dummy';
     $entry2->title = 'Hello2';
     $entry2->content = 'Hello, World!2';
     $entry2->published = new DateTime();
     $emapper->insert(array($entry, $entry2));
     $this->assertArrayHasKey('entryId', $entry->toArray());
     $this->assertArrayHasKey('entryId', $entry2->toArray());
 }
 public function sync($contract_guid)
 {
     $this->authenticate($contract_guid);
     $active_tree = Dropbox::find($contract_guid);
     $previous_delta = empty($active_tree->delta) ? null : $active_tree->delta;
     $delta_data = $this->active_client->getDelta($previous_delta);
     foreach (['has_more', 'cursor', 'entries', 'reset'] as $required_key) {
         if (!isset($delta_data[$required_key])) {
             return ['success' => false, 'error_message' => 'Missing ' . $required_key];
         }
     }
     if ($delta_data['reset'] && !is_null($previous_delta)) {
         // Have yet to encounter a 'reset', documentation suggests it only
         // will occur at the initial (null) delta, and if an app folder is
         // renamed. Since we're not in an app folder, it shouldn't occur.
         //
         // That said, if it does occur, we need to know right away!
         error_log("DELTA RESET ENCOUNTERED FOR USER " . $contract_guid . " AT DELTA " . $previous_delta . " NEED TO TEST!");
         // From documentation:
         // https://www.dropbox.com/developers/core/docs#metadata-details
         // reset If true, clear your local state before processing the delta
         // entries. reset is always true on the initial call to /delta (i.e.
         // when no cursor is passed in). Otherwise, it is true in rare
         // situations, such as after server or account maintenance, or if a
         // user deletes their app folder.
         // Supposedly that means we have to reprocess this user's entire
         // dropbox account, from scratch. Very scary prospect.
         dd("Special case, not yet handled!...");
     }
     if (count($delta_data['entries']) < 1 && !$delta_data['has_more'] && !$delta_data['reset']) {
         $active_tree->delta = $delta_data['cursor'];
         $active_tree->save();
         return ['success' => true, 'updated' => false];
     }
     foreach ($delta_data['entries'] as $entry_key => list($entry['original_path'], $entry['update_data'])) {
         $entry_altered = false;
         $entry_created = false;
         $entry_deleted = false;
         // Remove attributes we don't track, are deprecated, etc.
         unset($delta_data['entries'][$entry_key][1]['thumb_exists'], $delta_data['entries'][$entry_key][1]['revision'], $entry['update_data']['icon'], $entry['update_data']['root'], $entry['update_data']['size'], $entry['update_data']['hash'], $entry['update_data']['thumb_exists'], $entry['update_data']['revision']);
         if (is_null($entry['update_data'])) {
             $entry_deleted = true;
         } elseif ($stored_entry = Entry::where('original_path', '=', $entry['original_path'])->where('dropbox_id', $contract_guid)->first()) {
             foreach ($entry['update_data'] as $entry_column => $entry_column_value) {
                 $stored_column_name = ['rev' => 'rev', 'bytes' => 'bytes', 'modified' => 'service_updated_at', 'client_mtime' => 'client_updated_at', 'path' => 'original_path', 'is_dir' => 'is_dir', 'mime_type' => 'mime_type'][$entry_column];
                 if ($entry_column_value !== $stored_entry->{$stored_column_name}) {
                     $stored_entry->{$stored_column_name} = $entry_column_value;
                     $entry_altered = true;
                 }
             }
         } else {
             // Path does not exist in the database
             $stored_entry = new Entry();
             $stored_entry->dropbox_id = $contract_guid;
             if ($entry['original_path'] == '/') {
                 $stored_entry->parent_id = 0;
             } else {
                 $parent_entry = Entry::where('original_path', '=', dirname($entry['original_path']))->where('dropbox_id', $contract_guid)->first();
                 if (!$parent_entry && dirname($entry['original_path']) == '/') {
                     // Generate a root since it is not shown in deltas
                     $parent_entry = new Entry();
                     $parent_entry->original_path = '/';
                     $parent_entry->dropbox_id = $contract_guid;
                     $parent_entry->parent_id = 0;
                     $parent_entry->rev = '';
                     $parent_entry->bytes = 0;
                     $parent_entry->mime_type = '';
                     $parent_entry->service_updated_at = '';
                     $parent_entry->client_updated_at = '';
                     $parent_entry->is_dir = 1;
                     $parent_entry->save();
                 }
                 $stored_entry->parent_id = $parent_entry->id;
             }
             $stored_entry->original_path = $entry['update_data']['path'];
             $stored_entry->rev = $entry['update_data']['rev'];
             $stored_entry->bytes = $entry['update_data']['bytes'];
             $stored_entry->mime_type = isset($entry['update_data']['mime_type']) ? $entry['update_data']['mime_type'] : '';
             $stored_entry->service_updated_at = $entry['update_data']['modified'];
             $stored_entry->client_updated_at = isset($entry['update_data']['client_mtime']) ? $entry['update_data']['client_mtime'] : '';
             $stored_entry->is_dir = $entry['update_data']['is_dir'];
             $entry_created = true;
         }
         if ($entry_altered || $entry_created) {
             $stored_entry->save();
         }
         if ($entry_created) {
             $data = ['action' => 'create', 'entry' => $stored_entry->toArray()];
             if (!$stored_entry->is_dir) {
                 Queue::push('FileHandlerController@create', $data, $this->file_queue_id);
             }
         }
         if ($entry_altered) {
             $data = ['action' => 'update', 'entry' => $stored_entry->toArray()];
             if (!$stored_entry->is_dir) {
                 Queue::push('FileHandlerController@update', $data, $this->file_queue_id);
             }
         }
         if ($entry_deleted) {
             // TODO: Fire off single-file deletion processing for this file, here
             if ($stored_entry = Entry::where('original_path', '=', $entry['original_path'])->where('dropbox_id', $contract_guid)->first()) {
                 // Remove any/all children files and folders to this folder
                 foreach ($stored_entry->children() as $child_entry) {
                     $data = ['action' => 'remove', 'entry' => $child_entry->toArray()];
                     Queue::push('FileHandlerController@remove', $data, $this->file_queue_id);
                     $child_entry->delete();
                 }
                 $data = ['action' => 'remove', 'entry' => $stored_entry->toArray()];
                 if (!$stored_entry->is_dir) {
                     Queue::push('FileHandlerController@remove', $data, $this->file_queue_id);
                 }
                 $stored_entry->delete();
             }
         }
     }
     $active_tree->delta = $delta_data['cursor'];
     $active_tree->save();
     // One delta sync per queue job
     return ['success' => true, 'updated' => true];
 }