Post by Qphoria » Thu Jan 22, 2009 5:34 am

The way extensions work at the moment is highly retarded. You have to insert a record to find the extension. Extensions would be much more useful if designed to be plug-n-play. Kinda like how templates are done. You simply add the folder to the template directory, and it adds that template to the dropdown of the template choice.

Extensions need a little more information, so I was looking at the way WordPress does it. Check out the "Header Info" section here:
http://codex.wordpress.org/Writing_a_Plugin

This allows the system to find all the information it needs about the extension from the file itself on-the-fly. No more need to manually insert the details for a new extension.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 12:39 am

I'm looking at this atm, I see the issue now.

Before you can "install" the extension, you have to initialise the extension by running some SQL to include it into the database.

My issue is how to display the ones that aren't included in the database yet.

You can't just add them to the list because of the filtering, sorting, pagination elements of the sql lookup.

An idea I had was to get a list of the files, then lookup each filename in the database, if it doesn't exist, include it, and call a function, which will initialise the module in the database, and will then be included in the list.

My only issue with this is how many lookups you're gonna have to do each time you load the page to ensure all the modules are initialised, but I'm not sure I see any other way at the moment.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by Qphoria » Tue Feb 03, 2009 1:10 am

hm2k wrote:
My issue is how to display the ones that aren't included in the database yet.

You can't just add them to the list because of the filtering, sorting, pagination elements of the sql lookup.
Hmm. There is no "sort" field on extension descriptions so that shouldn't be an issue.
filtering is done by the value of the "Directory"
pagination is done on the fly based on the number of records returned, not related to insert.

So none of that should apply.
If we follow how WP does it with the header text, we'd simply need to have the inclusion data in the header and have the extension.php controller read the header of each file under the "extensions" folder and decide if it has been added already. If not, then parse that data and insert it and reload the list. Simple.

Example header:

/*
Extension Name: Authorize.net AIM
Extension Description: Authorize.net credit card module, advanced integration
code: authnetaim
directory: payment
filename: authnetaim.php
controller: payment_authnetaim
*/

The file controls what "filter" to add it under. The only other thing would be language support, which I haven't figured yet.

This would be a rudimentary way to add it to the existing structure.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 1:22 am

I think you got the wrong end of the stick, i'm not on about the insert, i'm on about the getList() lookup.

The SQL sorts by name, extension or code, it also involves pagination limits, and filtering by "module type".

These are things that you can't do with a file system, meaning you can't just put both sets of data into 1 list.

I'm not really sure we need to "follow" the way wordpress does it, considering that we already do it very differently to begin with.

I think it'd be much simpler to use a function with these details in, which can be called to initialise the extension rather than building a parser.

