Post by JNeuhoff » Fri Dec 11, 2020 8:55 pm

It can be done with a before-event handler, though it's a bit convoluted:

Code: Select all

	// event handler for admin/view/catalog/product_form/before
	public function eventViewCatalogProductFormBefore( &$route, &$data, &$template_code=null ) {

		$template_buffer = $this->getTemplateBuffer( $route, $template_code );

		$search  = '{% if customer_group.customer_group_id == product_special.customer_group_id %}';
		$replace = '{% if customer_group.customer_group_id == product_special.customer_group_id and some_new_variable_equal_true %}';
		$template_buffer = str_replace( $search, $replace, $template_buffer );

		$template_code = $template_buffer;

		return null;
	}


	// return template file contents as a string
	protected function getTemplateBuffer( $route, $event_template_buffer ) {
		// if there already is a modified template from view/*/before events use that one
		if ($event_template_buffer) {
			return $event_template_buffer;
		}

		// load the template file (possibly modified by ocmod and vqmod) into a string buffer
		if ($this->isAdmin()) {
			$dir_template = DIR_TEMPLATE;
		} else {
			if ($this->config->get('config_theme') == 'default') {
				$theme = $this->config->get('theme_default_directory');
			} else {
				$theme = $this->config->get('config_theme');
			}
			$dir_template = DIR_TEMPLATE . $theme . '/template/';
		}
		$template_file = $dir_template . $route . '.twig';
		if (file_exists( $template_file ) && is_file( $template_file )) {
			$template_file = $this->modCheck( $template_file );
			return file_get_contents( $template_file );
		}
		if ($this->isAdmin()) {
			trigger_error("Cannot find template file for route '$route'");
			exit;
		}
		$dir_template = DIR_TEMPLATE . 'default/template/';
		$template_file = $dir_template . $route . '.twig';
		if (file_exists( $template_file ) && is_file( $template_file )) {
			$template_file = $this->modCheck( $template_file );
			return file_get_contents( $template_file );
		}
		trigger_error("Cannot find template file for route '$route'");
		exit;
	}


	protected function isAdmin() {
		return defined( 'DIR_CATALOG' ) ? true : false;
	}


	protected function modCheck( $file ) {
		// return a PHP file possibly modified by OpenCart's system/storage/modification,
		//   and then possibly modified by vqmod (see also https://github.com/vqmod/vqmod)

		// Use OpenCart's modified file is available
		$original_file = $file;
		if (defined('DIR_MODIFICATION')) {
			if ($this->startsWith($file,DIR_APPLICATION)) {
				if ($this->isAdmin()) {
					if (file_exists( DIR_MODIFICATION . 'admin/' . substr($file,strlen(DIR_APPLICATION)) )) {
						$file = DIR_MODIFICATION . 'admin/' . substr($file,strlen(DIR_APPLICATION));
					}
				} else {
					if (file_exists( DIR_MODIFICATION . 'catalog/' . substr($file,strlen(DIR_APPLICATION)) )) {
						$file = DIR_MODIFICATION . 'catalog/' . substr($file,strlen(DIR_APPLICATION));
					}
				}
			} else if ($this->startsWith($file,DIR_SYSTEM)) {
				if (file_exists( DIR_MODIFICATION . 'system/' . substr($file,strlen(DIR_SYSTEM)) )) {
					$file = DIR_MODIFICATION . 'system/' . substr($file,strlen(DIR_SYSTEM));
				}
			}
		}

		// Don't use VQmod 2.3.2 or earlier if available
		if (array_key_exists('vqmod', get_defined_vars())) {
			trigger_error( "You are using an old VQMod version '2.3.2' or earlier, please upgrade your VQMod!" );
			exit;
		}

		// Use modification through VQmod 2.4.0 or later if available
		if (class_exists('VQMod',false)) {
			if (VQMod::$directorySeparator) {
				if (strpos($file,'vq2-')!==FALSE) {
					return $file;
				}
				if (version_compare(VQMod::$_vqversion,'2.5.0','<')) {
					trigger_error( "You are using an old VQMod version '".VQMod::$_vqversion."', please upgrade your VQMod!" );
					exit;
				}
				if ($original_file != $file) {
					return VQMod::modCheck($file,$original_file);
				}
				return VQMod::modCheck($original_file);
			}
		}

		// no VQmod
		return $file;
	}


	protected function startsWith( $haystack, $needle ) {
		if (strlen( $haystack ) < strlen( $needle )) {
			return false;
		}
		return (substr( $haystack, 0, strlen($needle) ) == $needle);
	}
