File "class-app.php"
Full Path: /home/besayzoj/kayantransport.com/wp-admin-20241215172305/app/class-app.php
File size: 22.2 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace IGD;
defined( 'ABSPATH' ) || exit();
class App {
public static $instance = null;
public $client;
public $service;
public $account_id = null;
public $file_fields = 'capabilities(canEdit,canRename,canDelete,canShare,canTrash,canMoveItemWithinDrive),shared,starred,sharedWithMeTime,description,fileExtension,iconLink,id,driveId,imageMediaMetadata(height,rotation,width,time),mimeType,createdTime,modifiedTime,name,ownedByMe,parents,size,thumbnailLink,trashed,videoMediaMetadata(height,width,durationMillis),webContentLink,webViewLink,exportLinks,permissions(id,type,role,domain),copyRequiresWriterPermission,shortcutDetails,resourceKey';
public $list_fields = 'files(capabilities(canEdit,canRename,canDelete,canShare,canTrash,canMoveItemWithinDrive),shared,starred,sharedWithMeTime,description,fileExtension,iconLink,id,driveId,imageMediaMetadata(height,rotation,width,time),mimeType,createdTime,modifiedTime,name,ownedByMe,parents,size,thumbnailLink,trashed,videoMediaMetadata(height,width,durationMillis),webContentLink,webViewLink,exportLinks,permissions(id,type,role,domain),copyRequiresWriterPermission,shortcutDetails,resourceKey),nextPageToken';
public function __construct( $account_id = null ) {
if ( empty( $account_id ) ) {
$account = Account::instance()->get_active_account();
$account_id = ! empty( $account ) ? $account['id'] : $account_id;
}
$this->account_id = $account_id;
$this->client = Client::instance( $this->account_id )->get_client();
if ( ! class_exists( 'IGDGoogle_Service_Drive' ) ) {
require_once IGD_PATH . '/vendors/Google-sdk/src/Google/Service/Drive.php';
}
$this->service = new \IGDGoogle_Service_Drive( $this->client );
}
/**
* Get files from Google Drive
*
* @return array
*/
public function get_files( $args = [] ) {
$default_args = [
'folder' => [],
'sort' => [
'sortBy' => 'name',
'sortDirection' => 'asc'
],
'from_server' => false,
'orderBy' => "folder,name",
'filters' => [],
];
$args = wp_parse_args( $args, $default_args );
// Set root folder as default folder if no folder is set and no search query
if ( empty( $args['folder'] ) && ! $this->is_search_query( $args['q'] ) ) {
$args['folder'] = [
'id' => 'root',
'accountId' => $this->account_id,
'pageNumber' => 1,
];
}
$from_server = $args['from_server'];
$sort = $args['sort'];
$folder_id = ! empty( $args['folder'] ) ? $args['folder']['id'] : '';
$folder_account_id = ! empty( $args['folder']['accountId'] ) ? $args['folder']['accountId'] : $this->account_id;
if ( ! empty( $args['folder']['shortcutDetails'] ) ) {
$folder_id = $args['folder']['shortcutDetails']['targetId'];
}
$limit = ! empty( $args['limit'] ) ? $args['limit'] : 0;
$page_number = ! empty( $args['folder']['pageNumber'] ) ? $args['folder']['pageNumber'] : 1;
$start_index = $page_number > 0 ? ( $page_number - 1 ) * $limit : 0;
$filters = ! empty( $args['filters'] ) ? $args['filters'] : [];
$files_number_to_show = ! empty( $args['fileNumbers'] ) ? $args['fileNumbers'] : 0;
$data = [
'nextPageNumber' => 0,
];
if ( $from_server || ! igd_is_cached_folder( $folder_id, $folder_account_id ) ) {
if ( 'shared-drives' == $folder_id ) {
$files = $this->get_shared_drives( $folder_account_id );
} else {
$params = [
'fields' => $this->list_fields,
'pageSize' => 300,
'orderBy' => ! empty( $args['orderBy'] ) ? $args['orderBy'] : "",
'pageToken' => '',
'supportsAllDrives' => true,
'includeItemsFromAllDrives' => true,
'corpora' => 'allDrives',
];
if ( ! empty( $args['q'] ) ) {
$params['q'] = $args['q'];
} elseif ( 'computers' == $folder_id ) {
$params['q'] = "'me' in owners and mimeType='application/vnd.google-apps.folder' and trashed=false";
} elseif ( 'shared' == $folder_id ) {
$params['q'] = "sharedWithMe=true and trashed=false";
} elseif ( 'starred' == $folder_id ) {
$params['q'] = "starred=true and trashed=false";
} else {
$params['q'] = "trashed=false and '$folder_id' in parents";
}
$files = [];
do {
try {
$response = $this->service->files->listFiles( $params );
$page_token = ! empty( $response->getNextPageToken() ) ? $response->getNextPageToken() : '';
$params['pageToken'] = $page_token;
$items = $response->getFiles();
if ( ! empty( $items ) ) {
foreach ( $items as $item ) {
$files[] = igd_file_map( $item, $folder_account_id );
}
}
} catch ( \Exception $e ) {
$data['error'] = __( 'Server error', 'integrate-google-drive' ) . ' - ' . __( 'Couldn\'t connect to the Google drive API server.', 'integrate-google-drive' );
}
} while ( ! empty( $page_token ) );
}
if ( empty( $files ) ) {
$data['files'] = [];
return $data;
}
// Filter files
if ( igd_should_filter_files( $filters ) ) {
$files = array_values( array_filter(
$files,
function ( $item ) use ( $filters ) {
return igd_should_allow( $item, $filters );
}
) );
}
$files = $this->sort_and_insert_files( $files, $sort, $folder_id, $folder_account_id );
$count = count( $files );
$data['count'] = $count;
if ( ! empty( $limit ) && ! empty( $count ) ) {
if ( $count > $limit ) {
$files = array_slice( $files, $start_index, $limit );
}
}
} else {
// Get files from cache
list( $files, $count ) = Files::get( $folder_id, $folder_account_id, $sort, $start_index, $limit, $filters );
$data['count'] = $count;
}
// Check limit number
if ( ! empty( $limit ) && ! empty( $count ) ) {
if ( $count > $limit ) {
$data['nextPageNumber'] = $page_number + 1;
}
}
// Check max number of files to show
if ( $files_number_to_show > 0 ) {
if ( ( $page_number * $limit ) > $files_number_to_show ) {
$files_number_to_show = $files_number_to_show - ( ( $page_number - 1 ) * $limit );
$files = array_slice( $files, 0, $files_number_to_show );
$data['nextPageNumber'] = 0;
}
if ( $count > $files_number_to_show ) {
$data['count'] = $files_number_to_show;
}
}
$data['files'] = $files;
return $data;
}
public function sort_and_insert_files( $files, $sort, $folder_id, $folder_account_id ) {
// If folder is computers, filter files without parents and not shared
if ( 'computers' == $folder_id ) {
$files = array_filter( $files, function ( $file ) {
return empty( $file['parents'] ) && empty( $file['shared'] );
} );
}
// Sort files
$files = igd_sort_files( $files, $sort );
// Reformat shortcuts
$files = $this->reformat_shortcuts( $files );
// Insert files to database
if ( $folder_id ) {
Files::set( $files, $folder_id );
igd_update_cached_folders( $folder_id, $folder_account_id );
}
return $files;
}
/**
* Add iconLink, thumbnailLink and metaData to shortcuts
*
* @param $files
*
* @return mixed
*/
public function reformat_shortcuts( $files ) {
array_walk( $files, function ( &$file ) {
if ( ! empty( $file['shortcutDetails'] ) && ! igd_is_dir( $file ) ) {
$original_file = $this->get_file_by_id( $file['shortcutDetails']['targetId'] );
$file['iconLink'] = $original_file['iconLink'];
$file['thumbnailLink'] = $original_file['thumbnailLink'];
if ( ! empty( $original_file['metaData'] ) ) {
$file['metaData'] = $original_file['metaData'];
}
}
} );
return $files;
}
public function get_shared_drives( $folder_account_id = null ) {
$params = [
'fields' => 'kind,nextPageToken,drives(kind,id,name,capabilities,backgroundImageFile,backgroundImageLink,createdTime,hidden)',
'pageSize' => 100,
'pageToken' => '',
];
// Get all files in folder
$files = [];
do {
try {
$response = $this->service->drives->listDrives( $params );
$items = $response->getDrives();
$page_token = ! empty( $response->getNextPageToken() ) ? $response->getNextPageToken() : '';
$params['pageToken'] = $page_token;
if ( ! empty( $items ) ) {
foreach ( $items as $drive ) {
$file = igd_drive_map( $drive, $folder_account_id );
$files[] = $file;
}
}
} catch ( \Exception $ex ) {
error_log( $ex->getMessage() );
return [];
}
} while ( ! empty( $page_token ) );
return $files;
}
public function get_search_files( $keyword, $folders = [], $sort = [], $full_text_search = true ) {
$keyword = str_replace( [ "\'", '\"' ], [ "'", '"' ], $keyword );
$files = [];
$look_in_to = [];
if ( ! empty( $folders ) ) {
foreach ( $folders as $key => $folder ) {
if ( in_array( $folder['id'], [
'root',
'computers',
'shared-drives',
'shared',
'starred'
] ) ) {
continue;
}
// Skip if shared drives
if ( ! empty( $folder['parents'] ) && in_array( 'shared-drives', $folder['parents'] ) ) {
continue;
}
// Skip if not a folder
if ( ! igd_is_dir( $folder ) ) {
continue;
}
// Get target ID from shortcut folder
if ( ! empty( $folder['shortcutDetails'] ) ) {
$folder_id = $folder['shortcutDetails']['targetId'];
$folder = $this->get_file_by_id( $folder_id );
$folders[ $key ] = $folder;
}
$look_in_to[] = $folder['id'];
$child_folders = igd_get_all_child_folders( $folder );
$child_folders_ids = wp_list_pluck( $child_folders, 'id' );
$look_in_to = array_merge( $look_in_to, $child_folders_ids );
}
}
// Filter files if files parents is in look_in_to
$args = array(
'fields' => $this->list_fields,
'pageSize' => 1000,
'orderBy' => "",
'q' => "fullText contains '{$keyword}' and trashed = false",
'from_server' => true,
'sort' => [
'sortBy' => 'name',
'sortDirection' => 'asc'
],
);
if ( ! empty( $sort ) ) {
$args['sort'] = $sort;
}
if ( ! $full_text_search ) {
$args['q'] = "name contains '{$keyword}' and trashed = false";
$args['orderBy'] = 'folder,name'; // Order by not supported in fullText search
}
$data = $this->get_files( $args );
$files = array_merge( $files, $data['files'] ?? [] );
if ( ! empty( $look_in_to ) ) {
$files = array_filter( $files, function ( $file ) use ( $look_in_to ) {
return ! empty( $file['parents'] ) && in_array( $file['parents'][0], $look_in_to );
} );
}
// Insert log
do_action( 'igd_insert_log', 'search', $keyword, $this->account_id );
return array_values( $files );
}
public function is_search_query( $args ) {
if ( empty( $args['q'] ) ) {
return false;
}
$keyword = $args['q'];
if ( strpos( $keyword, 'fullText contains' ) !== false ) {
return true;
}
if ( strpos( $keyword, 'name contains' ) !== false ) {
return true;
}
return false;
}
/**
* Get file item by file id
*
* @param $id
*
* @return array|false|mixed|void
*/
public function get_file_by_id( $id, $from_server = false ) {
// Get cache file
if ( ! $from_server ) {
$file = Files::get_file_by_id( $id );
}
// If no cache file then get file from server
if ( empty( $file ) || $from_server ) {
try {
$item = $this->service->files->get( $id, [
'supportsAllDrives' => true,
'fields' => $this->file_fields,
] );
// Skip errors if folder is not found
if ( ! is_object( $item ) || ! method_exists( $item, 'getId' ) || $item->trashed ) {
do_action( 'igd_trash_detected', $id, $this->account_id );
return false;
}
$file = igd_file_map( $item, $this->account_id );
// Add file to cache
Files::add_file( $file );
} catch ( \Exception $e ) {
error_log( 'IGD SDK ERROR - GET FILE BY ID : ' . $e->getMessage() );
return false;
}
}
return $file;
}
public function get_file_by_name( $name, $parent_folder = '', $from_server = false ) {
$folder_id = isset( $parent_folder['id'] ) ? $parent_folder['id'] : $parent_folder;
$file = ! $from_server ? Files::get_file_by_name( $name, $folder_id ) : null;
if ( empty( $file ) || $from_server ) {
$args = [
'fields' => $this->list_fields,
'pageSize' => 1,
'q' => "name = '{$name}' and trashed = false ",
];
if ( ! empty( $folder_id ) ) {
$args['q'] .= " and '{$folder_id}' in parents";
}
try {
$response = $this->service->files->listFiles( $args );
if ( ! method_exists( $response, 'getFiles' ) ) {
return false;
}
$files = $response->getFiles();
} catch ( \Exception $e ) {
return false;
}
if ( empty( $files ) ) {
return false;
}
$item = $files[0];
// Check if file is in trash
if ( $item->trashed ) {
do_action( 'igd_trash_detected', $item->id, $this->account_id );
return false;
}
$file = igd_file_map( $item, $this->account_id );
Files::add_file( $file );
}
return $file;
}
/**
* Create new folder
*
* @param $folder_name
* @param $parent_folder array | string
*
* @return array
*/
public function new_folder( $folder_name, $parent_id ) {
if ( empty( $parent_id ) ) {
$parent_id = 'root';
}
$params = [
'fields' => $this->file_fields,
'supportsAllDrives' => true,
];
$request = $this->getService()->files->create( new \IGDGoogle_Service_Drive_DriveFile( [
'name' => $folder_name,
'parents' => [ $parent_id ],
'mimeType' => 'application/vnd.google-apps.folder'
] ), $params );
// add new folder to cache
$item = igd_file_map( $request, $this->account_id );
Files::add_file( $item, $parent_id );
// Insert log
do_action( 'igd_insert_log', 'folder', $item['id'], $this->account_id );
return $item;
}
/**
* Move Files
*
* @param $file_ids
* @param $new_parent_id
*
* @return string|void
*/
public function move_file( $file_ids, $new_parent_id = null ) {
if ( empty( $new_parent_id ) ) {
$new_parent_id = 'root';
}
try {
$emptyFileMetadata = new \IGDGoogle_Service_Drive_DriveFile();
if ( ! empty( $file_ids ) ) {
foreach ( $file_ids as $file_id ) {
// Retrieve the existing parents to remove
$file = $this->get_file_by_id( $file_id );
$previousParents = join( ',', $file['parents'] );
// Move the file to the new folder
$file = $this->service->files->update( $file_id, $emptyFileMetadata, array(
'addParents' => $new_parent_id,
'removeParents' => $previousParents,
'fields' => $this->file_fields,
) );
//Update cached file
if ( method_exists( $file, 'getId' ) ) {
Files::update_file(
[
'parent_id' => $new_parent_id,
'data' => serialize( igd_file_map( $file, $this->account_id ) ),
],
[ 'id' => $file_id ]
);
}
// Insert log
do_action( 'igd_insert_log', 'move', $file_id, $this->account_id );
}
}
} catch ( \Exception $e ) {
return "An error occurred: " . $e->getMessage();
}
}
/**
* Rename file
*
* @param $name
* @param $file_id
*
* @return \IGDGoogle_Http_Request|\IGDGoogle_Service_Drive_DriveFile|string
*/
public function rename( $name, $file_id ) {
try {
$file_meta_data = new \IGDGoogle_Service_Drive_DriveFile();
$file_meta_data->setName( $name );
// Move the file to the new folder
$file = $this->service->files->update( $file_id, $file_meta_data, array(
'fields' => $this->file_fields,
) );
// Update cached file
if ( method_exists( $file, 'getId' ) ) {
Files::update_file( [
'name' => $name,
'data' => serialize( igd_file_map( $file, $this->account_id ) ),
], [ 'id' => $file_id ] );
}
// Insert log
do_action( 'igd_insert_log', 'rename', $file_id, $this->account_id );
return $file;
} catch ( \Exception $e ) {
return "An error occurred: " . $e->getMessage();
}
}
/**
* Rename multiple files on form submit
*
* @param $files
*
* @return array|string
*/
public function rename_files( $files ) {
try {
$this->client->setUseBatch( true );
$batch = new \IGDGoogle_Http_Batch( $this->client );
foreach ( $files as $file ) {
$name = $file['name'];
$file_id = $file['id'];
$file_met_data = new \IGDGoogle_Service_Drive_DriveFile();
$file_met_data->setName( $name );
// Move the file to the new folder
$batch->add( $this->service->files->update( $file_id, $file_met_data, array( 'fields' => $this->file_fields, ) ) );
}
$batch_result = $batch->execute();
$this->client->setUseBatch( false );
$renamed_files = [];
foreach ( $batch_result as $file ) {
if ( method_exists( $file, 'getId' ) ) {
$file = igd_file_map( $file, $this->account_id );
Files::update_file( [
'name' => $file['name'],
'data' => serialize( $file ),
], [ 'id' => $file['id'] ] );
$renamed_files[] = $file;
}
}
return $renamed_files;
} catch ( \Exception $e ) {
return "An error occurred: " . $e->getMessage();
}
}
public function update_description( $file_id, $description ) {
try {
$file = new \IGDGoogle_Service_Drive_DriveFile();
$file->setDescription( $description );
// Move the file to the new folder
$update_file = $this->service->files->update( $file_id, $file, array(
'fields' => $this->file_fields,
) );
// Insert log
do_action( 'igd_insert_log', 'description', $file_id, $this->account_id );
// Update cached file
if ( $update_file->getId() ) {
$update_file = igd_file_map( $update_file, $this->account_id );
Files::update_file( [ 'data' => serialize( $update_file ) ], [ 'id' => $file_id ] );
return $update_file;
}
} catch ( \Exception $e ) {
return "An error occurred: " . $e->getMessage();
}
}
public function copy( $files, $parent_id = null ) {
try {
$this->client->setUseBatch( true );
$batch = new \IGDGoogle_Http_Batch( $this->client );
$file_meta_data = new \IGDGoogle_Service_Drive_DriveFile();
foreach ( $files as $file ) {
$file_meta_data->setName( 'Copy of ' . $file['name'] );
if ( ! empty( $parent_id ) ) {
$file_meta_data->setParents( [ $parent_id ] );
}
$batch->add( $this->service->files->copy( $file['id'], $file_meta_data, [ 'fields' => $this->file_fields ] ) );
}
$batch_result = $batch->execute();
$copied_files = [];
foreach ( $batch_result as $file ) {
if ( method_exists( $file, 'getId' ) ) {
$file = igd_file_map( $file, $this->account_id );
Files::add_file( $file );
$copied_files[] = $file;
// Insert log
do_action( 'igd_insert_log', 'copy', $file['id'], $this->account_id );
}
}
$this->client->setUseBatch( false );
return $copied_files;
} catch ( \Exception $e ) {
$this->client->setUseBatch( false );
return "An error occurred: " . $e->getMessage();
}
}
public function copy_folder( $folder, $parent_id ) {
if ( empty( $folder ) || empty( $parent_id ) ) {
return false;
}
$args = [
'folder' => $folder,
];
$data = $this->get_files( $args );
$files = ! empty( $data['files'] ) ? $data['files'] : [];
if ( empty( $files ) ) {
return false;
}
$batch = new \IGDGoogle_Http_Batch( $this->client );
$batch_requests = 0;
$this->client->setUseBatch( true );
foreach ( $files as $file ) {
if ( igd_is_dir( $file ) ) {
//Create new folder in parent folder
$new_folder = new \IGDGoogle_Service_Drive_DriveFile();
$new_folder->setName( $file['name'] );
$new_folder->setMimeType( 'application/vnd.google-apps.folder' );
$new_folder->setParents( [ $parent_id ] );
$batch->add( $this->service->files->create( $new_folder, [
'fields' => $this->file_fields,
'supportsAllDrives' => true
] ), $file['id'] );
} else {
// Copy file to new folder
$new_file = new \IGDGoogle_Service_Drive_DriveFile();
$new_file->setName( $file['name'] );
$new_file->setParents( [ $parent_id ] );
$batch->add( $this->service->files->copy( $file['id'], $new_file, [
'fields' => $this->file_fields,
'supportsAllDrives' => true
] ), $file['id'] );
}
++ $batch_requests;
}
// Execute the Batch Call
try {
usleep( 20000 * $batch_requests );
@set_time_limit( 30 );
$batch_result = $batch->execute();
} catch ( \Exception $ex ) {
error_log( '[Integrate Google Drive Message]: ' . sprintf( 'API Error on line %s: %s', __LINE__, $ex->getMessage() ) );
return false;
}
$this->client->setUseBatch( false );
foreach ( $batch_result as $key => $file ) {
$file = igd_file_map( $file, $this->account_id );
Files::add_file( $file );
if ( igd_is_dir( $file ) ) {
$original_id = str_replace( 'response-', '', $key );
$original_file = array_filter( $files, function ( $item ) use ( $original_id ) {
return $item['id'] == $original_id;
} );
$original_file = array_shift( $original_file );
$new_id = $file['id'];
$this->copy_folder( $original_file, $new_id );
}
}
}
/**
* Delete files
*
* @param $file_ids
*
* @return string|void
*/
public function delete( $file_ids ) {
try {
$this->client->setUseBatch( true );
$batch = new \IGDGoogle_Http_Batch( $this->client );
foreach ( $file_ids as $file_id ) {
Files::delete( [ 'id' => $file_id ] );
do_action( 'igd_insert_log', 'delete', $file_id, $this->account_id );
do_action( 'igd_delete_file', $file_id, $this->account_id );
$meta_data = new \IGDGoogle_Service_Drive_DriveFile( [
'trashed' => true,
] );
$batch->add( $this->service->files->update( $file_id, $meta_data ) );
}
$batch->execute();
$this->client->setUseBatch( false );
} catch ( \Exception $e ) {
return "An error occurred: " . $e->getMessage();
}
}
/**
* Google Drive Service Instance
*
* @return \IGDGoogle_Service_Drive
*/
public function getService() {
return $this->service;
}
/**
* Render File Browser
*/
public static function view() { ?>
<div id="igd-app" class="igd-app"></div>
<?php
}
public static function instance( $account_id = null ) {
if ( is_null( self::$instance ) || self::$instance->account_id != $account_id ) {
self::$instance = new self( $account_id );
}
return self::$instance;
}
}