Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
podiocopy.bitkit.dk
httpdocs
app
Modules
Application
File Content:
AppToAppMoveRepo.php
<?php namespace App\Modules\Application; use App\Modules\Auth\AuthRepository; use App\Modules\Auth\PodioDBSession; use App\Modules\Auth\User; use App\Modules\Configurations\Config; use App\Modules\GenModels\Estimate; use App\Modules\GenModels\TransferQueue; use App\Modules\Item\AppToAppItemRepo; use App\Modules\Item\ItemModel; use App\Modules\Item\ItemRepo; use App\Modules\Logs\Helper; use App\Modules\OrganizationMove\OrganizationRepo; use App\Modules\WorkSpace\WorkSpaceModel; use App\Modules\WorkSpace\WorkSpaceMoveRepo; use Auth; use Exception; use Log; use MongoDB\BSON\ObjectId; use MongoId; use Podio; use PodioApp; use PodioAppField; use PodioComment; use PodioItem; use PodioNotFoundError; use PodioTask; /** * Created by PhpStorm. * User: jis * Date: 19/5/15 * Time: 3:07 PM */ class AppToAppMoveRepo { public function __construct() { $this->podioAppsModel = new PodioAppModel(); $this->podioItemModel = new ItemModel(); try { ini_set('memory_limit', '512M'); set_time_limit(0); // seconds } catch (Exception $e) { Log::error($e); } } public function doNextStepOfFirstApp($spaceID, $queueID) { $app = $this->podioAppsModel->find(array('space_id' => $spaceID, 'queue_id' => $queueID, 'status' => array('$ne' => 'completed')), 1); if ($app) { $this->doNextStep($app); } else { // all apps are moved to new space Log::info("doNextStepOfFirstApp:No app found"); // process next app $model = new TransferQueue(); $transferQueue = $model->findOne(array('_id' => new ObjectId($queueID))); switch ($transferQueue['type']) { case 'organization_move': case 'space_move': $model = new WorkSpaceModel(); $space = $model->find(array('space_id' => $spaceID, 'queue_id' => $queueID), 1); if ($space) { $model->update(array('_id' => $space['_id']), array('next_step' => 'process_space_task')); OrganizationRepo::callForNextStepOfSpace($space['queue_id']); } break; case 'app_move': Log::info("App move-all apps moved"); self::callForUpdateApp($spaceID, $queueID); break; case 'app_to_app_move': Log::info("AppToApp move-all apps moved"); } } } public function doNextStepOfAppToAppMove($queueID) { Log::info('inside doNextStepOfAppToAppMove'); $app = $this->podioAppsModel->find(array('queue_id' => $queueID, 'status' => array('$ne' => 'completed')), 1); if ($app) { $this->doNextStep($app); } else { // all apps are moved to new space Log::info("doNextStepOfFirstApp:No app found"); $item = $this->podioItemModel->find(array('queue_id' => $queueID, 'ref_update_status' => array('$ne' => 'completed')), 1); if (!is_null($item) && $item['ref_update_status'] != "completed") { log::info("Check for relation"); try { $itemRepo = new AppToAppItemRepo(); if (PodioDBSession::getRateLimitRemains($item['user']) <= 100) { Log::info("updateRelations" . $item['queue_id'] . ":Rate limit remaining is less than 1000" . ", adding to trigger"); $itemRepo->addTriggerForNextStepOfApp($item['queue_id'], 60); return true; } $itemRepo->itemRelationUpdate($item); $this->podioItemModel->update(array('_id' => $item['_id']), array('ref_update_status' => 'completed')); self::doNextStepOfAppToAppMove($queueID); } catch (Exception $e) { Log::debug($e); } } else { log::info("Check calculation"); $app = $this->podioAppsModel->find(array("have_calculation" => true, 'queue_id' => $queueID, 'calculation_status' => array('$ne' => 'completed')), 1); if ($app) { $itemRepo = new AppToAppItemRepo(); if (PodioDBSession::getRateLimitGenRemains($item['user']) <= 100) { Log::info("updateRelations" . $item['queue_id'] . ":Rate limit remaining is less than 1000" . ", adding to trigger"); $itemRepo->addTriggerForNextStepOfApp($item['queue_id'], 60); return true; } $calulationRepo = new CalculationAppToAppRepo(); $calulationRepo->updateCalculation($app); $this->podioAppsModel->update(array("_id" => $app['_id']), array("calculation_status" => "completed")); self::doNextStepOfAppToAppMove($queueID); } else { log::info("No more calculation"); $model = new TransferQueue(); $model->update(array('_id' => new ObjectId($queueID)), array("status" => "completed")); $missingCount = 0; $items = $this->podioItemModel->find(array('queue_id' => $queueID, 'status' => "not_completed", 'item_id' => array('$exists' => false))); $missingItems = array(); if ($items) { foreach ($items as $item) { $missingCount++; array_push($missingItems, $item['old_item_id']); } } Log::info('5'); if ($missingCount > 0) WorkSpaceMoveRepo::copyCompleteMissingSendMail($queueID, $missingItems); else WorkSpaceMoveRepo::copyCompleteSendMail($queueID); log::info("*****FINISHED******"); } } } } public function doNextStepOfItemMove($queueID) { $app = $this->podioAppsModel->find(array('queue_id' => $queueID, 'status' => array('$ne' => 'completed')), 1); if ($app) { $this->doNextStep($app); } else { // all apps are moved to new space Log::info("doNextStepOfFirstApp:No app found"); // process next app $model = new TransferQueue(); $transferQueue = $model->findOne(array('_id' => new ObjectId($queueID))); switch ($transferQueue['type']) { case 'organization_move': break; } } } public function getStartAppToAppMove($userId, $dbQueueID) { Log::info('inside getStartAppToAppMove'); $authRepo = new AuthRepository(); Log::info('userId--->' . $userId); if ($authRepo->authenticateUser($userId)) { Log::info('inside getStart if'); //get Estimate ID from payment success $estimateModel = new Estimate(); $doc = $estimateModel->findOne(array('_id' => new ObjectId($dbQueueID))); $queueModel = new TransferQueue(); $queueModel->create($doc); $newDoc = $queueModel->findOne(array('_id' => new ObjectId($dbQueueID))); $dupCustomMapping = array(); if ($newDoc) { if ($newDoc["status"] == "started_transfer" || $newDoc["status"] == "added_to_queue") { foreach ($newDoc["customMapping"] as $ind1 => $customMapping) { $itemCount = PodioItem::get_count(intval($newDoc["customMapping"][$ind1]["sourceApp"]["sourceAppID"])); $podioApp = PodioApp::get(intval($newDoc["customMapping"][$ind1]["destApp"]["destAppID"]), $attributes = array()); $appModel = new PodioAppModel(); $appData = array(); $appData['app_id'] = $newDoc["customMapping"][$ind1]["sourceApp"]["sourceAppID"]; $appData['app_name'] = $newDoc["customMapping"][$ind1]["sourceApp"]["sourceAppName"]; $appData['source_space_id'] = $newDoc["customMapping"][$ind1]["sourceApp"]["sourceSpaceID"]; $appData['source_view'] = isset($newDoc["customMapping"][$ind1]["sourceApp"]["sourceView"]) ? $newDoc["customMapping"][$ind1]["sourceApp"]["sourceView"] : false; $appData['source_org_id'] = $newDoc["customMapping"][$ind1]["sourceApp"]["sourceOrgID"]; $appData['target_app_id'] = $newDoc["customMapping"][$ind1]["destApp"]["destAppID"]; $appData['target_app_name'] = $newDoc["customMapping"][$ind1]["destApp"]["destAppName"]; $appData['target_space_id'] = $newDoc["customMapping"][$ind1]["destApp"]["destSpaceID"]; $appData['target_org_id'] = $newDoc["customMapping"][$ind1]["destApp"]["destOrgID"]; $appData['itemCount'] = $itemCount; $appData['queue_id'] = $dbQueueID; $appData['type'] = $podioApp->config['type']; $appData['user'] = $newDoc['user']; $appData['completed_steps'] = array(); $appData['error_messages'] = array(); $appData['next_step'] = "copy_items"; $appData['status'] = "not_completed"; $appData['calculation_status'] = "not_completed"; $appData['all_fields'] = []; $appData['new_fields'] = []; $appData['shareItem'] = $newDoc["customMapping"][$ind1]["shareItem"]; //check for 'addNew' field ,if found create new fields in target app and store field id in db $dupMapping = $customMapping; foreach ($customMapping["mapping"] as $ind2 => $mapping) { $dupMapping["mapping"][$ind2] = $mapping; if ($mapping["destinationFieldID"] == "addNew") { //create new field with the config of parent field and add its ids to the database $sourceFieldID = (int)$mapping["sourceFieldId"]; $sourceAppID = (int)$customMapping["sourceApp"]["sourceAppID"]; $config = $this->getFieldConfig($sourceAppID, $sourceFieldID); if ($config) { if ($mapping["fieldType"] == "app") { $attributes = array("type" => "app", "config" => array_filter($config)); $fieldID = PodioAppField::create((int)$customMapping["destApp"]["destAppID"], $attributes); $referenceTypeArray = $this->getNewReferenceTypeArray($newDoc, $config); PodioAppField::update((int)$customMapping["destApp"]["destAppID"], $fieldID, $attributes = array("label" => $config['label'], "settings" => array("referenceable_types" => $referenceTypeArray, "multiple" => $config['settings']['multiple']))); } else { if ($mapping["fieldType"] != "calculation") { $attributes = array("type" => $mapping["fieldType"], "config" => array_filter($config)); $fieldID = PodioAppField::create((int)$customMapping["destApp"]["destAppID"], $attributes); } } if (isset($fieldID)) { $dupMapping["mapping"][$ind2]["destinationFieldID"] = $fieldID . ''; if ($mapping["fieldType"] == "category") { $optionsCount = (int)$mapping["optionsCount"]; $dupMapping["mapping"][$ind2]['subCategory'] = []; for ($i = 0; $i < $optionsCount; $i++) { $dupMapping["mapping"][$ind2]['subCategory'][$i]['sourceChildID'] = $i + 1; $dupMapping["mapping"][$ind2]['subCategory'][$i]['destinationFieldID'] = $i + 1; } } } } } else if ($mapping["fieldType"] == "category") { //check for 'addNew' options //create options in categories and add its ids to the database $newOptions = $dupOptions = array(); $optionsCount = false; if (isset($mapping["subCategory"])) { foreach ($mapping["subCategory"] as $ind3 => $subCategory) { $dupOptions[$ind3] = $subCategory; if ($subCategory["destinationFieldID"] == "addNew") { $optionsCount = $optionsCount ? $optionsCount : $mapping["optionsCount"]; $newId = $optionsCount + 1; $newOptions[$optionsCount] = array( "id" => $newId, "text" => $subCategory["sourceLabel"] ); $dupOptions[$ind3]["destinationFieldID"] = $newId; $optionsCount++; } } $dupMapping["mapping"][$ind2]["subCategory"] = $dupOptions; if ($newOptions) { //append newOptions to config if (!isset($dupMapping["mapping"][$ind2]["config"]["settings"]["options"])) $dupMapping["mapping"][$ind2]["config"]["settings"]["options"] = array(); Log::info('Inside if ($newOptions)1 '); $newArray = []; foreach ($dupMapping["mapping"][$ind2]["config"]["settings"]["options"] as $option) { $newArray[] = (array)$option; } $dupMapping["mapping"][$ind2]["config"]["settings"]["options"] = $newArray; $dupMapping["mapping"][$ind2]["config"]["settings"]["options"] += $newOptions; $dupMapping["mapping"][$ind2]["config"]["settings"]["options"] = $this->changeToInteger($dupMapping["mapping"][$ind2]["config"]["settings"]["options"]); $dupMapping["mapping"][$ind2]["config"]["settings"]["options"] = array_filter($dupMapping["mapping"][$ind2]["config"]["settings"]["options"]); $dupMapping["mapping"][$ind2]["config"]["settings"]["multiple"] = $dupMapping["mapping"][$ind2]["config"]["settings"]["multiple"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["required"] = $dupMapping["mapping"][$ind2]["config"]["required"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["visible"] = $dupMapping["mapping"][$ind2]["config"]["visible"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["hidden"] = $dupMapping["mapping"][$ind2]["config"]["hidden"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["unique"] = $dupMapping["mapping"][$ind2]["config"]["unique"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["hidden_create_view_edit"] = $dupMapping["mapping"][$ind2]["config"]["hidden_create_view_edit"] == 'true' ? true : false; $dupMapping["mapping"][$ind2]["config"]["delta"] = (int)$dupMapping["mapping"][$ind2]["config"]["delta"]; Log::info('before try'); $new = []; $new = (array)$dupMapping["mapping"][$ind2]["config"]['settings']; $dupMapping["mapping"][$ind2]["config"]['settings'] = $new; PodioAppField::update($customMapping["destApp"]["destAppID"], $mapping["destinationFieldID"], array_filter((array)$dupMapping["mapping"][$ind2]["config"])); Log::info('after try'); } } } $fieldRel = []; $fieldRel['field_id'] = $mapping["sourceFieldId"]; $fieldRel['new_field_id'] = $dupMapping["mapping"][$ind2]["destinationFieldID"]; Log::info('2323'); if ($mapping["fieldType"] == "app") { $fieldRel['type'] = "app"; $fieldRel['config'] = $this->getFieldConfig((int)$customMapping["sourceApp"]["sourceAppID"], $mapping["sourceFieldId"]); } Log::info('======='); array_push($appData['all_fields'], $fieldRel); } Log::info('create'); $appModel->create($appData); $dupCustomMapping[$ind1] = $dupMapping; } } } Log::info('queue model update'); $queueModel->update(array('_id' => new ObjectId($dbQueueID)), array("customMapping" => $dupCustomMapping, "completedSteps" => "AddedNewFieldsToAllDestinationApps", "status" => "not_completed")); $appRepo = new AppToAppMoveRepo(); $appRepo->callForNextStepOfAppToAppMove($dbQueueID); } else { log::info("Auth Failed"); log::info($userId); } } public function changeToInteger($options) { foreach ($options as $index => $option) { $options[$index]["id"] = intval($option["id"]); } return $options; } public function getFieldConfig($sourceAppID, $sourceFieldID) { try { $field = PodioAppField::get($sourceAppID, $sourceFieldID); if ($field) { return $field->config; } else return false; } catch (Exception $e) { return false; } } public function getNewReferenceTypeArray($newDoc, $config) { $referenceTypeArray = []; $appNotFound = false; foreach ($newDoc['customMapping'] as $customMapping) { if (in_array($customMapping["sourceApp"]["sourceAppID"], $config['settings']['referenceable_types'])) { $referenceTypeArray[] = (int)$customMapping["destApp"]["destAppID"]; } else { $appNotFound = true; } } return $referenceTypeArray; } public function updateFirstApp($spaceID, $queueID) { $app = $this->podioAppsModel->find(array('space_id' => $spaceID, 'queue_id' => $queueID, 'update_status' => array('$ne' => 'updated')), 1); if ($app) { $this->doNextUpdateStep($app); } else { // all apps are moved to new space Log::info("All apps updated. No app found"); $transferQModel = new TransferQueue(); $transferQueue = $transferQModel->findOne(array('_id' => new ObjectId($queueID))); switch ($transferQueue['type']) { case 'organization_move': case 'space_move': $model = new WorkSpaceModel(); $space = $model->find(array('space_id' => $spaceID, 'queue_id' => $queueID), 1); if ($space) { $model->update(array('_id' => $space['_id']), array('update_status' => 'updated')); WorkSpaceMoveRepo::callForUpdateSpace($space['queue_id']); Log::info('Calling next space for update'); } break; case 'app_move': Log::info("App move-all apps updated"); $transferQModel->update(array('_id' => new ObjectId($queueID)), array('status' => 'completed')); WorkSpaceMoveRepo::copyCompleteSendMail($queueID); log::info("*****FINISHED******"); break; } } } public function doNextStep($app) { Log::info("AppMoveRepo: " . $app['_id'] . ", doNextStep:" . $app['next_step']); switch ($app['next_step']) { case 'save_app_structure': $this->saveAppStructure($app); break; case 'save_item_rel': $this->saveItemsRelation($app); break; case 'copy_item_comments': $userMdl = new User(); $user = $userMdl->findOne(array('_id' => $app['user'])); if ($user) { $userEmail = $user['email']; if (Config::checkIsCustomCopyUsers($userEmail)) { //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "Updated comments"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'copy_item_tasks', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } else { $this->copyItemComments($app); } } else { $this->copyItemComments($app); } break; case 'copy_item_tasks': $userMdl = new User(); $user = $userMdl->findOne(array('_id' => $app['user'])); if ($user) { $userEmail = $user['email']; if (Config::checkIsCustomCopyUsers($userEmail)) { //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "Item Task Copied"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'app_completed_process_next_app', //copy_app_tasks 'status' => 'completed', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } else { $this->copyItemTasks($app); } } break; case 'copy_items': $this->copyItems($app); break; case 'move_item': $this->moveItem($app); break; case 'app_completed_process_next_app': self::callForNextStepOfApp($app['space_id'], $app['queue_id']); break; } } public function moveItem($app) { self::callForNextStepOfItemMove($app['queue_id'], $app['app_id']); } public static function callForNextStepOfItemMove($queueID, $appID) { $param = array('queue_id' => $queueID, 'app_id' => $appID); $url = url() . '/app-move-async/do-next-step-of-item-move' . "?" . http_build_query($param); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); return; } public function doNextUpdateStep($app) { Log::info("AppMoveRepo, doNextUpdateStep:" . $app['next_update_step'] . ", appID:" . $app['_id']); switch ($app['next_update_step']) { case 'update_app_ref_structure': $this->updateAppStructure($app); break; case 'update_item_references': $this->updateItemReferences($app); break; case 'update_calculation': $this->updateCalculation($app); break; case 'process_next_app': self::callForUpdateApp($app['space_id'], $app['queue_id']); break; case 'no_update_needed': $this->noUpdateNeeded($app); break; } } /** * @param $app * Clone the podio app- cloning process may take time, there is no call back method */ private function cloneApp($app) { try { $response = PodioApp::install($app['app_id'], $attributes = array( "space_id" => $app['target_space_id'], "features" => array('votings', 'items', 'integration', 'flows', 'forms', 'filters', 'widgets') )); Log::info("Podio app cloned"); Log::info($response); } catch (Exception $e) { Log::error($e); } //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App clone started"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'check_clone_status', 'new_app_id' => $response, 'completed_steps' => $completed_steps)); // cloning process may take time, there is no call back method // add this to triggering system self::checkCloneStatusAsync($app['item_count'], $app['space_id'], $app['queue_id']); } /** * @param $count * @param $spaceId * @param $queueID * Add a trigger - run after some time* Add a trigger - run after some time * @internal param $targetSpaceDd */ public static function checkCloneStatusAsync($count, $spaceId, $queueID) { // $runAfter = ($count > 0) ? round((1 + ($count / 100))) : 0; // $url = "http://trigger.phases.dk/trigger/save-trigger"; // $param = array("server" => "podio-data-copy", // "space_id" => $spaceId, // 'queue_id' => $queueID, // 'url' => url() . '/app-move-async/do-next-step-of-first-app', // 'run_after' => 0 // ); // $url = $url . "?" . http_build_query($param); $param = array("space_id" => $spaceId, 'queue_id' => $queueID); $url = url() . '/app-move-async/do-next-step-of-first-app' . "?" . http_build_query($param); Log::info($url); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); // sleep(20); // self:: callForNextStepOfApp($spaceId, $queueID); return; } public static function addTriggerForNextStepOfApp($spaceId, $queueID, $runAfter) { // $url = "http://trigger.phases.dk/trigger/save-trigger"; // $param = array("server" => "podio-data-copy", // "space_id" => $spaceId, 'queue_id' => $queueID, // 'url' => url() . '/app-move-async/do-next-step-of-first-app', // 'run_after' => 0 // ); // $url = $url . "?" . http_build_query($param); $param = array("space_id" => $spaceId, 'queue_id' => $queueID); $url =url() . '/app-move-async/do-next-step-of-first-app' . "?" . http_build_query($param); Log::info($url); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); return; } public static function callForNextStepOfApp($spaceId, $queueID) { $param = array("space_id" => $spaceId, 'queue_id' => $queueID); $url = url() . '/app-move-async/do-next-step-of-first-app' . "?" . http_build_query($param); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); return; } public static function callForUpdateApp($spaceId, $queueID) { $param = array("space_id" => $spaceId, 'queue_id' => $queueID); $url = url() . '/app-move-async/do-update-first-app' . "?" . http_build_query($param); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; shell_exec($cmd); return; } public static function callForNextStepOfAppToAppMove($queueID) { Log::info('inside callForNextStepOfAppToAppMove'); $param = array('queue_id' => $queueID); $url = url() . '/app-move-async/do-next-step-of-app-to-app-move' . "?" . http_build_query($param); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); return; } /** * @param $app * Check clone status - whether all items are created or not */ private function checkCloneStatus($app) { $itemCount = PodioItem::get_count($app['new_app_id']); $itemCount = $itemCount ? $itemCount : 0; if ($itemCount < $app['item_count']) { /** * all items are not cloned due to some error. - stop the process */ if ($app['last_clone_check_count'] == $itemCount) { //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App clone completed"; $error_messages = $app['error_messages']; $error_messages[] = "Not all items Cloned"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'save_app_structure', 'completed_steps' => $completed_steps, 'error_messages' => $error_messages)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } else { $this->podioAppsModel->update(array('_id' => $app['_id']), array('last_clone_check_count' => $itemCount)); self::checkCloneStatusAsync($app['item_count'] - $itemCount, $app['space_id'], $app['queue_id']); } } else { // clone process completed PodioDBSession::updateRateLimitGeneral($app['user']); //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App clone completed"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'save_app_structure', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } } /** * @param $app * Save the app structure - Rel */ private function saveAppStructure($app) { // save the relational fields structure $fieldRel = array(); $fields = array(); $haveCalculation = false; $dependencyApps = array(); $newFields = array(); try { // get the original app structure $podioApp = PodioApp::get($app['app_id'], $attributes = array()); foreach ($podioApp->fields as $field) { if ($field->status == "active") { $itemField = array( 'type' => $field->type, 'field_id' => $field->field_id, 'label' => $field->config['label'], 'external_id' => $field->external_id, 'delta' => $field->config['delta'], ); switch ($field->type) { case 'calculation': $itemField['script'] = $field->config['settings']['script']; $itemField['script_status'] = "not_updated"; $haveCalculation = true; break; } if ($field->type == 'app') { if (array_key_exists("apps", $field->config['settings'])) { $det = array('field_id' => $field->field_id, 'external_id' => $field->external_id, 'new_field_id' => null); $det['config'] = array( 'label' => $field->config['label'], 'visible' => $field->config['visible'], 'delta' => $field->config['delta'], 'mapping' => $field->config['mapping'], 'default_value' => $field->config['default_value'], 'required' => $field->config['required'], 'description' => $field->config['description'] ); foreach ($field->config['settings']['apps'] as $appRel) { $det['relationApps'][] = array('app_id' => $appRel['app_id'], 'space_id' => $appRel['space_id']); } $fieldRel[] = $det; $itemField['relationApps'] = $det['relationApps']; } } $fields[] = $itemField; } } // dependencies $dependencies = PodioApp::dependencies($app['app_id']); $dependencyApps = array(); if ($dependencies['apps'] && count($dependencies['apps'])) { foreach ($dependencies['apps'] as $dependApp) { $dependencyApps[] = $dependApp->app_id; } } // get new app structure $podioApp = PodioApp::get($app['new_app_id'], $attributes = array()); $newFields = array(); foreach ($podioApp->fields as $field) { $itemField = array( 'type' => $field->type, 'field_id' => $field->field_id, 'label' => $field->config['label'], 'external_id' => $field->external_id ); $newFields[] = $itemField; } } catch (Exception $e) { Log::error($e); } //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App structure saved"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'save_item_rel', 'fields' => $fields, 'new_fields' => $newFields, 'dependencies' => $dependencyApps, 'relational_fields' => $fieldRel, 'next_update_step' => (count($fieldRel) > 0) ? 'update_app_ref_structure' : 'update_calculation', 'have_calculation' => $haveCalculation, 'calculation_recursion' => ($haveCalculation) ? "not_done" : 'not_needed', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } public function updateAppStructure($app) { $needToUpdateItems = false; $error_messages = $app['error_messages']; try { if ($app['relational_fields'] && count($app['relational_fields'])) { foreach ($app['relational_fields'] as &$relation) { if (array_key_exists('relationApps', $relation) && count($relation['relationApps']) > 0) { $aOriginalAppIds = $this->getRelationApps($relation['relationApps']); $config = $relation['config']; $config['settings'] = array('referenceable_types' => $aOriginalAppIds); try { if ($relation['new_field_id']) { $appField = PodioAppField::get($app['new_app_id'], $relation['new_field_id']); } else { $appField = PodioAppField::get($app['new_app_id'], $relation['external_id']); } PodioAppField::update($app['new_app_id'], $appField->field_id, $config); } catch (PodioNotFoundError $e) { Log::info("Field not found. Creating new field"); $attributes = array("type" => 'app', 'config' => $config); try { $resp = PodioAppField::create($app['new_app_id'], $attributes); $relation['new_field_id'] = intval($resp); } catch (Exception $e) { Log::error($e); $error_messages[] = array('error_message' => $e->getMessage(), 'error_trace' => $e->getTraceAsString()); } } catch (Exception $e) { Log::error($e); $error_messages[] = array('error_message' => $e->getMessage(), 'error_trace' => $e->getTraceAsString()); } $needToUpdateItems = true; } } PodioDBSession::updateRateLimitGeneral($app['user']); } } catch (Exception $e) { Log::error($e); } //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App structure Updated"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_update_step' => 'update_item_references', 'relational_fields' => $app['relational_fields'], 'need_to_update_items' => $needToUpdateItems, 'completed_steps' => $completed_steps, 'error_messages' => $error_messages)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextUpdateStep($app); } private function getRelationApps($relationApps) { $aOriginalAppIds = array(); foreach ($relationApps as $rel) { $originalRelApp = $this->podioAppsModel->find(array('app_id' => $rel['app_id']), 1); if ($originalRelApp) { $aOriginalAppIds[] = $originalRelApp['new_app_id']; } else Log::info("App not found:" . $rel['app_id']); } return $aOriginalAppIds; } /** * @param $app */ private function saveItemsRelation($app) { try { $itemRepo = new AppToAppItemRepo(); // get all the item from the new app $limit = 500; $offset = 0; do { $attributes = array( 'sort_desc' => true, 'limit' => $limit, 'offset' => $offset); $itemCollection = PodioItem::filter($app['new_app_id'], $attributes, $options = array()); PodioDBSession::updateRateLimit($app['user']); $count = count($itemCollection); foreach ($itemCollection as $item) { $itemID = $item->item_id; $oldItemID = str_replace("share_", "", $item->external_id); $oldPodioItem = PodioItem::get($oldItemID); $dbItemID = $itemRepo->saveItemRelation($app, $item, $oldItemID, $oldPodioItem); } if ($count > 0) PodioDBSession::updateRateLimitGeneral($app['user']); $offset += $limit; } while ($count >= $limit); } catch (Exception $e) { Log::error($e); } //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "Updated Item relation"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'copy_item_comments', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } /** * @param $app */ private function copyItems($app) { try { // get all the item from the new app $limit = 200; $offset = 0; do { $attributes = array( 'sort_desc' => true, 'limit' => $limit, 'offset' => $offset); if ($app['source_view']) $itemCollection = PodioItem::filter_by_view($app['app_id'], $app['source_view'], $attributes, $options = array()); else $itemCollection = PodioItem::filter($app['app_id'], $attributes, $options = array()); PodioDBSession::updateRateLimit($app['user']); $count = count($itemCollection); foreach ($itemCollection as $item) { $itemID = $item->item_id; $data = array("old_item_id" => $itemID, 'user' => $app['user'], 'app_id' => $app['app_id'], 'app_type' => $app['type'], 'new_app_id' => $app['target_app_id'], 'queue_id' => $app['queue_id'], 'shareItem' => $app['shareItem'], 'ref_update_status' => 'not_updated', 'comment_count' => $item->comment_count ? $item->comment_count : false, 'comment_status' => 'not_completed', 'task_status' => 'not_completed', 'next_step' => 'move_item', 'item_created_by_comment' => "*Item created by [" . $item->created_by->name . '](' . $item->created_by->url . ') on ' . date('Y-m-d H:i:s', $item->created_on->getTimestamp()) . '(UTC)*' . PHP_EOL, 'status' => 'not_completed' ); $itemModel = new ItemModel(); $existingItem = $itemModel->findOne(array('item_id' => $itemID, 'queue_id' => $app['queue_id'])); if (!$existingItem) $itemModel->create($data); } if ($count > 0) PodioDBSession::updateRateLimit($app['user']); $offset += $limit; } while ($count >= $limit); } catch (Exception $e) { Log::error($e); } // dependencies $dependencies = PodioApp::dependencies($app['app_id']); $dependencyApps = array(); if ($dependencies['apps'] && count($dependencies['apps'])) { foreach ($dependencies['apps'] as $dependApp) { $dependencyApps[] = $dependApp->app_id; } } //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "All Items Copied To DB"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'move_item', 'completed_steps' => $completed_steps, 'dependencies' => $dependencyApps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } private function updateItemReferences($app) { try { if ($app['need_to_update_items'] == true) { $itemRepo = new AppToAppItemRepo(); $itemRepo->updateItemRelation($app); } } catch (Exception $e) { Log::error($e); } //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App Item Reference Updated"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_update_step' => 'update_calculation', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextUpdateStep($app); } private function updateCalculation($app) { if ($app['have_calculation'] == true) { $calculationRepo = new CalculationRepo(); try { $calculationRepo->updateCalculation($app); } catch (Exception $e) { Log::error($e); } } //update $completed_steps = $app['completed_steps']; $completed_steps[] = "App Calculation fields Updated"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_update_step' => 'process_next_app', 'update_status' => "updated", 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextUpdateStep($app); } private function copyItemComments($app) { //check remaining rate limit try { if (PodioDBSession::getRateLimitGenRemains($app['user']) <= (($app['item_count']) * 100)) { Log::info("copyItemComments" . $app['queue_id'] . ":Rate limit remaining is less than " . ($app['item_count'] * 100) . ", adding to trigger"); self::addTriggerForNextStepOfApp($app['space_id'], $app['queue_id'], 60); return; } $itemModel = new ItemModel(); $items = $itemModel->find(array('new_app_id' => $app['new_app_id'], 'queue_id' => $app['queue_id'], 'comment_status' => array('$ne' => 'completed'))); if ($items) { $itemRepo = new AppToAppItemRepo(); foreach ($items as $item) { $itemRepo->copyComments($item, false, false); } PodioDBSession::updateRateLimitGeneral($app['user']); } } catch (Exception $e) { Log::error($e); } //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "Updated comments"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'copy_item_tasks', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } private function copyAppTasks($app) { $options = array('silent' => true, 'hook' => false); $attributes = array("reference" => "app:" . $app['app_id']); try { $tasks = PodioTask::get_all($attributes); foreach ($tasks as $task) { $commentAttributes = array(); $comment = $this->taskCreatedByComment($task); $taskStatus = $task->status; $attributes = array( "responsible" => $task->responsible->user_id, "group" => $task->group, "text" => $task->text, "description" => $task->description, "private" => $task->private, "due_on" => $task->due_on ? $task->due_on->format('Y-m-d H:i:s') : null, "due_date" => $task->due_date ? $task->due_date : null, // $task->due_date "due_time" => $task->due_time ? $task->due_time : null, //$task->due_time ); // todo Rate-limited $resp = PodioTask::create_for("app", $app['new_app_id'], $attributes, $options); $commentAttributes['value'] = $comment; PodioComment::create('task', $resp->task_id, $commentAttributes, $options); PodioDBSession::updateRateLimit($app['user']); if ($taskStatus == 'completed') { PodioTask::complete($resp->task_id); } } } catch (Exception $e) { Log::error($e); } //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "App Task Copied"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'app_completed_process_next_app', //copy_app_tasks 'status' => 'completed', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } private function copyItemTasks($app) { //check remaining rate limit try { if (PodioDBSession::getRateLimitRemains($app['user']) <= (($app['task_count']) * 10)) { Log::info("copyItemTasks" . $app['queue_id'] . ":Rate limit remaining is less than " . ($app['task_count'] * 10) . ", adding to trigger"); self::addTriggerForNextStepOfApp($app['space_id'], $app['queue_id'], 60); return; } $itemModel = new ItemModel(); $items = $itemModel->find(array('new_app_id' => $app['new_app_id'], 'queue_id' => $app['queue_id'], 'comment_status' => array('$ne' => 'completed'))); if ($items) { $itemRepo = new AppToAppItemRepo(); foreach ($items as $item) { $itemRepo->copyTasks($item, $app['user'], false, $app['new_app_id']); } } } catch (Exception $e) { Log::error($e); } //update app $completed_steps = $app['completed_steps']; $completed_steps[] = "Item Task Copied"; $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_step' => 'app_completed_process_next_app', //copy_app_tasks 'status' => 'completed', 'completed_steps' => $completed_steps)); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextStep($app); } private function noUpdateNeeded($app) { //update $this->podioAppsModel->update(array('_id' => $app['_id']), array('next_update_step' => 'process_next_app', 'update_status' => "updated")); //updated $app = $this->podioAppsModel->findOne(array('_id' => new ObjectId($app['_id']))); $this->doNextUpdateStep($app); } /** * @param $apps * @return array * Get estimate of app moving */ public function getEstimate($apps) { $result = array(); $totalAmount = Config::$SPACE_PRICE; $result['apps'] = array(); if ($apps != false && count($apps)) { foreach ($apps as $app) { $appRes = array(); $appRes['name'] = $app['name']; if (isset($app['viewId']) && $app['viewId'] != null) { $count = Podio::get("/item/app/{$app['id']}/count?view_id={$app['viewId']}")->json_body(); $itemCount = $count['count']; // $itemCount = PodioItem::get_count_view(intval($app['id']), $app['viewId']); } else { Log::info('enter else'); $itemCount = PodioItem::get_count(intval($app['id'])); } $appRes['itemCount'] = ($itemCount) ? $itemCount : 0; $totalAmount += ($appRes['itemCount'] * Config::$ITEM_PRICE); $result['apps'][] = $appRes; } } $result['totalAmount'] = Helper::formatNumber($totalAmount); return $result; } /** * @param $input * @return mixed * Save the move details to queue */ public function getSaveAppMove($input) { $data = array( 'user' => Auth::user()->id, 'type' => 'app_move', 'src_org_id' => intval($input['source_org']['id']), 'src_org' => $input['source_org']['name'], 'target_org_id' => intval($input['destination_org']['id']), 'target_org' => $input['destination_org']['name'], 'apps' => $input['apps'], 'src_space_id' => $input['sourceSpace']['id'], 'src_space_name' => $input['sourceSpace']['name'], 'target_space_id' => $input['destinationSpace']['id'], 'target_space_name' => $input['destinationSpace']['name'], 'status' => 'added_to_queue' ); $model = new TransferQueue(); return $model->create($data); } public function getSaveAppMoveEstimate($input) { $data = array( 'user' => Auth::user()->id, 'type' => 'app_move', 'src_org_id' => intval($input['source_org']['id']), 'src_org' => $input['source_org']['name'], 'target_org_id' => intval($input['destination_org']['id']), 'target_org' => $input['destination_org']['name'], 'apps' => $input['apps'], 'src_space_id' => $input['sourceSpace']['id'], 'src_space_name' => $input['sourceSpace']['name'], 'target_space_id' => $input['destinationSpace']['id'], 'target_space_name' => $input['destinationSpace']['name'], 'status' => 'added_to_queue' ); $model = new Estimate(); return $model->create($data); } public function getSaveAppToAppMoveEstimate($input) { $data = array( 'user' => Auth::user()->id, 'type' => 'app_to_app_move', 'apps' => $input['apps'], // 'src_details' => $input['sourceDetails'], // 'target_details' => $input['destinationDetails'], 'status' => 'added_to_queue' ); $model = new Estimate(); return $model->create($data); } /** * @param $queueID * Start moving app from one space to another */ public function startAppMove($queueID) { $model = new TransferQueue(); $podioAppsModel = new PodioAppModel(); $transferQueue = $model->findOne(array('_id' => new ObjectId($queueID))); if ($transferQueue['apps'] != false && count($transferQueue['apps'])) { foreach ($transferQueue['apps'] as $app) { $itemCount = PodioItem::get_count(intval($app['id'])); $itemCount = $itemCount ? $itemCount : 0; $taskCount = Podio::get("/task/app/" . $app['id'] . "/count"); $taskCount = json_decode($taskCount->body); $taskCount = ($taskCount->count) ? $taskCount->count : 0; $podioAppsModel->create(array( 'app_id' => intval($app['id']), 'app_name' => $app['name'], 'item_count' => $itemCount, 'task_count' => $taskCount, 'last_clone_check_count' => 0, 'space_id' => intval($transferQueue['src_space_id']), 'target_space_id' => intval($transferQueue['target_space_id']), 'src_org_id' => intval($transferQueue['src_org_id']), 'target_org_id' => intval($transferQueue['target_org_id']), 'queue_id' => $queueID, 'user' => $transferQueue['user'], 'status' => 'added_to_queue', 'update_status' => 'not_updated', 'next_step' => 'clone_app', 'next_update_step' => 'no_update_needed', 'error_messages' => array(), 'completed_steps' => array(), )); } } self:: callForNextStepOfApp(intval($transferQueue['src_space_id']), $queueID); } public function taskCreatedByComment($task) { $comment = PHP_EOL . PHP_EOL; $comment .= ' *Created by [' . $task->ref->created_by->name . '](' . $task->ref->created_by->url . ')*' . PHP_EOL . PHP_EOL; $comment .= ' *on ' . date('Y-m-d H:i:s', $task->ref->created_on->getTimestamp()) . '* '; // CET return $comment; } public function processQueue($dbQueueID) { $param = array('queue_id' => $dbQueueID); $url = url() . '/app-app-move/dest-app-items' . "?" . http_build_query($param); $cmd = " wget -O /dev/null -o /dev/null -qb -t 1 --no-check-certificate " . '"' . $url . '"'; $pid = shell_exec($cmd); return; } }
Edit
Download
Unzip
Chmod
Delete