diff --git a/app/Config/Routes.php b/app/Config/Routes.php index efde3147..fc5ee993 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -11,10 +11,11 @@ $routes->options('(:any)', function() { }); $routes->group('sheet', function ($routes) { - $routes->get('(:any)', 'GoogleSheetController::editor/$1'); - $routes->get('(:any)/fetch', 'GoogleSheetController::fetch/$1'); - $routes->post('(:any)/save', 'GoogleSheetController::save/$1'); - $routes->get('(:any)/download', 'GoogleSheetController::download/$1'); + $routes->post('create', 'GoogleSheetController::create'); + $routes->get('(:segment)/fetch', 'GoogleSheetController::fetch/$1'); + $routes->post('(:segment)/save', 'GoogleSheetController::save/$1'); + $routes->get('(:segment)/download', 'GoogleSheetController::download/$1'); + $routes->get('(:segment)', 'GoogleSheetController::editor/$1'); }); diff --git a/app/Controllers/GoogleSheetController.php b/app/Controllers/GoogleSheetController.php index e51f81ab..cfdd98fc 100644 --- a/app/Controllers/GoogleSheetController.php +++ b/app/Controllers/GoogleSheetController.php @@ -6,6 +6,35 @@ use CodeIgniter\Controller; class GoogleSheetController extends Controller { protected GoogleSheetLib $sheetLib; + public $config = [ + + 'permissions' => [ + 'editors' => [ + 'vitvelz@gmail.com', 'velz1990@gmail.com','venkateshraman786@gmail.com' + // 'group:rfq-editors@company.com' + ], + 'viewers' => [], + ], + + 'protections' => [ + [ + 'range' => 'RFQ Page!B12:C12', + 'users' => [ //allowed users to edit this cell range + 'velz1990@gmail.com','vitvelz@gmail.com','firebase-adminsdk-mcdfe@nhance-ee8d1.iam.gserviceaccount.com' + ], + 'groups' => [] + ], + [ + 'range' => 'Claims Page!A1', + 'users' => [ + 'velz1990@gmail.com','venkateshraman786@gmail.com','firebase-adminsdk-mcdfe@nhance-ee8d1.iam.gserviceaccount.com' + ], + 'groups' => [] + ] + ], + + 'parentFolderId' => '19uySI-PSFQfFpZvMSnBtirXbwfCTXFBL', // RFQ folder +]; public function __construct() { @@ -23,10 +52,16 @@ class GoogleSheetController extends Controller /* ---------- FETCH ---------- */ public function fetch(string $sheetId) { - // $data = $this->sheetLib->read($sheetId); + $data = $this->sheetLib->read($sheetId); // print_rr($data);die; - // return $this->response->setJSON($data); - echo 'Hi'; + return $this->response->setJSON($data); + // echo 'Hi'; + } + + public function sample(string $sheetId) + { + echo $sheetId; + } /* ---------- SAVE ---------- */ @@ -63,4 +98,39 @@ class GoogleSheetController extends Controller ) ->setBody($content); } + + public function create() + { + try { + $config = config('RfqConfig'); + // #$lib = new RfqGoogleSheetLib(); + + // $templateId = $this->request->getPost('templateId'); + // if (!$templateId) { + // throw new \Exception('Template ID missing'); + // } + + // $newSheetId = $this->sheetLib->copyTemplate( + // $templateId, + // 'RFQ_' . date('Ymd_His'), + // $this->config['parentFolderId'] + // ); + $newSheetId = '1GXNDNXoWriClb5HCqPYd2GAY1T8aie_Hos0yAOoTaC0'; + // $this->sheetLib->applyPermissions($newSheetId, $this->config['permissions']); + $this->sheetLib->applyProtections($newSheetId, $this->config['protections']); + + return $this->response->setJSON([ + 'status' => 'success', + 'url' => $this->sheetLib->sheetUrl($newSheetId) + ]); + + } catch (\Throwable $e) { + return $this->response + ->setStatusCode(500) + ->setJSON([ + 'status' => 'error', + 'message' => $e->getMessage() + ]); + } + } } diff --git a/app/Controllers/TestingController.php b/app/Controllers/TestingController.php index 66957ea8..098c2105 100644 --- a/app/Controllers/TestingController.php +++ b/app/Controllers/TestingController.php @@ -999,7 +999,7 @@ class TestingController extends BaseController // 'dashboard' => 1 'dashboard' => $database_id ], - 'exp' => time() + (10 * 60) // 10 minutes + 'exp' => time() + (10 * 60), // 10 minutes ]; if(!empty($policy_id)){ diff --git a/app/Libraries/GoogleSheetLib.php b/app/Libraries/GoogleSheetLib.php index 5bdb9464..a04ab1e9 100644 --- a/app/Libraries/GoogleSheetLib.php +++ b/app/Libraries/GoogleSheetLib.php @@ -4,6 +4,7 @@ use Google_Client; use Google_Service_Sheets; use Google_Service_Drive; use Google_Service_Sheets_ValueRange; +use Google_Service_Sheets_BatchUpdateSpreadsheetRequest; class GoogleSheetLib { @@ -11,13 +12,14 @@ class GoogleSheetLib protected Google_Service_Sheets $sheets; protected Google_Service_Drive $drive; + public function __construct() { $this->client = new Google_Client(); // Service account JSON $this->client->setAuthConfig( - ROOTPATH . 'gdrive-demo-394007-5b1d856b0c5b.json' + ROOTPATH . 'nhance-ee8d1-e3c5269b1ec7.json' ); // IMPORTANT for service account @@ -32,11 +34,12 @@ class GoogleSheetLib // Init services $this->sheets = new Google_Service_Sheets($this->client); $this->drive = new Google_Service_Drive($this->client); + } /* ===================== READ ===================== */ - public function read(string $spreadsheetId, string $range = 'Sheet1') + public function read(string $spreadsheetId, string $range = 'RFQ Page') { $response = $this->sheets ->spreadsheets_values @@ -77,4 +80,205 @@ class GoogleSheetLib return $response->getBody()->getContents(); } + + + /* ================= COPY TEMPLATE ================= */ + + public function copyTemplate(string $templateId, string $name, string $folderId): string + { + $file = $this->drive->files->copy( + $templateId, + new \Google_Service_Drive_DriveFile([ + 'name' => $name, + 'parents' => [$folderId], + + ]),[ + 'supportsAllDrives' => true, + 'fields' => 'id, name, parents' + ] + ); + + return $file->id; + } + + /* ================= PERMISSIONS ================= */ + + public function applyPermissions(string $fileId, array $permissions) + { + foreach ($permissions['editors'] as $email) { + $this->createPermission($fileId, $email, 'writer'); + } + + foreach ($permissions['viewers'] as $email) { + $this->createPermission($fileId, $email, 'reader'); + } + } + + private function createPermission(string $fileId, string $email, string $role) + { + $type = str_starts_with($email, 'group:') ? 'group' : 'user'; + $email = str_replace('group:', '', $email); + + $this->drive->permissions->create( + $fileId, + new \Google_Service_Drive_Permission([ + 'type' => $type, + 'role' => $role, + 'emailAddress' => $email + ]), + ['sendNotificationEmail' => false,'supportsAllDrives' => true] + ); + } + + /* ================= PROTECTIONS ================= */ + + public function applyProtectionsold(string $spreadsheetId, array $ranges) + { + $spreadsheet = $this->sheets->spreadsheets->get($spreadsheetId); + $sheetId = $spreadsheet->getSheets()[0]->getProperties()->getSheetId(); + + $requests = []; + + foreach ($ranges as $range) { + [$sheetName, $a1] = explode('!', $range); + + $requests[] = [ + 'addProtectedRange' => [ + 'protectedRange' => [ + 'range' => [ + 'sheetId' => $sheetId + ], + 'warningOnly' => false + ] + ] + ]; + } + + $this->sheets->spreadsheets->batchUpdate( + $spreadsheetId, + new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([ + 'requests' => $requests + ]) + ); + } + + + public function applyProtections(string $spreadsheetId, array $protections) +{ + // Fetch spreadsheet metadata + $spreadsheet = $this->sheets->spreadsheets->get( + $spreadsheetId, + ['fields' => 'sheets(properties(sheetId,title,gridProperties))'] + ); + + // Map sheet names + $sheetMap = []; + foreach ($spreadsheet->getSheets() as $sheet) { + $props = $sheet->getProperties(); + $sheetMap[$props->getTitle()] = [ + 'sheetId' => $props->getSheetId(), + 'rowCount' => $props->getGridProperties()->getRowCount(), + 'colCount' => $props->getGridProperties()->getColumnCount(), + ]; + } + + $requests = []; + + foreach ($protections as $protection) { + + $rangeStr = $protection['range']; + + if (!str_contains($rangeStr, '!')) { + throw new \Exception("Invalid range format: {$rangeStr}"); + } + + [$sheetName, $a1] = explode('!', $rangeStr, 2); + + if (!isset($sheetMap[$sheetName])) { + throw new \Exception("Sheet not found: {$sheetName}"); + } + + $sheetMeta = $sheetMap[$sheetName]; + + $gridRange = $this->convertA1ToGridRange( + $a1, + $sheetMeta['sheetId'], + $sheetMeta['rowCount'], + $sheetMeta['colCount'] + ); + + $protectedRange = [ + 'range' => $gridRange, + 'description' => 'RFQ Protected Area', + 'warningOnly' => false, + 'editors' => [ + 'users' => $protection['users'] ?? [], + 'groups' => $protection['groups'] ?? [] + ] + ]; + + $requests[] = [ + 'addProtectedRange' => [ + 'protectedRange' => $protectedRange + ] + ]; + } + + if (!empty($requests)) { + $batch = new \Google_Service_Sheets_BatchUpdateSpreadsheetRequest([ + 'requests' => $requests + ]); + + $this->sheets->spreadsheets->batchUpdate($spreadsheetId, $batch); + } + + return true; +} + + /* ================= URL ================= */ + + public function sheetUrl(string $sheetId): string + { + return "https://docs.google.com/spreadsheets/d/{$sheetId}/edit"; + } + + + private function convertA1ToGridRange($a1, $sheetId, $maxRows, $maxCols) +{ + if (preg_match('/^([A-Z]+)(\d+)(?::([A-Z]+)(\d+))?$/i', $a1, $m)) { + + $startCol = $this->colToIndex($m[1]); + $startRow = intval($m[2]) - 1; + + if (!empty($m[3])) { + $endCol = $this->colToIndex($m[3]) + 1; + $endRow = intval($m[4]); + } else { + $endCol = $startCol + 1; + $endRow = $startRow + 1; + } + + return [ + 'sheetId' => $sheetId, + 'startRowIndex' => $startRow, + 'endRowIndex' => $endRow, + 'startColumnIndex' => $startCol, + 'endColumnIndex' => $endCol + ]; + } + + throw new \Exception("Unsupported A1 format: {$a1}"); +} + +private function colToIndex($letters) +{ + $letters = strtoupper($letters); + $index = 0; + for ($i = 0; $i < strlen($letters); $i++) { + $index = $index * 26 + (ord($letters[$i]) - 64); + } + return $index - 1; +} + + } diff --git a/app/Views/gsheet_editor.php b/app/Views/gsheet_editor.php index 93f40957..e3c9f316 100644 --- a/app/Views/gsheet_editor.php +++ b/app/Views/gsheet_editor.php @@ -16,6 +16,28 @@ + + +
+ +