diff --git a/ProcessMaker/Http/Resources/Task.php b/ProcessMaker/Http/Resources/Task.php index 186c6ab89f..11008405d0 100644 --- a/ProcessMaker/Http/Resources/Task.php +++ b/ProcessMaker/Http/Resources/Task.php @@ -113,20 +113,6 @@ private function addAssignableUsers(&$array, $include) } } - private function loadUserRequestPermission(ProcessRequest $request, User $user, array $permissions) - { - $permissions[] = [ - 'process_request_id' => $request->id, - 'allowed' => $user ? $user->can('view', $request) : false, - ]; - - if ($request->parentRequest && $user) { - $permissions = $this->loadUserRequestPermission($request->parentRequest, $user, $permissions); - } - - return $permissions; - } - private function getAssignedUsers($users) { foreach ($users as $user) { @@ -148,16 +134,4 @@ private function getAssignedGroupMembers($groups) return $assignedUsers; } - - private function getData() - { - if ($this->loadedData) { - return $this->loadedData; - } - $dataManager = new DataManager(); - $task = $this->resource->loadTokenInstance(); - $this->loadedData = $dataManager->getData($task); - - return $this->loadedData; - } } diff --git a/ProcessMaker/Http/Resources/V1_1/TaskResource.php b/ProcessMaker/Http/Resources/V1_1/TaskResource.php new file mode 100644 index 0000000000..7877910217 --- /dev/null +++ b/ProcessMaker/Http/Resources/V1_1/TaskResource.php @@ -0,0 +1,174 @@ + ['id', 'firstname', 'lastname', 'email', 'username', 'avatar'], + 'requestor' => ['id', 'first_name', 'last_name', 'email'], + 'processRequest' => ['id', 'process_id', 'status'], + 'draft' => ['id', 'task_id', 'data'], + 'screen' => ['id', 'config'], + 'process' => ['id', 'name'], + ]; + + /** + * Transform the resource into an array. + * + * @param \Illuminate\Http\Request + * @return array + */ + public function toArray($request) + { + $array = [ + 'id' => $this->id, + 'element_name' => $this->element_name, + 'element_id' => $this->element_id, + 'due_at' => $this->due_at, + 'advancedStatus' => $this->advanceStatus, + ]; + + return $this->processInclude($request, $array); + } + + private static function addRelationshipKeyColumn(Builder $query, string $relationship): bool + { + $model = $query->getModel(); + if (!method_exists($model, $relationship)) { + return false; + } + $relationshipObject = $model->$relationship(); + if (!($relationshipObject instanceof Relation)) { + return false; + } + + if ($relationshipObject instanceof BelongsTo) { + $relationshipKey = $relationshipObject->getForeignKeyName(); + $query->addSelect($relationshipKey); + } + + return true; + } + + private static function addRelationship(ProcessRequestToken $model, string $relationship): bool + { + if (!method_exists($model, $relationship)) { + return false; + } + $relationshipObject = $model->$relationship(); + if (!($relationshipObject instanceof Relation)) { + return false; + } + + $relationshipColumns = self::$defaultFieldsFor[$relationship] ?? ['id']; + $model->$relationship = $relationshipObject->select($relationshipColumns)->get(); + + return true; + } + + public static function preprocessInclude(Request $request, Builder $query): self + { + foreach (self::$defaultFields as $field) { + $query->addSelect($field); + } + + $include = $request->query('include', []); + if ($include) { + $include = explode(',', $include); + } + $include = array_merge($include, self::$defaultIncludes); + + if (in_array('data', $include)) { + $query->addSelect('process_request_id'); + } + + foreach (self::$includeMethods as $key) { + if (!in_array($key, $include)) { + continue; + } + + self::addRelationshipKeyColumn($query, $key); + } + + $model = $query->first(); + foreach (self::$includeMethods as $key) { + if (!in_array($key, $include)) { + continue; + } + + self::addRelationship($model, $key); + } + + return new static($model); + } + + private function processInclude(Request $request, array $array) + { + $include = $request->query('include', []); + if ($include) { + $include = explode(',', $include); + } + + foreach (self::$includeMethods as $key) { + if (!in_array($key, $include)) { + continue; + } + + $method = self::INCLUDE_PREFIX . ucfirst($key); + if (method_exists($this, $method)) { + $attributes = $this->$method(); + $array = array_merge($array, $attributes); + } else { + $array[$key] = $this->$key; + } + } + return $array; + } +} diff --git a/ProcessMaker/Traits/TaskResourceIncludes.php b/ProcessMaker/Traits/TaskResourceIncludes.php index 429e0c6603..467190244a 100644 --- a/ProcessMaker/Traits/TaskResourceIncludes.php +++ b/ProcessMaker/Traits/TaskResourceIncludes.php @@ -6,7 +6,9 @@ use ProcessMaker\Http\Resources\ScreenVersion as ScreenVersionResource; use ProcessMaker\Http\Resources\Users; use ProcessMaker\Managers\DataManager; +use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\TaskDraft; +use ProcessMaker\Models\User; use ProcessMaker\ProcessTranslations\ProcessTranslation; use StdClass; @@ -14,6 +16,19 @@ trait TaskResourceIncludes { use TaskScreenResourceTrait; + + private function getData() + { + if ($this->loadedData) { + return $this->loadedData; + } + $dataManager = new DataManager(); + $task = $this->resource->loadTokenInstance(); + $this->loadedData = $dataManager->getData($task); + + return $this->loadedData; + } + private function includeData() { return ['data' => $this->getData()]; @@ -131,7 +146,7 @@ private function includeInterstitial() // Remove inspector metadata $interstitial['interstitial_screen']['config'] = $this->removeInspectorMetadata( - $interstitial['interstitial_screen']['config'] + $interstitial['interstitial_screen']['config'] ?: [] ); return [ @@ -146,4 +161,18 @@ private function includeUserRequestPermission() return ['user_request_permission' => $userRequestPermission]; } + + private function loadUserRequestPermission(ProcessRequest $request, User $user, array $permissions) + { + $permissions[] = [ + 'process_request_id' => $request->id, + 'allowed' => $user ? $user->can('view', $request) : false, + ]; + + if ($request->parentRequest && $user) { + $permissions = $this->loadUserRequestPermission($request->parentRequest, $user, $permissions); + } + + return $permissions; + } } diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js index 36adc17e16..7b5dde41a1 100644 --- a/resources/js/bootstrap.js +++ b/resources/js/bootstrap.js @@ -232,7 +232,30 @@ if (token) { console.error("CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token"); } +// Setup api versions +const apiVersionConfig = [ + { version: "1.0", baseURL: "/api/1.0/" }, + { version: "1.1", baseURL: "/api/1.1/" }, +]; + window.ProcessMaker.apiClient.defaults.baseURL = "/api/1.0/"; +window.ProcessMaker.apiClient.interceptors.request.use((config) => { + if (typeof config.url !== "string" || !config.url) { + throw new Error("Invalid URL in the request configuration"); + } + + apiVersionConfig.forEach(({ version, baseURL }) => { + const versionPrefix = `/api/${version}/`; + if (config.url.startsWith(versionPrefix)) { + // eslint-disable-next-line no-param-reassign + config.baseURL = baseURL; + // eslint-disable-next-line no-param-reassign + config.url = config.url.replace(versionPrefix, ""); + } + }); + + return config; +}); // Set the default API timeout let apiTimeout = 5000;