The basic idea is to use a simple str_replace call in the event handler.
Last edited by JNeuhoff on Thu Dec 17, 2020 7:33 pm, edited 3 times in total.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by straightlight » Fri Dec 11, 2020 9:40 pm

Interesting ... all lookups done together ... :o

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by JNeuhoff » Fri Dec 11, 2020 9:49 pm

It would be good to have the getTemplateBuffer function available in e.g. the system/library/template.php, this way it can be used in view/*/before event handlers, without having to redefine it each time.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by straightlight » Fri Dec 11, 2020 9:56 pm

JNeuhoff wrote:
Fri Dec 11, 2020 9:49 pm
It would be good to have the getTemplateBuffer function available in e.g. the system/library/template.php, this way it can be used in view/*/before event handlers, without having to redefine it each time.
You could submit a pull request about it.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by straightlight » Fri Dec 11, 2020 10:06 pm

As for $this->startsWith, I am not sure where that one originates from.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by JNeuhoff » Fri Dec 11, 2020 10:49 pm

straightlight wrote:
Fri Dec 11, 2020 10:06 pm
As for $this->startsWith, I am not sure where that one originates from.
OK, added that one now, too.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by straightlight » Fri Dec 11, 2020 10:50 pm

Perhaps this line:

Code: Select all

