mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 07:57:33 -05:00 
			
		
		
		
	Fixes for casting pdf_variables
This commit is contained in:
		
							parent
							
								
									eec9fa4dbc
								
							
						
					
					
						commit
						2fe91b5707
					
				@ -27,21 +27,58 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public PdfService $service;
 | 
					    public PdfService $service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * an array of sections to be injected into the template
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public array $sections = [];
 | 
					    public array $sections = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param PdfService $service 
 | 
				
			||||||
 | 
					     * @return void 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function __construct(PdfService $service)
 | 
					    public function __construct(PdfService $service)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->service = $service;
 | 
					        $this->service = $service;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function build()
 | 
					    /**
 | 
				
			||||||
 | 
					     * Builds the template sections
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function build(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->getTemplate()
 | 
					        $this->getTemplate()
 | 
				
			||||||
             ->buildSections();
 | 
					             ->buildSections()
 | 
				
			||||||
 | 
					             ->getEmptyElements()
 | 
				
			||||||
 | 
					             ->updateElementProperties()
 | 
				
			||||||
 | 
					             ->updateVariables();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     /**
 | 
				
			||||||
 | 
					     * Final method to get compiled HTML.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param bool $final @deprecated // is it? i still see it being called elsewhere
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getCompiledHTML($final = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $html = $this->document->saveHTML();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return str_replace('%24', '$', $html);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generate the template
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getTemplate() :self
 | 
					    private function getTemplate() :self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -56,6 +93,12 @@ class PdfBuilder
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates product entity sections
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getProductSections(): self
 | 
					    private function getProductSections(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
@ -69,6 +112,12 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates delivery note sections
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getDeliveryNoteSections(): self
 | 
					    private function getDeliveryNoteSections(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,6 +143,12 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates statement sections
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getStatementSections(): self
 | 
					    private function getStatementSections(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -130,7 +185,12 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Parent method for building invoice table totals
 | 
				
			||||||
 | 
					     * for statements.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function statementInvoiceTableTotals(): array
 | 
					    public function statementInvoiceTableTotals(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,6 +244,12 @@ class PdfBuilder
 | 
				
			|||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the statement payments table
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function statementPaymentTableTotals(): array
 | 
					    public function statementPaymentTableTotals(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (is_null($this->service->options['payments']) || !$this->service->options['payments']->first()) {
 | 
					        if (is_null($this->service->options['payments']) || !$this->service->options['payments']->first()) {
 | 
				
			||||||
@ -201,6 +267,12 @@ class PdfBuilder
 | 
				
			|||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the statement aging table
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function statementAgingTable(): array
 | 
					    public function statementAgingTable(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -224,6 +296,12 @@ class PdfBuilder
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the purchase order sections
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getPurchaseOrderSections(): self
 | 
					    private function getPurchaseOrderSections(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -245,17 +323,24 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the generic section which apply
 | 
				
			||||||
 | 
					     * across all design templates
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function genericSectionBuilder(): self
 | 
					    private function genericSectionBuilder(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->sections[] = [
 | 
					        $this->sections[] = [
 | 
				
			||||||
            'company-details' => [
 | 
					            'company-details' => [
 | 
				
			||||||
                'id' => 'company-details',
 | 
					                'id' => 'company-details',
 | 
				
			||||||
                'elements' => $this->service->companyDetails(),
 | 
					                'elements' => $this->companyDetails(),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            'company-address' => [
 | 
					            'company-address' => [
 | 
				
			||||||
                'id' => 'company-address',
 | 
					                'id' => 'company-address',
 | 
				
			||||||
                'elements' => $this->service->companyAddress(),
 | 
					                'elements' => $this->companyAddress(),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            'footer-elements' => [
 | 
					            'footer-elements' => [
 | 
				
			||||||
                'id' => 'footer',
 | 
					                'id' => 'footer',
 | 
				
			||||||
@ -268,6 +353,12 @@ class PdfBuilder
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the invoices table for statements
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function statementInvoiceTable(): array
 | 
					    public function statementInvoiceTable(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -277,10 +368,10 @@ class PdfBuilder
 | 
				
			|||||||
            $element = ['element' => 'tr', 'elements' => []];
 | 
					            $element = ['element' => 'tr', 'elements' => []];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $element['elements'][] = ['element' => 'td', 'content' => $invoice->number];
 | 
					            $element['elements'][] = ['element' => 'td', 'content' => $invoice->number];
 | 
				
			||||||
            $element['elements'][] = ['element' => 'td', 'content' => $this->translateDate($invoice->date, $this->client->date_format(), $this->client->locale()) ?: ' '];
 | 
					            $element['elements'][] = ['element' => 'td', 'content' => $this->translateDate($invoice->date, $this->client->date_format(), $this->service->config->client->locale()) ?: ' '];
 | 
				
			||||||
            $element['elements'][] = ['element' => 'td', 'content' => $this->translateDate($invoice->due_date, $this->client->date_format(), $this->client->locale()) ?: ' '];
 | 
					            $element['elements'][] = ['element' => 'td', 'content' => $this->translateDate($invoice->due_date, $this->client->date_format(), $this->service->config->client->locale()) ?: ' '];
 | 
				
			||||||
            $element['elements'][] = ['element' => 'td', 'content' => Number::formatMoney($invoice->amount, $this->client) ?: ' '];
 | 
					            $element['elements'][] = ['element' => 'td', 'content' => Number::formatMoney($invoice->amount, $this->service->config->client) ?: ' '];
 | 
				
			||||||
            $element['elements'][] = ['element' => 'td', 'content' => Number::formatMoney($invoice->balance, $this->client) ?: ' '];
 | 
					            $element['elements'][] = ['element' => 'td', 'content' => Number::formatMoney($invoice->balance, $this->service->config->client) ?: ' '];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $tbody[] = $element;
 | 
					            $tbody[] = $element;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -297,6 +388,7 @@ class PdfBuilder
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param string $type "$product" or "$task"
 | 
					     * @param string $type "$product" or "$task"
 | 
				
			||||||
     * @return array
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function buildTableBody(string $type): array
 | 
					    public function buildTableBody(string $type): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -369,7 +461,7 @@ class PdfBuilder
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $_type = Str::startsWith($type, '$') ? ltrim($type, '$') : $type;
 | 
					                $_type = Str::startsWith($type, '$') ? ltrim($type, '$') : $type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                foreach ($this->context['pdf_variables']["{$_type}_columns"] as $key => $cell) {
 | 
					                foreach ($this->service->config->pdf_variables["{$_type}_columns"] as $key => $cell) {
 | 
				
			||||||
                    // We want to keep aliases like these:
 | 
					                    // We want to keep aliases like these:
 | 
				
			||||||
                    // $task.cost => $task.rate
 | 
					                    // $task.cost => $task.rate
 | 
				
			||||||
                    // $task.quantity => $task.hours
 | 
					                    // $task.quantity => $task.hours
 | 
				
			||||||
@ -404,8 +496,6 @@ class PdfBuilder
 | 
				
			|||||||
        return $elements;
 | 
					        return $elements;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Formats the line items for display.
 | 
					     * Formats the line items for display.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -420,9 +510,6 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $data = [];
 | 
					        $data = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! is_array($items)) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $locale_info = localeconv();
 | 
					        $locale_info = localeconv();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->service->config->entity_currency = $this->service->config->currency;
 | 
					        $this->service->config->entity_currency = $this->service->config->currency;
 | 
				
			||||||
@ -448,8 +535,8 @@ class PdfBuilder
 | 
				
			|||||||
            $data[$key][$table_type.'.service'] = is_null(optional($item)->service) ? $item->product_key : $item->service;
 | 
					            $data[$key][$table_type.'.service'] = is_null(optional($item)->service) ? $item->product_key : $item->service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $currentDateTime = null;
 | 
					            $currentDateTime = null;
 | 
				
			||||||
            if (isset($this->entity->next_send_date)) {
 | 
					            if (isset($this->service->config->entity->next_send_date)) {
 | 
				
			||||||
                $currentDateTime = Carbon::parse($this->entity->next_send_date);
 | 
					                $currentDateTime = Carbon::parse($this->service->config->entity->next_send_date);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $this->service->config->currency_entity, $currentDateTime);
 | 
					            $data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $this->service->config->currency_entity, $currentDateTime);
 | 
				
			||||||
@ -531,6 +618,7 @@ class PdfBuilder
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param string $type "product" or "task"
 | 
					     * @param string $type "product" or "task"
 | 
				
			||||||
     * @return array
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function buildTableHeader(string $type): array
 | 
					    public function buildTableHeader(string $type): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -546,7 +634,7 @@ class PdfBuilder
 | 
				
			|||||||
            '$task.rate' => '$task.cost',
 | 
					            '$task.rate' => '$task.cost',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($this->context['pdf_variables']["{$type}_columns"] as $column) {
 | 
					        foreach ($this->service->config->pdf_variables["{$type}_columns"] as $column) {
 | 
				
			||||||
            if (array_key_exists($column, $aliases)) {
 | 
					            if (array_key_exists($column, $aliases)) {
 | 
				
			||||||
                $elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->service->config->settings_object->getSetting('hide_empty_columns_on_pdf')]];
 | 
					                $elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->service->config->settings_object->getSetting('hide_empty_columns_on_pdf')]];
 | 
				
			||||||
            } elseif ($column == '$product.discount' && !$this->service->company->enable_product_discount) {
 | 
					            } elseif ($column == '$product.discount' && !$this->service->company->enable_product_discount) {
 | 
				
			||||||
@ -623,7 +711,13 @@ class PdfBuilder
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the javascript block for 
 | 
				
			||||||
 | 
					     * hiding elements which need to be hidden
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function sharedFooterElements(): array
 | 
					    public function sharedFooterElements(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // We want to show headers for statements, no exceptions.
 | 
					        // We want to show headers for statements, no exceptions.
 | 
				
			||||||
@ -647,6 +741,13 @@ class PdfBuilder
 | 
				
			|||||||
        ]];
 | 
					        ]];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the totals table for 
 | 
				
			||||||
 | 
					     * the product type entities
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getProductTotals(): self
 | 
					    private function getProductTotals(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -660,6 +761,15 @@ class PdfBuilder
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the entity details for
 | 
				
			||||||
 | 
					     * Credits
 | 
				
			||||||
 | 
					     * Quotes
 | 
				
			||||||
 | 
					     * Invoices
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function getProductEntityDetails(): self
 | 
					    private function getProductEntityDetails(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -701,7 +811,12 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Parent entry point when building sections of the design content */
 | 
					    /**
 | 
				
			||||||
 | 
					     * Parent entry point when building sections of the design content
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return self
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function buildSections() :self
 | 
					    private function buildSections() :self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -714,6 +829,12 @@ class PdfBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates the table totals for statements
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function statementTableTotals(): array
 | 
					    private function statementTableTotals(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
@ -725,6 +846,14 @@ class PdfBuilder
 | 
				
			|||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Performs a variable check to ensure
 | 
				
			||||||
 | 
					     * the variable exists
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param  string $variables
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function entityVariableCheck(string $variable): bool
 | 
					    public function entityVariableCheck(string $variable): bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // When it comes to invoice balance, we'll always show it.
 | 
					        // When it comes to invoice balance, we'll always show it.
 | 
				
			||||||
@ -747,11 +876,11 @@ class PdfBuilder
 | 
				
			|||||||
            $_variable = $aliases[$variable];
 | 
					            $_variable = $aliases[$variable];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (is_null($this->entity->{$_variable})) {
 | 
					        if (is_null($this->service->config->entity->{$_variable})) {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (empty($this->entity->{$_variable})) {
 | 
					        if (empty($this->service->config->entity->{$_variable})) {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -759,11 +888,17 @@ class PdfBuilder
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //First pass done, need a second pass to abstract this content completely.
 | 
					    //First pass done, need a second pass to abstract this content completely.
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Builds the table totals for all entities, we'll want to split this
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function getTableTotals() :array
 | 
					    public function getTableTotals() :array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //need to see where we don't pass all these particular variables. try and refactor thisout
 | 
					        //need to see where we don't pass all these particular variables. try and refactor thisout
 | 
				
			||||||
        $_variables = array_key_exists('variables', $this->context)
 | 
					        $_variables = array_key_exists('variables', $this->service->options)
 | 
				
			||||||
            ? $this->context['variables']
 | 
					            ? $this->service->options['variables']
 | 
				
			||||||
            : ['values' => ['$this->service->config->entity.public_notes' => $this->service->config->entity->public_notes, '$this->service->config->entity.terms' => $this->service->config->entity->terms, '$this->service->config->entity_footer' => $this->service->config->entity->footer], 'labels' => []];
 | 
					            : ['values' => ['$this->service->config->entity.public_notes' => $this->service->config->entity->public_notes, '$this->service->config->entity.terms' => $this->service->config->entity->terms, '$this->service->config->entity_footer' => $this->service->config->entity->footer], 'labels' => []];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $variables = $this->service->config->pdf_variables['total_columns'];
 | 
					        $variables = $this->service->config->pdf_variables['total_columns'];
 | 
				
			||||||
@ -1287,25 +1422,169 @@ class PdfBuilder
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Dom Traversal
 | 
				
			||||||
 | 
					    ///////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getSectionNode(string $selector)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->document->getElementById($selector);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function updateElementProperties() :self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($this->sections as $element) {
 | 
				
			||||||
 | 
					            if (isset($element['tag'])) {
 | 
				
			||||||
 | 
					                $node = $this->document->getElementsByTagName($element['tag'])->item(0);
 | 
				
			||||||
 | 
					            } elseif (! is_null($this->document->getElementById($element['id']))) {
 | 
				
			||||||
 | 
					                $node = $this->document->getElementById($element['id']);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 //         if (isset($this->data['template']) && isset($this->data['variables'])) {
 | 
					            if (isset($element['properties'])) {
 | 
				
			||||||
 //            $this->getEmptyElements($this->data['template'], $this->data['variables']);
 | 
					                foreach ($element['properties'] as $property => $value) {
 | 
				
			||||||
 //        }
 | 
					                    $this->updateElementProperty($node, $property, $value);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 //        if (isset($this->data['template'])) {
 | 
					            if (isset($element['elements'])) {
 | 
				
			||||||
 //            $this->updateElementProperties($this->data['template']);
 | 
					                $this->createElementContent($node, $element['elements']);
 | 
				
			||||||
 //        }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 //        if (isset($this->data['variables'])) {
 | 
					        return $this;
 | 
				
			||||||
 //            $this->updateVariables($this->data['variables']);
 | 
					    }
 | 
				
			||||||
 //        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 //        return $this;
 | 
					    public function updateElementProperty($element, string $attribute, ?string $value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // We have exception for "hidden" property.
 | 
				
			||||||
 | 
					        // hidden="true" or hidden="false" will both hide the element,
 | 
				
			||||||
 | 
					        // that's why we have to create an exception here for this rule.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($attribute == 'hidden' && ($value == false || $value == 'false')) {
 | 
				
			||||||
 | 
					            return $element;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $element->setAttribute($attribute, $value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($element->getAttribute($attribute) === $value) {
 | 
				
			||||||
 | 
					            return $element;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $element;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function createElementContent($element, $children) :self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($children as $child) {
 | 
				
			||||||
 | 
					            $contains_html = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($child['element'] !== 'script') {
 | 
				
			||||||
 | 
					                if (array_key_exists('process_markdown', $this->data) && array_key_exists('content', $child) && $this->data['process_markdown']) {
 | 
				
			||||||
 | 
					                    $child['content'] = str_replace('<br>', "\r", $child['content']);
 | 
				
			||||||
 | 
					                    $child['content'] = $this->commonmark->convert($child['content'] ?? '');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (isset($child['content'])) {
 | 
				
			||||||
 | 
					                if (isset($child['is_empty']) && $child['is_empty'] === true) {
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $contains_html = preg_match('#(?<=<)\w+(?=[^<]*?>)#', $child['content'], $m) != 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($contains_html) {
 | 
				
			||||||
 | 
					                // If the element contains the HTML, we gonna display it as is. Backend is going to
 | 
				
			||||||
 | 
					                // encode it for us, preventing any errors on the processing stage.
 | 
				
			||||||
 | 
					                // Later, we decode this using Javascript so it looks like it's normal HTML being injected.
 | 
				
			||||||
 | 
					                // To get all elements that need frontend decoding, we use 'data-state' property.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $_child = $this->document->createElement($child['element'], '');
 | 
				
			||||||
 | 
					                $_child->setAttribute('data-state', 'encoded-html');
 | 
				
			||||||
 | 
					                $_child->nodeValue = htmlspecialchars($child['content']);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // .. in case string doesn't contain any HTML, we'll just return
 | 
				
			||||||
 | 
					                // raw $content.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $_child = $this->document->createElement($child['element'], isset($child['content']) ? htmlspecialchars($child['content']) : '');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $element->appendChild($_child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (isset($child['properties'])) {
 | 
				
			||||||
 | 
					                foreach ($child['properties'] as $property => $value) {
 | 
				
			||||||
 | 
					                    $this->updateElementProperty($_child, $property, $value);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (isset($child['elements'])) {
 | 
				
			||||||
 | 
					                $this->createElementContent($_child, $child['elements']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function updateVariables()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $html = strtr($this->getCompiledHTML(), $this->service->config->html_variables['labels']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $html = strtr($html, $this->service->config->html_variables['values']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->document->saveHTML();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function updateVariable(string $element, string $variable, string $value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $element = $this->document->getElementById($element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $original = $element->nodeValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $element->nodeValue = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $replaced = strtr($original, [$variable => $value]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $element->appendChild(
 | 
				
			||||||
 | 
					            $this->document->createTextNode($replaced)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $element;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getEmptyElements() :self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($this->sections as $element) {
 | 
				
			||||||
 | 
					            if (isset($element['elements'])) {
 | 
				
			||||||
 | 
					                $this->getEmptyChildrens($element['elements'], $this->service->config->html_variables);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getEmptyChildrens(array $children)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($children as $key => $child) {
 | 
				
			||||||
 | 
					            if (isset($child['content']) && isset($child['show_empty']) && $child['show_empty'] === false) {
 | 
				
			||||||
 | 
					                $value = strtr($child['content'], $this->service->config->html_variables['values']);
 | 
				
			||||||
 | 
					                if ($value === '' || $value === ' ') {
 | 
				
			||||||
 | 
					                    $child['is_empty'] = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (isset($child['elements'])) {
 | 
				
			||||||
 | 
					                $this->getEmptyChildrens($child['elements']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -100,7 +100,7 @@ class PdfConfiguration
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $default = (array) CompanySettings::getEntityVariableDefaults();
 | 
					        $default = (array) CompanySettings::getEntityVariableDefaults();
 | 
				
			||||||
        $variables = $this->service->company->pdf_variables;
 | 
					        $variables = (array)$this->service->company->settings->pdf_variables;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($default as $property => $value) {
 | 
					        foreach ($default as $property => $value) {
 | 
				
			||||||
            if (array_key_exists($property, $variables)) {
 | 
					            if (array_key_exists($property, $variables)) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user