Post by SapporoGuy » Tue Feb 22, 2011 3:40 am

Brilliant!

I am truly enjoying following this thread! It's a complete breath of fresh air!

What does the rest of the files look like?

Also what did you mean by?
I had to include that new file at the top of the latest module, which may show good reason why we should rethink about adding the php autoload function.

930sc ... because it is fun!


User avatar
Active Member

Posts

Joined
Mon Nov 01, 2010 7:29 pm

Post by Qphoria » Tue Feb 22, 2011 5:52 am

SapporoGuy wrote: Also what did you mean by?
I had to include that new file at the top of the latest module, which may show good reason why we should rethink about adding the php autoload function.
Whenever you are subclassing, you need to include the main class, as explained here in the first "Note:" area:
http://www.php.net/manual/en/language.o ... itance.php

PHP 5.0 added a new magic function called "__autoload" that allows classes to be loaded only if they are called automatically. Despite the majority of the web development world, Daniel has opted to not use it in OpenCart... not sure why.. but if autoload was used I wouldn't need to have that first line:
include('module.base.php');

in my example as it would autoload

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JAY6390 » Tue Feb 22, 2011 7:18 am

Surely you would be better off using the startup.php file and loading it there?

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Tue Feb 22, 2011 8:39 am

JAY6390 wrote:Surely you would be better off using the startup.php file and loading it there?
I wouldn't in terms of a mod.. and making it so static is just limiting.. autoload would be ideal for this. But if forced then yes.. but that also loads things when not needed

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JAY6390 » Tue Feb 22, 2011 8:45 am

Sure in some circumstances, but the module controller would be pretty much used every page load on the front end, and it's not likely to cause any trouble on the admin side of things

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Tue Feb 22, 2011 8:46 am

well i wouldn't want special cases for modules while controllers and other stuff are loaded individually. autoload ftw!

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by SapporoGuy » Tue Feb 22, 2011 11:48 pm

hehe, slip it in as a bug fix ;)

Thanks for the link! study time ;D

930sc ... because it is fun!


User avatar
Active Member

Posts

Joined
Mon Nov 01, 2010 7:29 pm

Post by ritey » Wed Mar 02, 2011 4:54 am

Great thread :)

Dave
www.coderstudios.com


User avatar
Active Member

Posts

Joined
Fri Jan 22, 2010 4:28 am
Location - Richmond

Post by jang1200 » Sun Mar 20, 2011 8:19 am

Qphoria wrote: 1. Let language load array merge directly with $this->data
I added a small change in 1.4.8 to return the results back from the language->load function instead of just setting it. This tiny change allows us to get rid of thousands of lines of tedious language entry defines.

So in the setting.php file I removed all language defines like these:
This is from 1.4.9.4 /admin/controller/setting/setting.php :

Code: Select all

<?php

# This file has changed for 1.4.9.4 based on the optimization proposal here: http://forum.opencart.com/viewtopic.php?f=24&t=19000

class ControllerSettingSetting extends Controller {
	private $error = array();

	public function index() {
		$this->load->language('setting/setting');

		$this->document->title = $this->language->get('heading_title');

...
...
...

			$this->session->data['success'] = $this->language->get('text_success');

			$this->redirect(HTTPS_SERVER . 'index.php?route=setting/setting&token=' . $this->session->data['token']);
		}

		# Load language file
		$this->data = array_merge($this->data, $this->load->language('setting/setting'));
array_merge you have in class Language !

works fine for me (in all controllers) since version 1.4.8 :

Code: Select all

