[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: CloneProjectRepository.php
<?php /** -------------------------------------------------------------------------------- * This repository class manages all the data absctration for cloning projects * * @package Grow CRM * @author NextLoop *----------------------------------------------------------------------------------*/ /** -------------------------------------------------------------------------- * [Clone Invoice Repository] * Clone an project. The new project is set to 'draft status' by default * It can be published as needed * @source Nextloop *--------------------------------------------------------------------------*/ namespace App\Repositories; use App\Repositories\CloneEstimateRepository; use App\Repositories\CloneInvoiceRepository; use App\Repositories\MilestoneCategoryRepository; use App\Repositories\MilestoneRepository; use App\Repositories\ProjectRepository; use App\Repositories\TagRepository; use Illuminate\Support\Facades\File; use Illuminate\Support\Str; use Log; class CloneProjectRepository { //vars protected $projectrepo; protected $tagrepo; protected $milestonerepo; protected $milestonecategories; protected $cloneinvoicerepo; protected $cloneestimaterepo; protected $data; /** * Inject dependecies */ public function __construct( ProjectRepository $projectrepo, TagRepository $tagrepo, MilestoneRepository $milestonerepo, MilestoneCategoryRepository $milestonecategories, CloneInvoiceRepository $cloneinvoicerepo, CloneEstimateRepository $cloneestimaterepo ) { $this->projectrepo = $projectrepo; $this->tagrepo = $tagrepo; $this->milestonerepo = $milestonerepo; $this->milestonecategories = $milestonecategories; $this->cloneinvoicerepo = $cloneinvoicerepo; $this->cloneestimaterepo = $cloneestimaterepo; } /** * Clone an project * @param array data array * - project_id * - project_title * - project_date_start * - project_date_due * - tags * - project_categoryid * - copy_milestones * - copy_tasks * - copy_tasks_files * - copy_tasks_checklist * - copy_invoices * - copy_estimates * - copy_files * - return (id|object) * @return mixed int|object */ public function clone ($data = []) { //save global $this->data = $data; //info Log::info("cloning project started", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'payload' => $data]); //validate information if (!$this->validateData($data)) { Log::info("cloning project failed", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'payload' => $data]); return false; } //get clean the object for cloning $project = \App\Models\Project::Where('project_id', $data['project_id'])->first(); //clone main invoice $new_project = $project->replicate(); //update from provided data $new_project->project_importid = $data['project_id']; $new_project->project_clientid = $data['project_clientid']; $new_project->project_title = $data['project_title']; $new_project->project_date_start = $data['project_date_start']; $new_project->project_date_due = $data['project_date_due'] ?? null; $new_project->project_categoryid = $data['project_categoryid']; //update using some defaults $new_project->project_uniqueid = str_unique(); $new_project->project_status = 'not_started '; $new_project->project_active_state = 'active'; $new_project->project_visibility = 'visible'; $new_project->project_creatorid = auth()->id(); $new_project->project_calendar_timezone = config('system.settings_system_timezone'); //save $new_project->save(); //add tags $this->tagrepo->add('project', $new_project->project_id); //milestones $mileston_map = $this->copyMilestones($project, $new_project); //tasks $this->copyTasks($project, $new_project, $mileston_map); //invoice $this->copyInvoices($project, $new_project); //estimate $this->copyEstimates($project, $new_project); //folders $folder_mapping = $this->copyFolders($project, $new_project); //files $this->copyFiles($project, $new_project, $folder_mapping); //log its finished Log::info("cloning project completed", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'new_project_id' => $new_project->project_id]); //return invoice id | invoice object if (isset($data['return']) && $data['return'] == 'id') { return $new_project->project_id; } else { return $new_project; } } /** * Clone an project templates resources * @param array data array * - new_project_id * - template_project_id * - copy_milestones * - copy_tasks * - copy_tasks_files * - copy_tasks_checklist * @return mixed int|object */ public function cloneTemplate($data = []) { //append data $data += [ 'copy_milestones' => 'on', 'copy_tasks' => 'on', 'copy_files' => 'on', 'copy_tasks_files' => 'on', 'copy_tasks_checklist' => 'on', ]; //save global $this->data = $data; //validate //validation if (!isset($data['new_project_id']) || !isset($data['template_project_id'])) { Log::error("the supplied data is not valid", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'payload' => $data]); return false; } //get clean the object for cloning if (!$new_project = \App\Models\Project::Where('project_id', $data['new_project_id'])->first()) { Log::error("new project could not be loaded", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'template_project_id' => $data['template_project_id']]); return false; } //get clean the object for cloning if (!$template = \App\Models\Project::Where('project_id', $data['template_project_id'])->first()) { Log::error("template project could not be found", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'template_project_id' => $data['template_project_id']]); return false; } //milestones $mileston_map = $this->copyMilestones($template, $new_project); //tasks $this->copyTasks($template, $new_project, $mileston_map); //folders $folder_mapping = $this->copyFolders($template, $new_project); //files $this->copyFiles($template, $new_project, $folder_mapping); //tags $this->copyTags($template, $new_project); //save global $this->data = $data; } /** * copy milestones * @return bool */ private function copyMilestones($old_project, $new_project) { //milestone map $mileston_map = []; //we are copying if ($this->data['copy_milestones'] == 'on') { if ($milestones = \App\Models\Milestone::Where('milestone_projectid', $old_project->project_id)->get()) { foreach ($milestones as $milestone) { $new_milestone = $milestone->replicate(); $new_milestone->milestone_projectid = $new_project->project_id; $new_milestone->save(); //milestone map $mileston_map[$milestone->milestone_id] = $new_milestone->milestone_id; } } } //use defauls milestones if ($this->data['copy_milestones'] != 'on') { $position = $this->milestonecategories->addProjectMilestones($new_project); $this->milestonerepo->addUncategorised($new_project->project_id, $position); } //return map return $mileston_map; } /** * copy tasks * @return bool */ private function copyTasks($old_project, $new_project, $mileston_map) { //we are copying if ($this->data['copy_tasks'] == 'on' && $this->data['copy_milestones'] == 'on') { if ($tasks = \App\Models\Task::Where('task_projectid', $old_project->project_id)->get()) { foreach ($tasks as $task) { $new_task = $task->replicate(); $new_task->task_created = now(); $new_task->task_creatorid = auth()->id(); $new_task->task_clientid = $new_project->project_clientid; $new_task->task_projectid = $new_project->project_id; $new_task->task_date_start = now(); $new_task->task_date_due = null; $new_task->task_billable_status = 'not_invoiced'; $new_task->task_billable_invoiceid = null; $new_task->task_billable_lineitemid = null; $new_task->task_milestoneid = $mileston_map[$task->task_milestoneid]; //get new milestone id of the cloned milestone $new_task->task_cloning_original_task_id = $task->task_id; $new_task->task_uniqueid = str_unique(); $new_task->taskresource_id = $new_project->project_id; $new_task->save(); //copy check list if ($this->data['copy_tasks_checklist'] == 'on') { if ($checklists = \App\Models\Checklist::Where('checklistresource_type', 'task')->Where('checklistresource_id', $task->task_id)->get()) { foreach ($checklists as $checklist) { $new_checklist = $checklist->replicate(); $new_checklist->checklist_created = now(); $new_checklist->checklist_creatorid = auth()->id(); $new_checklist->checklist_clientid = $new_project->project_clientid; $new_checklist->checklist_status = 'pending'; $new_checklist->checklistresource_type = 'task'; $new_checklist->checklistresource_id = $new_task->task_id; $new_checklist->save(); } } } //copy attachements if ($this->data['copy_tasks_files'] == 'on') { if ($attachments = \App\Models\Attachment::Where('attachmentresource_type', 'task')->Where('attachmentresource_id', $task->task_id)->get()) { foreach ($attachments as $attachment) { //unique key $unique_key = Str::random(50); //directory $directory = Str::random(40); //paths $source = BASE_DIR . "/storage/files/" . $attachment->attachment_directory; $destination = BASE_DIR . "/storage/files/$directory"; //validate if (is_dir($source)) { //copy the database record $new_attachment = $attachment->replicate(); $new_attachment->attachment_creatorid = auth()->id(); $new_attachment->attachment_created = now(); $new_attachment->attachmentresource_id = $task->task_id; $new_attachment->attachment_clientid = $new_project->project_clientid; $new_attachment->attachment_uniqiueid = $directory; $new_attachment->attachment_directory = $directory; $new_attachment->attachmentresource_type = 'task'; $new_attachment->attachmentresource_id = $new_task->task_id; $new_attachment->save(); //copy folder File::copyDirectory($source, $destination); } } } } } } //copy dependencies if ($dependencies = \App\Models\TaskDependency::Where('tasksdependency_projectid', $old_project->project_id)->get()) { foreach ($dependencies as $dependency) { //find new dependant task if ($dependant_task = \App\Models\Task::Where('task_cloning_original_task_id', $dependency->tasksdependency_taskid)->first()) { //find new blocking task if ($blocking_task = \App\Models\Task::Where('task_cloning_original_task_id', $dependency->tasksdependency_blockerid)->first()) { $new_dependency = $dependency->replicate(); $new_dependency->tasksdependency_creatorid = auth()->id(); $new_dependency->tasksdependency_projectid = $new_project->project_id; $new_dependency->tasksdependency_clientid = $new_project->project_clientid; $new_dependency->tasksdependency_taskid = $dependant_task->task_id; $new_dependency->tasksdependency_blockerid = $blocking_task->task_id; $new_dependency->tasksdependency_status = 'active'; $new_dependency->save(); } } } } } } /** * copy invoices * @return bool */ private function copyInvoices($old_project, $new_project) { //we are copying if ($this->data['copy_invoices'] == 'on') { if ($invoices = \App\Models\Invoice::Where('bill_projectid', $old_project->project_id)->get()) { foreach ($invoices as $invoice) { //clone data $data = [ 'invoice_id' => $invoice->bill_invoiceid, 'client_id' => $new_project->project_clientid, 'project_id' => $new_project->project_id, 'invoice_date' => now(), //make invoice data today 'invoice_due_date' => \Carbon\Carbon::now()->addMonths(1)->format('Y-m-d'), //30 days from now 'return' => 'id', ]; //clone invoice if (!$this->cloneinvoicerepo->clone($data)) { Log::error("cloning the project's invoice failed - invoice id(" . $invoice->bill_invoiceid . ") failed", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__]); } } } } } /** * copy estimates * @return bool */ private function copyEstimates($old_project, $new_project) { //we are copying if ($this->data['copy_estimates'] == 'on') { if ($estimates = \App\Models\Estimate::Where('bill_projectid', $old_project->project_id)->get()) { foreach ($estimates as $estimate) { //clone data $data = [ 'estimate_id' => $estimate->bill_estimateid, 'client_id' => $new_project->project_clientid, 'project_id' => $new_project->project_id, 'estimate_date' => now(), //make estimate data today 'return' => 'id', ]; //clone estimate if (!$this->cloneestimaterepo->clone($data)) { Log::error("cloning the project's estimate failed - estimate id(" . $estimate->bill_estimateid . ") failed", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__]); } } } } } /** * copy folders * @return bool */ private function copyFolders($old_project, $new_project) { //get all the folders for the old project $folders = \App\Models\FileFolder::Where('filefolder_projectid', $old_project->project_id)->get(); //delete any folders that may have been created in the project controller steps \App\Models\FileFolder::Where('filefolder_projectid', $new_project->project_id)->delete(); //get the old folders $folder_mapping = []; //loop through and clone the folders foreach ($folders as $folder) { $new_folder = $folder->replicate(); $new_folder->filefolder_projectid = $new_project->project_id; $new_folder->save(); //map for allocating to files later $folder_mapping[$folder->filefolder_id] = $new_folder->filefolder_id; //set as default (sanity) if ($new_folder->filefolder_default == 'yes') { $folder_mapping['default'] = $new_folder->filefolder_id; } } return $folder_mapping; } /** * copy files * @return bool */ private function copyFiles($old_project, $new_project, $folder_mapping) { //we are copying if ($this->data['copy_files'] == 'on') { if ($files = \App\Models\File::Where('fileresource_type', 'project')->Where('fileresource_id', $old_project->project_id)->get()) { foreach ($files as $file) { //unique key $unique_key = Str::random(50); //directory $directory = Str::random(40); //paths $source = BASE_DIR . "/storage/files/" . $file->file_directory; $destination = BASE_DIR . "/storage/files/$directory"; //validate if (is_dir($source)) { //copy the database record $new_file = $file->replicate(); $new_file->file_creatorid = auth()->id(); $new_file->file_created = now(); $new_file->fileresource_id = $new_project->project_id; $new_file->file_clientid = $new_project->project_clientid; $new_file->file_uniqueid = $directory; $new_file->file_directory = $directory; $new_file->file_upload_unique_key = $unique_key; //set the folder $new_file->file_folderid = (isset($folder_mapping[$file->file_folderid])) ? $folder_mapping[$file->file_folderid] : $folder_mapping['default']; $new_file->save(); //set the folder //copy folder File::copyDirectory($source, $destination); } } } } } /** * copy tags * @return bool */ private function copyTags($old_project, $new_project) { //we are copying if ($tags = \App\Models\Tag::Where('tagresource_type', 'project')->Where('tagresource_id', $old_project->project_id)->get()) { foreach ($tags as $tag) { $new_tag = $tag->replicate(); $new_tag->tagresource_id = $new_project->project_id; $new_tag->save(); } } } /** * validate required data for cloning an project * @param array $data information payload * @return bool */ private function validateData($data = []) { //validation if (!isset($data['project_id']) || !isset($data['project_clientid']) || !isset($data['project_title']) || !isset($data['project_date_start'])) { Log::error("the supplied data is not valid", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'payload' => $data]); return false; } //project_id if (!is_numeric($data['project_id'])) { Log::error("the supplied project id is invalid", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'invoice_id' => $data['invoice_id']]); return false; } //project_clientid if (!is_numeric($data['project_clientid'])) { Log::error("the supplied client id is invalid", ['process' => '[CloneProjectRepository]', config('app.debug_ref'), 'function' => __function__, 'file' => basename(__FILE__), 'line' => __line__, 'path' => __file__, 'invoice_id' => $data['invoice_id']]); return false; } return true; } }
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.97 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002