| Server IP : 103.161.17.216 / Your IP : 216.73.216.1 Web Server : nginx/1.18.0 System : Linux tipsysaigoncharming 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 7.4.3-4ubuntu2.29 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/app.houseland.info/application/libraries/ |
Upload File : |
<?php
defined('BASEPATH') or exit('No direct script access allowed');
@ini_set('memory_limit', '512M');
@ini_set('max_execution_time', 360);
class App_bulk_pdf_export
{
/**
* The export config
*
* @var array
*/
protected $config = [];
/**
* Codeigniter instance
* @var object
*/
protected $ci;
/**
* This property is used to store the PDF
* @var object
*/
public $pdf_zip;
/**
* Can view based on the $type property
* @var boolean
*/
protected $can_view;
/**
* Export type
* Possible values: invoices, estimates, credit_notes, payments, proposal
* @var string
*/
protected $type;
/**
* Filter period from
* @var string
*/
protected $date_from;
/**
* Filter period to
* @var string
*/
protected $date_to;
/**
* Payments export payment mode
* @var string
*/
protected $payment_mode;
/**
* Status for estimates, invoices, credit notes, proposals
* @var mixed
*/
protected $status;
/**
* Required status parameter
* @var array
*/
protected $status_param_required = ['invoices', 'estimates', 'credit_notes', 'proposals'];
/**
* PDF tag
* @var string
*/
protected $pdf_tag = '';
/**
* Zip directory
* @var string
*/
protected $zip_dir;
/**
* Unique years for the data that is exporting
* Used to create the folders
* @var array
*/
protected $years = [];
/**
* Client ID if exporting for specific client
* @var mixed
*/
protected $client_id = null;
/**
* Client ID Column
* @var string
*/
protected $client_id_column = 'clientid';
/**
* Add the main folder contents in folder
* e.q. customer-name/YEAR/INVOICE.pdf
* @var string
*/
protected $in_folder = null;
/**
* Redirect user to specific url after error
* This parameter is required
* @var string
*/
protected $redirect_on_error = '';
public function __construct($config)
{
$this->type = $config['export_type'];
$this->config = $config;
if (!isset($config['redirect_on_error'])) {
show_error('You must set parameter "redirect_on_error"');
} else {
$this->redirect_on_error = $config['redirect_on_error'];
}
if (in_array($this->type, $this->status_param_required)
&& (!isset($config['status']) || isset($config['status']) && empty($config['status']))) {
show_error('You must set "status" config if you are exporting data for: ' . implode(', ', $this->status_param_required));
}
if (isset($config['status'])) {
$this->status = $config['status'];
}
if (isset($config['client_id'])) {
$this->set_client_id($config['client_id']);
}
if (isset($config['date_from']) && isset($config['date_to'])) {
$this->date_from = to_sql_date($config['date_from']);
$this->date_to = to_sql_date($config['date_to']);
}
if (isset($config['payment_mode'])) {
$this->payment_mode = $config['payment_mode'];
}
if (isset($config['tag']) && !empty($config['tag'])) {
$this->pdf_tag = $config['tag'];
}
$this->ci = &get_instance();
$this->ci->load->library('zip');
$this->can_view = has_permission($this->type, '', 'view');
if (!is_really_writable(TEMP_FOLDER)) {
show_error(TEMP_FOLDER . ' folder is not writable. You need to change the permissions to 0755');
}
$this->dir = TEMP_FOLDER . $this->type;
if (is_dir($this->dir)) {
$this->clear($this->dir);
}
mkdir($this->dir, 0755);
register_shutdown_function([$this, 'clear'], $this->dir);
}
/**
* The main function for exporting
* @return mixed
*/
public function export()
{
if (method_exists($this, $this->type)) {
$data = $this->{$this->type}();
} else {
if (!hooks()->has_filter('bulk_pdf_export_class')) {
show_error('No export type selected!');
} else {
$class = hooks()->apply_filters('bulk_pdf_export_class', null, $this->type);
if (!$class) {
show_error('No export type found!');
}
$class = new $class($this->config);
$class->export();
}
}
$this->zip();
}
/**
* Create payment export
* @return object
*/
protected function payments()
{
$this->ci->db->select('' . db_prefix() . 'invoicepaymentrecords.id as paymentid');
$this->ci->db->from(db_prefix() . 'invoicepaymentrecords');
$this->ci->db->join(db_prefix() . 'invoices', '' . db_prefix() . 'invoices.id = ' . db_prefix() . 'invoicepaymentrecords.invoiceid', 'left');
$this->ci->db->join(db_prefix() . 'clients', '' . db_prefix() . 'clients.userid = ' . db_prefix() . 'invoices.clientid', 'left');
if (!$this->can_view) {
$whereUser = '';
$whereUser .= '(invoiceid IN (SELECT id FROM ' . db_prefix() . 'invoices WHERE addedfrom=' . get_staff_user_id() . ')';
if (get_option('allow_staff_view_invoices_assigned') == 1) {
$whereUser .= ' OR invoiceid IN (SELECT id FROM ' . db_prefix() . 'invoices WHERE sale_agent=' . get_staff_user_id() . ')';
}
$whereUser .= ')';
$this->ci->db->where($whereUser);
}
if ($this->payment_mode) {
$this->ci->db->where('paymentmode', $this->payment_mode);
}
$this->ci->db->order_by($this->get_date_column(), 'desc');
$data = $this->finalize();
$this->ci->load->model('payments_model');
$this->ci->load->model('invoices_model');
foreach ($data as $payment) {
$payment_data = $this->ci->payments_model->get($payment['paymentid']);
$payment_data->invoice_data = $this->ci->invoices_model->get($payment_data->invoiceid);
$file_name = strtoupper(_l('payment'));
$file_name .= '-' . strtoupper($payment_data->paymentid) . '.pdf';
$pdf = payment_pdf($payment_data, $this->pdf_tag);
$this->save_to_dir($payment_data, $pdf, $file_name);
}
return $this;
}
/**
* Create payment export
* @return object
*/
protected function expenses()
{
$this->ci->load->model('payment_modes_model');
$payment_gateways = $this->ci->payment_modes_model->get_payment_gateways(true);
$this->ci->db->select('*,' . db_prefix() . 'expenses.id as id,' . db_prefix() . 'expenses_categories.name as category_name,' . db_prefix() . 'payment_modes.name as payment_mode_name,' . db_prefix() . 'taxes.name as tax_name, ' . db_prefix() . 'taxes.taxrate as taxrate,' . db_prefix() . 'taxes_2.name as tax_name2, ' . db_prefix() . 'taxes_2.taxrate as taxrate2, ' . db_prefix() . 'expenses.id as expenseid,' . db_prefix() . 'expenses.addedfrom as addedfrom');
$this->ci->db->from('expenses');
$this->ci->db->join(db_prefix() . 'clients', '' . db_prefix() . 'clients.userid = ' . db_prefix() . 'expenses.clientid', 'left');
$this->ci->db->join(db_prefix() . 'payment_modes', '' . db_prefix() . 'payment_modes.id = ' . db_prefix() . 'expenses.paymentmode', 'left');
$this->ci->db->join(db_prefix() . 'taxes', '' . db_prefix() . 'taxes.id = ' . db_prefix() . 'expenses.tax', 'left');
$this->ci->db->join(db_prefix() . 'taxes as ' . db_prefix() . 'taxes_2', '' . db_prefix() . 'taxes_2.id = ' . db_prefix() . 'expenses.tax2', 'left');
$this->ci->db->join(db_prefix() . 'expenses_categories', '' . db_prefix() . 'expenses_categories.id = ' . db_prefix() . 'expenses.category');
if (!$this->can_view) {
$this->ci->db->where('addedfrom', get_staff_user_id());
}
if ($this->payment_mode) {
$this->ci->db->where('paymentmode', $this->payment_mode);
}
$data = $this->finalize();
$expensesIds = array_column($data, 'expenseid');
$this->ci->db->select('file_name, filetype, staffid, rel_id')
->where_in('rel_id', $expensesIds)
->where('rel_type', 'expense');
$files = $this->ci->db->get('files')->result_array();
$projectIds = array_filter(array_column($data, 'project_id'));
$projects = [];
if (count($projectIds) > 0) {
$this->ci->db->select('id, name')->where_in('id', $projectIds);
$projects = $this->ci->db->get('projects')->result_array();
}
foreach ($data as $expense) {
$expense = array_to_object($expense);
$fileIndex = array_search($expense->expenseid, array_column($files, 'rel_id'));
if ($fileIndex !== false) {
$expense->attachment = $files[$fileIndex]['file_name'];
$expense->filetype = $files[$fileIndex]['filetype'];
$expense->attachment_added_from = $files[$fileIndex]['staffid'];
}
if ($expense->project_id) {
$expense->project_data = array_to_object(
$projects[array_search($expense->project_id, array_column($projects, 'id'))]
);
}
if (is_null($expense->payment_mode_name)) {
// is online payment mode
$expense->payment_mode_name = $payment_gateways[
array_search($expense->paymentmode, array_column($payment_gateways, 'id'))
] ?? null;
}
$expense->currency_data = get_currency($expense->currency);
$slug = sanitize_file_name(slug_it($expense->category_name . '_' . _d($expense->date)));
$pdf = app_pdf('expense', LIBSPATH . 'pdf/Expense_pdf', $expense, $this->pdf_tag);
$dir = $this->save_to_dir($expense, $pdf, $slug . '.pdf', isset($expense->attachment) ? $slug : '');
if (isset($expense->attachment)) {
xcopy(
get_upload_path_by_type('expense') . $expense->expenseid . '/' . $expense->attachment,
$dir . '/' . $expense->attachment
);
}
}
return $this;
}
/**
* Create estimates export
* @return object
*/
protected function estimates()
{
$noPermissionQuery = get_estimates_where_sql_for_staff(get_staff_user_id());
$this->ci->db->select('id');
$this->ci->db->from(db_prefix() . 'estimates');
if ($this->status != 'all') {
$this->ci->db->where('status', $this->status);
}
if (!$this->can_view) {
$this->ci->db->where($noPermissionQuery);
}
$this->ci->db->order_by($this->get_date_column(), 'desc');
$data = $this->finalize();
$this->ci->load->model('estimates_model');
foreach ($data as $estimate) {
$estimate = $this->ci->estimates_model->get($estimate['id']);
$pdf = estimate_pdf($estimate, $this->pdf_tag);
$this->save_to_dir($estimate, $pdf, strtoupper(slug_it(format_estimate_number($estimate->id))) . '.pdf');
}
return $this;
}
/**
* Create invoices export
* @return object
*/
protected function invoices()
{
$noPermissionQuery = get_invoices_where_sql_for_staff(get_staff_user_id());
$notSentQuery = 'sent=0 AND status NOT IN(2,5)' . (!$this->can_view ? ' AND (' . $noPermissionQuery . ')' : '');
$this->ci->db->select('id');
$this->ci->db->from(db_prefix() . 'invoices');
if ($this->status != 'all') {
if (is_numeric($this->status)) {
$this->ci->db->where('status', $this->status);
} else {
$this->ci->db->where($notSentQuery);
}
}
if (!$this->can_view) {
$this->ci->db->where($noPermissionQuery);
}
$this->ci->db->order_by($this->get_date_column(), 'desc');
$data = $this->finalize();
$this->ci->load->model('invoices_model');
foreach ($data as $invoice) {
$invoice = $this->ci->invoices_model->get($invoice['id']);
$pdf = invoice_pdf($invoice, $this->pdf_tag);
$this->save_to_dir($invoice, $pdf, strtoupper(slug_it(format_invoice_number($invoice->id))) . '.pdf');
}
return $this;
}
/**
* Create proposals export
* @return object
*/
public function proposals()
{
$noPermissionQuery = get_proposals_sql_where_staff(get_staff_user_id());
$this->ci->db->select('id');
$this->ci->db->from(db_prefix() . 'proposals');
if ($this->status != 'all') {
$this->ci->db->where('status', $this->status);
}
if (!$this->can_view) {
$this->ci->db->where($noPermissionQuery);
}
$this->ci->db->order_by($this->get_date_column(), 'desc');
$data = $this->finalize();
$this->ci->load->model('proposals_model');
foreach ($data as $proposal) {
$proposal = $this->ci->proposals_model->get($proposal['id']);
$pdf = proposal_pdf($proposal, $this->pdf_tag);
$this->save_to_dir($proposal, $pdf, strtoupper(format_proposal_number($proposal->id)) . '.pdf');
}
return $this;
}
/**
* Create credit notes export
* @return object
*/
public function credit_notes()
{
$this->ci->db->select('id');
$this->ci->db->from(db_prefix() . 'creditnotes');
if ($this->status != 'all') {
$this->ci->db->where('status', $this->status);
}
if (!$this->can_view) {
$this->ci->db->where('addedfrom', get_staff_user_id());
}
$this->ci->db->order_by($this->get_date_column(), 'desc');
$data = $this->finalize();
$this->ci->load->model('credit_notes_model');
foreach ($data as $credit_note) {
$credit_note = $this->ci->credit_notes_model->get($credit_note['id']);
$pdf = credit_note_pdf($credit_note, $this->pdf_tag);
$this->save_to_dir($credit_note, $pdf, strtoupper(slug_it(format_credit_note_number($credit_note->id))) . '.pdf');
}
return $this;
}
/**
* Sets the client id column
* @param string $column
*/
public function set_client_id_column($column)
{
$this->client_id_column = $column;
return $this;
}
/**
* Set client id
* @param mixed $client_id
*/
public function set_client_id($client_id)
{
$this->client_id = $client_id;
return $this;
}
/**
* Set export contents in folder
* @param string $folder
* @return object
*/
public function in_folder($folder)
{
$this->in_folder = $folder;
return $this;
}
/**
* Used to zip the data in the folder
* @return null
*/
protected function zip()
{
$this->ci->zip->read_dir($this->dir, false);
$this->ci->zip->download(slug_it(get_option('companyname')) . '-' . $this->type . '.zip');
$this->ci->zip->clear_data();
}
/**
* Save the PDF to the temporary directory to zip later
* @param object $object the data object, e.q. invoice, estimate
* @param mixed $pdf the actual PDF
* @param string file name for the PDF file
* @param string $folderName additional folder for storage
*
* @return string
*/
protected function save_to_dir($object, $pdf, $file_name, $folderName = '')
{
$dir = $this->dir . '/';
if ($this->in_folder) {
$dir .= $this->in_folder . '/';
}
$dateColumn = str_replace('`', '', $this->get_date_column());
if (strpos($dateColumn, '.') !== false) {
$dateColumn = strafter($dateColumn, '.');
}
if (!empty($object->{$dateColumn})) {
$dir .= date('Y', strtotime($object->{$dateColumn})) . '/';
}
if ($folderName !== '') {
$dir .= $folderName . '/';
if (!is_dir($dir)) {
mkdir($dir, 0755);
}
}
$path = $dir . $file_name;
$this->pdf_zip = $pdf;
$this->pdf_zip->Output($path, 'F');
return $dir;
}
/**
* Set date query for the data that is exported
*/
protected function set_date_query()
{
if ($this->date_from && $this->date_to) {
$date_field = $this->get_date_column();
if ($this->date_from == $this->date_to) {
$this->ci->db->where($date_field, $this->date_from);
} else {
$this->ci->db->where($date_field . ' BETWEEN "' . $this->date_from . '" AND "' . $this->date_to . '"');
}
}
}
/**
* Finalize all the query and necessary actions, used for common export options
* @return array
*/
protected function finalize()
{
$this->set_date_query();
if ($this->client_id) {
$this->ci->db->where($this->client_id_column, $this->client_id);
}
$data = $this->ci->db->get()->result_array();
$last_query = $this->ci->db->last_query();
$withoutSelect = strafter($last_query, 'FROM');
$yearSelectQuery = 'SELECT DISTINCT(YEAR(' . $this->get_date_column() . ')) as year FROM' . str_replace('ORDER BY ' . $this->get_date_column() . '', 'ORDER BY year', $withoutSelect);
$years = $this->ci->db->query($yearSelectQuery)->result_array();
if (count($data) == 0) {
set_alert('warning', _l('no_data_found_bulk_pdf_export'));
redirect($this->redirect_on_error);
}
$this->set_years_and_create_directories($years);
return $data;
}
/**
* Set years property and create years directories
* @param array $years
*/
protected function set_years_and_create_directories($years)
{
$flat = [];
$dir = $this->dir . '/';
if ($this->in_folder) {
$dir .= $this->in_folder . '/';
}
foreach ($years as $year) {
if (!is_dir($dir . $year['year'])) {
mkdir($dir . $year['year'], 0755, true);
}
$flat[] = $year['year'];
}
$this->years = $flat;
}
/**
* Get the date column for the exported feature
* @return string
*/
protected function get_date_column()
{
$date_field = '`date`';
// Column date is ambiguous in payments
if ($this->type == 'payments') {
$date_field = '`' . db_prefix() . 'invoicepaymentrecords`.`date`';
}
return $date_field;
}
/**
* Clear the temporary folder
* @param string $dir directory to clear
* @return null
*/
public function clear($dir)
{
if ($dir == TEMP_FOLDER) {
return true;
}
if (is_dir($dir)) {
delete_files($dir);
delete_dir($dir);
}
}
}