	public function index() {
		$this->data = $this->load->language('setting/setting');

		$this->document->title = $this->data['heading_title'];
...
...
          $this->session->data['success'] = $this->data['text_success'];

without array_merge:

Code: Select all

$this->data = array_merge($this->data, $this->load->language('setting/setting'));
only

Code: Select all

$this->data = $this->load->language('setting/setting');
and not

Code: Select all

$this->document->title = $this->language->get('heading_title');
only :

Code: Select all

$this->document->title = $this->data['heading_title'];
same here, not :

Code: Select all

	private function validate() {
		if (!$this->user->hasPermission('modify', 'setting/setting')) {
			$this->error['warning'] = $this->language->get('error_permission');
		}

		if (!$this->request->post['config_name']) {
			$this->error['name'] = $this->language->get('error_name');
		}
...
...
only :

Code: Select all

	private function validate() {
		if (!$this->user->hasPermission('modify', 'setting/setting')) {
			$this->error['warning'] = $this->data['error_permission'];
		}

		if (!$this->request->post['config_name']) {
			$this->error['name'] = $this->data['error_name'];
		}

not:

Code: Select all

$this->language->get('error_name')
only

Code: Select all

$this->data['error_name'];
Sorry for my english.
Thanks

$email = filter_var(filter_var($email, FILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL);
if($email === false) {
// Houston, we have a problem....
}


Newbie

Posts

Joined
Mon Apr 12, 2010 4:17 pm

Post by jonnyreeves » Thu Apr 28, 2011 12:07 am

Hi All,

I've also been tinkering with the OpenCart codebase and thought I would share a couple of helper methods that I added to my Controller.php file to make like a little bit easier and reduce the amount of code duplication:

Code: Select all

/**
 * Builds up a standard OpenCart URL; particularly useful in the Admin pages as it automatically 
 * appends the token from the Session object.  
 *
 * @param String $route The route you wish to direct the link at, ie 'sale/customer'
 * @param Array $query_data an array of key/value pairs which will be appended to
 * the generated link as part of the query string.
 * @return String fully qualified URL for the supplied route and query string, including the admin
 * session token if it is present in the session object.
 * @example
 * <listing>
 *   // http://my.store/index.php?route=sale/customer/edit&token=123&customer_id=22
 *   $this->link('sale/customer/edit', array('customer_id' => 22));
 * </listing>
 */
protected function link($route, $query_data = array()) {
    if (isset($this->session->data['token'])) {
        $query_data ['token'] = $this->session->data['token'];
    }
    $url = HTTPS_SERVER . 'index.php?route=' . $route;
    if (!empty($query_data)) {
        $url .= '&' . http_build_query($query_data);
    }
    return $url;
} 

Code: Select all

/**
 * Reads the supplied property from the GET request object.  If the property is not set in the GET 
 * request object then the supplied default value will be returned instead.
 *
 * @param String $prop The key to read from the GET request object.
 * @param mixed $default_value Default value which will be returned if the supplied $prop key
 * is not set in the GET request object.
 * @return mixed either the value mapped to the supplied $prop key from the GET request object
 * if it has been set, or the supplied $default_value if it was not set.
 * @example
 * <listing>
 *   $this->data['email'] = $this->readGet('email', '');
 * </listing>
 */
protected function readGet($prop, $default_value = NULL) {
    return (isset($this->request->get[$prop])) ? $this->request->get[$prop] : $default_value;
} 

Code: Select all

/**
 * Renders the supplied template as HTML, including the default childen if they have not
 * already been set.
 * @param String $template the name of the template file to render, exlcuding the .tpl 
 * file extension, eg: 'information/contact'.
 * @example
 * <listing>
 *   // In ControllerInformationContact:index
 *   $this->outputTemplate('information/contact');
 * </listing>
 */
protected function outputTemplate($template) {
    // Include either a custom template, goverened by the current theme, or fall back to the default 
    // theme which ships with OpenCart.
    if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/' . $template . '.tpl')) {
        $this->template = $this->config->get('config_template') . '/template/' . $template . '.tpl';
    } else {
        $this->template = 'default/template/' . $template . '.tpl';
    }
        
    // Populate default child templates.
    if (empty($this->children)) {
        $this->children = array(
            'common/column_right',
            'common/footer',
            'common/column_left',
            'common/header'
        );
    }    
    $this->response->setOutput($this->render(TRUE), $this->config->get('config_compression'));        
}
 
Hope these snippets help in some way :)
Last edited by jonnyreeves on Thu Apr 28, 2011 6:23 pm, edited 5 times in total.

Newbie

Posts

Joined
Wed Apr 27, 2011 11:48 pm

Post by JAY6390 » Thu Apr 28, 2011 12:13 am

Well the first one of those two snippets is a little bloated, since http_build_query can do pretty much the whole thing at once. To be honest, these are unlikely to be included in the core. There are far more useful things that could be added that have been rejected

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Thu Apr 28, 2011 12:17 am

Well lets not piss on people's ideas... They are good ideas and while they may not be included as shown some inspiration may be taken from them.

Thank you for the tips :)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by jonnyreeves » Thu Apr 28, 2011 12:28 am

Thanks for the tip about http_build_query() Jay; PHP is not my 'native' language and it's easy to miss some of these built in methods - I've updated my snippet accordingly.

Although the snippets above are simple, their impact is fairly high as they allow you to quickly distil common Controller actions down; just like Qphoria's tweak to the way language definitions are read at the top of this thread. For example, just by using the queryGet() method, the following boilerplate code goes from:

Code: Select all

if (isset($this->request->post['config_address'])) {
	$this->data['config_address'] = $this->request->post['config_address'];
} else {
	$this->data['config_address'] = $this->config->get('config_address');
}
To:

Code: Select all

$this->data['config_address'] = $this->queryPost('config_address', $this->config->get('config_address'));
Also, just to note, I am not trying to get these changes merged into OpenCart core; I simply wanted to share them with the other developers as they follow a similar topic as the rest of this thread.

Newbie

Posts

Joined
Wed Apr 27, 2011 11:48 pm

Post by Johnathan » Thu Apr 28, 2011 10:35 am

Hey Q -- any chance these ideas will make it into the final version of 1.5.0?

Image Image Image Image Image


User avatar
Administrator

Posts

Joined
Fri Dec 18, 2009 3:08 am


Post by Qphoria » Thu Apr 28, 2011 11:12 am

Johnathan wrote:Hey Q -- any chance these ideas will make it into the final version of 1.5.0?
I doubt it. I think perhaps if we can make a working concept we can feel it out for how it will or won't work. There are a few ideas now thrown about
- subclassing
- Common "generic_form.tpl" file
- The other controller changes listed in this thread...

All of them seem like great ideas but actually each conflicts with the other in some way. So I think more time needs to be spent with which way is best before we decide for sure and 1.5.0 bug fixing has got our full attention as it is. So I wouldn't expect 1.5.0 to have anything different from massive bug fixes and touchups as far as the code breakdown goes

Some bits from this thread will be implemented. Like the language defines replaced by the array_merge
And the arrays of some of the repeats.

That will clean up a lot of the code and give us cleaner code to start as a base

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Xsecrets » Thu Apr 28, 2011 12:17 pm

I don't see why subclassing would interfere with a generic form.tpl, it might actually work very well with it, but yeah I think all these ideas and more should be thrown in a pile and tested out to come up with something really good for 2.0

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US

Post by Qphoria » Thu Apr 28, 2011 7:11 pm

Xsecrets wrote:I don't see why subclassing would interfere with a generic form.tpl, it might actually work very well with it, but yeah I think all these ideas and more should be thrown in a pile and tested out to come up with something really good for 2.0
I meant subclassing interfering with the 2 controller concepts.
The original idea in this thread was to simplify the controller page by simply making all the post fields an array and looping through them. This assumes that the tpl file will be specific to each controller. I've implemented this in the setting.php file in 1.4.9.4 as a point of test and it works great

The second idea I had here for using a common generic tpl, is the polar opposite of this one. It moves all control to the "Controller" (pun it baby!) and leaves the tpl file generic based on the controller data.

I'm my own devil's advocate when it comes to ideas... but now which one is better?

Don't want to start using one and having people create subclasses from it using the wrong format if we are going to go with a different method. Then again, they can technically live together, as long as the controllers that use the method from this thread use their own tpl files, and for those that use the method in the other thread, they'd use the more involved controller file.

I guess it is nice to have options and subclassers will just have to follow which ever method the parent controller uses.

The method listed in this thread is readily usable now and actually always has been for the array looping part.
The method with generic tpl was added to 1.5.0 which is simply just that one file which i renamed to "common_form.tpl" in the admin/view/template/common folder. You can use that as well in 1.5.0 and I'll add it to 1.4.9.5 for good measure on the stable version.

So I guess decide which you'd like to use for your mod

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Xsecrets » Thu Apr 28, 2011 8:26 pm

ok here's a great question does the generic form handle all the layout stuff that is now it 1.5? We really need to come up with something in the next few versions to simplify that for the developers. From what I can tell right now there is not even any standard implementation used throughout the existing modules.

What I was suggesting when I said throw them all in a pile is that for the long haul we should probably start a thread or something where developers can mishmashing this stuff and come up with the best solution to put in say 2.0

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US

Post by Qphoria » Thu Apr 28, 2011 9:30 pm

Xsecrets wrote:ok here's a great question does the generic form handle all the layout stuff that is now it 1.5? We really need to come up with something in the next few versions to simplify that for the developers. From what I can tell right now there is not even any standard implementation used throughout the existing modules.

What I was suggesting when I said throw them all in a pile is that for the long haul we should probably start a thread or something where developers can mishmashing this stuff and come up with the best solution to put in say 2.0
Well 1.5.0 is a new beast.. and it is true there are some changes. In 1.4.x the common form could be used for almost all extensions. Now that modules have slight differences in their features and a lot more javascript html building for the instance-based design, it may no longer be able to use a common form for modules. But it is still usable for payment, shipping, order total extensions, and other similarly coded mods which are still main targets for 3rd party developers. So people making those extensions can certainly benefit from it and start using the common form now.

For those making modules and other controllers files with a lot more custom js html building won't likely be able to use a common form, but will perhaps benefit from either controller coding method. Both would need to use their own tpl files but it's like six in one hand, half-dozen in the other... You really have the choice in this case since you will be controlling both files:
1. Use the array loop method in the controller and have a very specific tpl file
2. Use the field builder method used in the common form example and have a slightly more generic tpl file
3. Or use your own method. Extensions are coded the way you choose.

So I guess this part is moot. We could start subclassing and whatever method the controller uses, the subclass will follow.. but I can say right now that is on the back burner as far as core bits.. but this could be started as a mod and evolve into the core

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Xsecrets » Thu Apr 28, 2011 9:39 pm

Qphoria wrote: Well 1.5.0 is a new beast.. and it is true there are some changes. In 1.4.x the common form could be used for almost all extensions. Now that modules have slight differences in their features and a lot more javascript html building for the instance-based design, it may no longer be able to use a common form for modules. But it is still usable for payment, shipping, order total extensions, and other similarly coded mods which are still main targets for 3rd party developers. So people making those extensions can certainly benefit from it and start using the common form now.
here's a question I mentioned it in the bug thread, but I'd like to reiterate it. Would it be possible to go a head and extend the payment/shipping modules to have a store dropdown so you can have different settings for each store in a mulit-store setup. From looking at the code and database it looks like it would be fairly simple to extend them to do that, and with that and the layout system you could have a truly useful multi-store setup.

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US
Who is online

Users browsing this forum: No registered users and 70 guests