I think the best plan could be to just use the filesystem to include() each module and run it's init() function if it has one. The init() function can "initialise" the extension so it's details get added into the database (if it isn't already there), BEFORE the getList() is called, meaning the details will always be there.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by Qphoria » Tue Feb 03, 2009 1:37 am

I'm not sure I follow.

My thought, and lets start small for understanding sake....

There are 3 shipping modules
- flat
- zone
- per-item

so when you do getList() on shipping, the sql returns 3 shipping options based on the "group" field of "shipping"

Now lets say you want to add "UPS Shippping Module".

1. You upload the files to the server
2. You goto Extensions->Shipping menu option
3. getlist() runs the sql query on the db to get the list of installed shipping modules
- then, it runs a filesearch on "admin/extension/shipping" for shipping modules.
- foreach file, check the header "code" value is in_array of the 3 codes it returned from the db
- If the code is not in_array, then read all the header info from that file, insert the data into the db and requery. Ouput the results to getList() which will have all 4 of the modules now, self-installing the new one in the background
- If the codes are all in_array, then just output as normal.

This way it only does a requery if it finds new ones to add.

Remember, this leaves the new module in the list but not "installed". It shows the "+" icon to install it.  getlist() DOES NOT use sort_order to get the list (since there is no sort order on the descriptors). Sort order is only used by the front end when getting all actual shipping module data and deciding which way to display them to the customer. There is no bearing on the admin side. The admin side uses alphabetical sort by name
Last edited by Qphoria on Tue Feb 03, 2009 1:47 am, edited 1 time in total.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 2:00 am

This is what i'm talking about:

1. Upload new module to server.
2. Go to: /admin/?controller=extension&type=[any]
3. Page begins to load...
- Use glob() to list the files in the extentions/[type]/ directory to get a list
- Check each file to see if it exists in the database or not
- If it doesn't exist in the database, include the file and run the init() function
- If it exists, the init() function will run the SQL that inserts the extension details into the database
- The page continues to load getList(), any new extensions will be listed

The benefit of this is as follows:
* It's compatible with what we have at the moment
* We don't need to parse a "header"
* getList() doesn't have to be changed

Note: There is no sort_order, but there is mysql sorting to think about, which is why we must use an SQL solution, and not just pure filesystem, although what you're suggesting would work in a similar way to what I suggested with the SQL.

Attachments

???
sorting.jpg

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by Qphoria » Tue Feb 03, 2009 2:04 am

Ah ok.
We are saying the same thing actually, just going about it differently.

-You are adding an init function, which is essentially the same as the header parser, which is just inserting a sql insert for the descriptor. init makes more sense and I was thinking it would be simpler to just have the sql in the header, but an actual init function make more sense to be more structured

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 2:06 am

Great, i'll go ahead and add this feature in.

My only concern is the SQL lookup I have to do for each file might slow it down a bit, but it may not be noticeable.

I guess it's a case of suck it and see.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by Qphoria » Tue Feb 03, 2009 2:53 am

at least its only on the admin side and not the customer side

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 4:24 am

Yeah and at least it wouldn't be all the time...

I'm faced with a little bit of a problem...
Fatal error: Cannot redeclare class modulefooter
The way the main classes handle this is by using the locator, but since these extensions are exactly that extensions of the main classes, it's difficult to handle them.

Another thing is that all the "extensions" (module,calculate,payment,shipping) are practically all the same, but they don't have a common library.

I'm not sure what to make of all this at the moment, or how to handle it.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by Qphoria » Tue Feb 03, 2009 4:28 am

daniel changed this a bit in 1.0. Perhaps the new way is better (or worse). Perhaps something to learn from.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by hm2k » Tue Feb 03, 2009 4:45 am

How it is atm:

Code: Select all

	function __construct(&$locator) {
		$this->database =& $locator->get('database');
		
		$results = $this->database->getRows("select * from extension where type = 'payment'");
		
		foreach ($results as $result) {
			$file  = DIR_EXTENSION . $result['directory'] . '/' . $result['filename'];
			$class = 'Payment' . str_replace('_', '', $result['code']);

			if (file_exists($file)) {
				require_once($file);
	
				$this->data[$result['code']] = new $class($locator);
			}
		}
	}
New code:

Code: Select all

	public function __construct($registry) {
		$files = glob(DIR_LIBRARY . 'application/payment/*.php');		
		
		foreach ($files as $file) {
			$class = 'Payment' . str_replace('_', '', basename($file, '.php'));
			
			require_once($file);

			$this->data[basename($file, '.php')] = new $class($registry);
		}	
	}
So, the difference is, before it relies purely on the database, where as in the new system there's no use of the database at all.

Perhaps we should do away with the use of the extension and extension_description tables, and just do the filesystem approach, then we don't have to init() them at all.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by hm2k » Tue Feb 03, 2009 6:51 am

Looking at this again, basically what's happening is, I'm including the file once, then that file declares the class, then when the footer is called, of course, it's the same file, so it tries to declare the class again to use it.

I see the issue now.

The \admin\extension\module\footer.php uses

Code: Select all

class ModuleFooter extends Controller {  
which is the same as:
\catalog\extension\module\footer.php

Code: Select all

class ModuleFooter extends Controller {  
So even though we use _once, the class is still trying to be declared twice, in two different files.

We could use class_exists() in an if statement to ensure the class isn't redeclared, but that's just a cheap hack really, it's not the real solution.

The real solution would be to use something like ModuleAdminFooter, and ModuleCatalogFooter for the class names, however this may be quite a big adjustment, but should be done to avoid conflict and confusion.

We see similar formatting to this in "\admin\controller\module_catalog_footer.php":

Code: Select all

class ControllerModuleCatalogFooter extends Controller {
I'm not sure atm how such a change will impact the system, but i'm not sure what else to suggest atm.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by hm2k » Tue Feb 03, 2009 8:32 am

Had a brainwave, and realised I shouldn't even be getting these errors, as they are already in the db.

So I checked my code, turns out I was using the full file path, instead of just the basename filename. Doh!

However, now I'm not convinced I've got the right file...

I've dropped in "\catalog\extension\module\latest.php", which is a module like the others in the same directory, it works in the same way, however, each of these modules has a "controller", in this case it's "\admin\controller\module_catalog_latest.php".

At the moment the files i'm looking for are as follows:

Code: Select all

	
	$path=DIR_CATALOG.PATH_EXTENSION.DIRECTORY_SEPARATOR.$type.DIRECTORY_SEPARATOR;
	$files=glob($path.'*.php');
This means I should be looking for:

Code: Select all

	$files=glob(DIR_CONTROLLER.$type.'_*.php');
Which probably makes more sense really, since this is where the install/uninstall functions are already, and it's all admin side, it will also lead to less confusion, I hope.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK

Post by hm2k » Tue Feb 03, 2009 9:34 am

Going public as of r407.

UK Web Hosting


User avatar
Global Moderator

Posts

Joined
Tue Mar 11, 2008 9:06 am
Location - UK
Who is online

Users browsing this forum: No registered users and 6 guests