formatForService($ID, $type); } catch (Exception $e){ $this->logError('Could not format Item for service',[ 'itemID' => $ID, 'type' => $type, 'message' => $e->getMessage(), ]); } } return $items; } /*************************************************************** * Item creation ***************************************************************/ public function createBatchToService($data):array { $type = $data['type']??'post'; //Check if any of the submitted ids are already created $created = array_filter($data['items'], function($ID) use ($type) { return !empty($this->getServiceItemID($ID, $type)); }); $updated = []; if (!empty($created)) { $updateData = $data; $updateData['items'] = $created; $updated = $this->updateBatchToService($data); //remove any updated items from the original items to process $data['items'] = array_filter($data['items'], function ($ID) use ($created) { return !in_array($ID, $created); }); } $items = $this->formatItems($data['items'], $type); if (empty($items)) { return $this->noCreatedItems($updated); } $response = [ 'outcome' => 'failed', 'result' => [ 'message' => 'No result' ] ]; if ($this->hasBatchCreate) { $response = $this->sendBatchCreate($items); if (!is_wp_error($response)) { $result = $this->processBatchCreateResponse($data, $response); } else { $this->logError('Batch create failed',[ 'method' => 'createBatchToService', 'item_ids' => $data['items'], 'error' => $response ]); $this->updateItemStatus($data['items'], 'error'); $result = [ 'outcome' => 'failed_permanent', 'result' => 'Could not update items' ]; } } else { $success = $errors = []; foreach ($items as $item) { $itemResult = $this->createOne($item); if (!is_wp_error($itemResult)) { $success[] = $itemResult; } else { $errors[] = $itemResult; } } $result = [ 'outcome' => empty($errors) ? 'success' : (empty($success) ? 'failed' : 'partial'), 'result' => [ 'success' => $success, 'errors' => $errors ] ]; } return array_merge($result, $updated); } /** * To be implemented by integration extension. Updates a single item * @param array $item * @return array|WP_Error */ protected function createOne(array $item):array|WP_Error { return new WP_Error('invalid', 'Integration '.$this->service_name.' must implement its own createOne'); } /** * Overridden by child classes * @param array $items * @return array|WP_Error */ protected function sendBatchCreate(array $items):array|WP_Error { return new WP_Error('invalid', 'Integration '.$this->service_name.' must implement its own sendBatchCreate'); } /** * To be implemented by extensions * @param array $data * @param array $response * @return array */ protected function processBatchCreateResponse(array $data, array $response):array { return [ 'outcome' => 'failed', 'result' => [ 'message' => $this->service_name.' should implement processBatchCreateResponse.' ] ]; } /***************************************************************** * ITEM UPDATING *****************************************************************/ public function updateBatchToService(array $data):array { $type = $data['type']??'post'; $newlyCreated = []; if (!$this->canCreateOnUpdate) { $created = array_filter($data['items'], function($ID) use ($type) { return !empty($this->getServiceItemID($ID, $type)); }); //Test to see if we have any that haven't been created yet. //For some services, items may have to be created before they can be updated if (count($created) !== count($data['items'])) { $notCreated = array_filter($data['items'], function($ID) use ($type) { return empty($this->getServiceItemID($ID, $type)); }); $newData = $data; $newData['items'] = $notCreated; $newlyCreated = $this->createBatchToService($newData); } // If we don't have any that are created, just send the noUpdatedItems response, with any newly created items added if (empty($created)) { return $this->noUpdatedItems($newlyCreated); } $data['items'] = $created; } $items = $this->formatItems($data['items'], $type); if (empty($items)) { return $this->noUpdatedItems($newlyCreated); } if ($this->hasBatchUpdate) { $response = $this->sendBatchUpdate($items); if (!is_wp_error($response)) { $result = $this->processBatchUpdateResponse($data, $response); } else { $this->logError('Batch update failed',[ 'method' => 'updateBatchToService', 'item_ids' => $data['items'], 'error' => $response ]); $this->updateItemStatus($data['items'], 'error'); $result = [ 'outcome' => 'failed_permanent', 'result' => 'Could not update items' ]; } } else { $success = $errors = []; //Does not have batch update, manually update each one foreach ($items as $item) { $itemResult = $this->updateOne($item); if (!is_wp_error($itemResult)) { $success[] = $itemResult; } else { $errors[] = $itemResult; } } $result = [ 'outcome' => empty($errors) ? 'success' : (empty($success) ? 'failed' : 'partial'), 'result' => [ 'success' => $success, 'errors' => $errors ] ]; } return array_merge($result, $newlyCreated); } /** * To be implemented by integration extension. Updates a single item * @param array $item * @return array|WP_Error */ protected function updateOne(array $item):array|WP_Error { return new WP_Error('invalid', 'Integration '.$this->service_name.' must implement its own updateOne method'); } /** * Overridden by child classes * @param array $items * @return array|WP_Error */ protected function sendBatchUpdate(array $items):array|WP_Error { return new WP_Error('invalid', 'Integration '.$this->service_name.' must implement its own sendBatchUpdate'); } /** * To be implemented by extensions * @param array $data * @param array $response * @return array */ protected function processBatchUpdateResponse(array $data, array $response):array { return [ 'outcome' => 'failed', 'result' => [ 'message' => $this->service_name.' should implement processBatchUpdateResponse.' ] ]; } /***************************************************************** * UTILITY *****************************************************************/ protected function noUpdatedItems(array $created):array { $result = [ 'outcome' => 'success', 'result' => [ 'message' => 'No items to update', 'updated' => [], 'errors' => [], ] ]; if (!empty($created)) { error_log('Result before: '.print_r($result, true)); $result = array_merge($result, $created); error_log('Result after merge: '.print_r($result, true)); } return $result; } protected function noCreatedItems(array $updated):array { $result = [ 'outcome' => 'success', 'result' => [ 'message' => 'No items to create', 'created' => [], 'errors' => [], ] ]; if (!empty($updated)) { $result = array_merge($result, $updated); } return $result; } }