if (!empty($GLOBALS['vqmod'])) {
should be replaced with:

Code: Select all

if (array_key_exists('vqmod', get_defined_vars())) {
since $GLOBALS is not safe to be used: https://stackoverflow.com/a/41982330 .

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by JNeuhoff » Fri Dec 11, 2020 11:56 pm

straightlight wrote:
Fri Dec 11, 2020 10:50 pm
Perhaps this line:

Code: Select all

if (!empty($GLOBALS['vqmod'])) {
should be replaced with:

Code: Select all

if (array_key_exists('vqmod', get_defined_vars())) {
since $GLOBALS is not safe to be used: https://stackoverflow.com/a/41982330 .
You are right, now updated.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by madimar » Sat Dec 12, 2020 1:05 am

Great guys! I was sure someone of you could be so kind to give his valuable opinion and suggestion. I'll try to arrange a first simple "modification" via event soon and, why not, I'll post a full example here.

Regards,

M

-----------------------------------------------------------------------
My last mods: Partita IVA e CF | Pro EU VAT Number | Sales Agents | Pricelist Pro
-----------------------------------------------------------------------


User avatar
Active Member

Posts

Joined
Thu Sep 24, 2009 6:27 pm


Post by madimar » Sun Dec 13, 2020 12:18 am

Hi, here I am again, as promised, trying to arrange a simple mod as exercize. Things begin to work, thanks to your suggestions, even if I'm still facing some difficulties. Template part works perfectly, thanks to JNeuhoff suggestions. Now I'm trying to understand who to modify properly controller and Model.

Let me sum up my exercize full goal: To add some fields in admin Customer Group in order to be able to decide if to show Company field or not in registration form. So besides, template modification, I need to get and update 2 new fields I added in oc_customer_group table.

This is current full code:

Code: Select all

<?php
class ControllerExtensionModuleOcTest extends Controller {
	private $codename = 'oc_test';
	private $config_file = 'oc_test';
	
	public function install() {
		$this->load->model('extension/oc_module/oc_test');
		$this->model_extension_oc_module_oc_test->install();

		$this->load->model('setting/event');
		
		// List of events
		$this->model_setting_event->addEvent($this->codename, 'admin/view/customer/customer_group_form/before',  'extension/module/oc_test/eventViewCustomerGroupFormBefore');

		$this->model_setting_event->addEvent($this->codename, 'admin/model/customer/customer_group/editCustomerGroup/after', 'extension/module/oc_test/eventModelCustomerGroupAddEditAfter');
		$this->model_setting_event->addEvent($this->codename, 'admin/model/customer/customer_group/addCustomerGroup/after', 'extension/module/oc_test/eventModelCustomerGroupAddEditAfter');		
		
	}
	
	public function uninstall() {
		$this->load->model('extension/oc_module/oc_test');
		$this->model_extension_oc_module_oc_test->uninstall();

		$this->load->model('setting/event');		
		$this->model_setting_event->deleteEventByCode($this->codename);
	}	


// event handler for admin/view/customer/customer_group_form/before
	public function eventViewCustomerGroupFormBefore( &$route, &$data, &$template_code=null ) {

		$this->load->language('extension/oc_module/oc_test');
		$this->load->model('localisation/language');
				
		// Entry
		$data['entry_company_show'] = $this->language->get('entry_company_show');
		$data['entry_company_oblige'] = $this->language->get('entry_company_oblige');
		
		// Help
		$data['help_company_show'] = $this->language->get('help_company_show');
		$data['help_company_oblige'] = $this->language->get('help_company_oblige');	
		
		$this->load->model('customer/customer_group');
		
		if (isset($this->request->get['customer_group_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
			$customer_group_info = $this->model_customer_customer_group->getCustomerGroup($this->request->get['customer_group_id']);
		}
		
		if (isset($this->request->post['company_show'])) {
			$data['company_show'] = $this->request->post['company_show'];
		} elseif (!empty($customer_group_info)) {
			$data['company_show'] = $customer_group_info['company_show'];
		} else {
			$data['company_show'] = '';
		}

		if (isset($this->request->post['company_oblige'])) {
			$data['company_oblige'] = $this->request->post['company_oblige'];
		} elseif (!empty($customer_group_info)) {
			$data['company_oblige'] = $customer_group_info['company_oblige'];
		} else {
			$data['company_oblige'] = '';
		}
				
		$template_buffer = $this->getTemplateBuffer( $route, $template_code );

		$search  = '          <div class="form-group">
            <label class="col-sm-2 control-label" for="input-sort-order">{{ entry_sort_order }}</label>';
		$replace = '          <div class="form-group">
            <label class="col-sm-2 control-label"><span data-toggle="tooltip" title="{{ help_company_view }}">{{ entry_company_view }}</span></label>
            <div class="col-sm-10">
              <label class="radio-inline">
                {% if company_view %}
                <input type="radio" name="company_view" value="1" checked="checked" />
                {{ text_yes }}
                {% else %}
                <input type="radio" name="company_view" value="1" />
                {{ text_yes }}
                {% endif %}
              </label>
              <label class="radio-inline">
                {% if not company_view %}
                <input type="radio" name="company_view" value="0" checked="checked" />
                {{ text_no }}
                {% else %}
                <input type="radio" name="company_view" value="0" />
                {{ text_no }}
                {% endif %}
              </label>
            </div>			  
            <label class="col-sm-2 control-label"><span data-toggle="tooltip" title="{{ help_company_oblige }}">{{ entry_company_oblige }}</span></label>
            <div class="col-sm-10">
              <label class="radio-inline">
                {% if company_oblige %}
                <input type="radio" name="company_oblige" value="1" checked="checked" />
                {{ text_yes }}
                {% else %}
                <input type="radio" name="company_oblige" value="1" />
                {{ text_yes }}
                {% endif %}
              </label>
              <label class="radio-inline">
                {% if not company_oblige %}
                <input type="radio" name="company_oblige" value="0" checked="checked" />
                {{ text_no }}
                {% else %}
                <input type="radio" name="company_oblige" value="0" />
                {{ text_no }}
                {% endif %}
              </label>			  
            </div>
          </div>
          <div class="form-group">
            <label class="col-sm-2 control-label" for="input-sort-order">{{ entry_sort_order }}</label>';
		$template_buffer = str_replace( $search, $replace, $template_buffer );

		$template_code = $template_buffer;

		return null;
	}



// event handler for admin/model/customer/customer_group/edit/after
	public function eventModelCustomerGroupAddEditAfter(&$route, &$data, &$template_code=null ) {

		$this->db->query("UPDATE " . DB_PREFIX . "customer_group SET company_show = '" . (int)$data['1']['company_show'] . "', company_oblige = '" . (int)$data['1']['company_oblige'] . "' WHERE customer_group_id = '" . (int)$data['0'] . "'");
		
		return null;
	}
Actually new fields are shown, but I can get values from db and neither to update them. What am I wrong?

-----------------------------------------------------------------------
My last mods: Partita IVA e CF | Pro EU VAT Number | Sales Agents | Pricelist Pro
-----------------------------------------------------------------------


User avatar
Active Member

Posts

Joined
Thu Sep 24, 2009 6:27 pm


Post by OSWorX » Thu Dec 17, 2020 12:35 am

madimar wrote:
Sun Dec 13, 2020 12:18 am
Actually new fields are shown, but I can get values from db and neither to update them. What am I wrong?
Usually an event is called like this:

Code: Select all

public function eventModelCustomerGroupAddEditAfter(&$route, &$data [, &$output]) { .. }
($output is used only if the event is called with after not with before)

which means, if you call it

Code: Select all

public function eventModelCustomerGroupAddEditAfter($data)
$data is the string $route and therefore no data here ..

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by JNeuhoff » Thu Dec 17, 2020 6:48 pm

Try this, the event handlers require certain arguments:

Code: Select all

	// event handler for admin/controller/customer/customer_group/edit/before
	public function eventControllerCustomerGroupAddEditBefore($route,&$data) {
		// ........
	}

	// event handler for admin/model/customer/customer_group/edit/after
	public function eventModelCustomerGroupAddEditAfter(&$route,&$data,&$output) {
		// ........
	}

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by OSWorX » Thu Dec 17, 2020 7:12 pm

JNeuhoff wrote:
Thu Dec 17, 2020 6:48 pm
Try this, the event handlers require certain arguments
Just what I wrote above ..

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by OSWorX » Thu Dec 17, 2020 7:17 pm

Just a short update to Juergens code.

Inside that, he use the variable: $template_engine
But it is never defined which will lead to troubles (1) and (2) code is not useable if you use it for OpenCart 2.x

Therefore add following:

Code: Select all

		// get engine type, OC >= 3.x has template_engine
		if( !$template_engine = $this->config->get( 'template_engine' ) ) {
			$template_engine = 'tpl';
		}
and replace

Code: Select all

$template_file = $dir_template . $route . '.twig';
with:

Code: Select all

$template_file = $dir_template . $route . ' . template_engine ;
Maybe Juergen does it not this way ..

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by JNeuhoff » Thu Dec 17, 2020 7:39 pm

Inside that, he use the variable: $template_engine
But it is never defined which will lead to troubles (1) and (2) code is not useable if you use it for OpenCart 2.x
Well spotted, I have now updated my sample code for OC 3.0.x.

Personally, I tend to write my own event handlers for views to support both twig and PHP templates because I often use the Template Switcher on OC 3.0.x sites.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by OSWorX » Thu Dec 17, 2020 8:01 pm

JNeuhoff wrote:
Thu Dec 17, 2020 7:39 pm
Inside that, he use the variable: $template_engine
But it is never defined which will lead to troubles (1) and (2) code is not useable if you use it for OpenCart 2.x
Well spotted, I have now updated my sample code for OC 3.0.x.

Personally, I tend to write my own event handlers for views to support both twig and PHP templates because I often use the Template Switcher on OC 3.0.x sites.
Well okay, but the less extensions are used, the more I like it.
And here there are only 3 lines of code, instead of a "full extension" or what else ..
And not to forget, your Template Switcher is only for OC 3.x - so if someone use the above code inside OC 2.x > he is lost.

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by straightlight » Thu Dec 17, 2020 10:39 pm

@JNeuhoff: OSWorX addresses a good point here. If we want to encourage forum users to use the Events engine from the core, then additional extension Engines should not be imported in the validations but rather to validate the Events as stand-alone.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by madimar » Mon Dec 21, 2020 1:53 am

Thanks again for suggestions, I edited my code above, and now thigns generally work. Regarding event "model...after", to write additional data to db, it was actually easiest thanks to your suggestions.
On the other side I've had more difficulties for the "get" part and I'm not sure what I made is the best way to achieve the result. What I don't like to much it is to need to perform an additional getCustomerGroup before view in order to have all data.
What do you think about that? Is there another more elegant/efficent way to achieve the same result?

Thanks in advance, regards,

M

-----------------------------------------------------------------------
My last mods: Partita IVA e CF | Pro EU VAT Number | Sales Agents | Pricelist Pro
-----------------------------------------------------------------------


User avatar
Active Member

Posts

Joined
Thu Sep 24, 2009 6:27 pm


Post by straightlight » Mon Dec 21, 2020 8:40 am

madimar wrote:
Mon Dec 21, 2020 1:53 am
Thanks again for suggestions, I edited my code above, and now thigns generally work. Regarding event "model...after", to write additional data to db, it was actually easiest thanks to your suggestions.
On the other side I've had more difficulties for the "get" part and I'm not sure what I made is the best way to achieve the result. What I don't like to much it is to need to perform an additional getCustomerGroup before view in order to have all data.
What do you think about that? Is there another more elegant/efficent way to achieve the same result?

Thanks in advance, regards,

M
Directly into the install.xml file to search for lines and alter them.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by madimar » Tue Dec 22, 2020 2:04 am

straightlight wrote:
Mon Dec 21, 2020 8:40 am
Directly into the install.xml file to search for lines and alter them.
DO YOU MEAN OCMOD ?!?

-----------------------------------------------------------------------
My last mods: Partita IVA e CF | Pro EU VAT Number | Sales Agents | Pricelist Pro
-----------------------------------------------------------------------


User avatar
Active Member

Posts

Joined
Thu Sep 24, 2009 6:27 pm

Who is online

Users browsing this forum: No registered users and 14 guests