Coding Standards Improvement Proposal
Posted: Wed Aug 25, 2010 12:25 am
As it is now, there is a lot of repetitive code in many of the controllers. While there are lots of places it can be improved, I started with the admin/controller/setting/setting.php file, and found a way to go from 1000 lines of code to just 330 lines of code using a for loop.
There were 3 changes made
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:
And simply changed:
to
Now, any new entry in the language file will be automatically pushed to the view without having to double define each entry in the controller. You can still define an entry manually as well when you want to do something with sprintf or override a setting from the language file. So it is completely transparent.
2. Made an errors array
The code for each error is exactly the same. Might as well just code it once and loop through each error:
I Removed all this:
And added this:
3. For loop for all settings from the database
Again, the code for each field on the view is the exact same if/else with only the field name changing. But why bother hardcoding it when our current standard is to name the db fields the same as the form post fields. Instead, following that design, we can just loop through them as variables.
So I deleted all this:
And replaced it with a simple for loop using the settings from the database:
That's it! 400+lines of code replaced with 8!
This also makes it easier to add new fields. You no longer need to edit the controller to add the new field set. Simply add it to the tpl and language file and you are done. This makes development of the core as well as mods much easier and reduces the excess copy/paste code. The same changes can be made to product, category, coupons, etc. All files can benefit from this. Thousands of lines of code can be removed and development efficiency can be increased substantially.
It also stays inline with keeping the framework separate from the app. I'd like this to be the new standard to follow for future development. It also doesn't break any existing code since there are no functional changes so it is backwards compatible.
Thoughts?
There were 3 changes made
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:
Code: Select all
$this->data['heading_title'] = $this->language->get('heading_title');
$this->data['text_none'] = $this->language->get('text_none');
$this->data['text_yes'] = $this->language->get('text_yes');
$this->data['text_no'] = $this->language->get('text_no');
$this->data['text_image_manager'] = $this->language->get('text_image_manager');
$this->data['text_add_store'] = $this->language->get('text_add_store');
$this->data['text_edit_store'] = $this->language->get('text_edit_store');
$this->data['text_mail'] = $this->language->get('text_mail');
$this->data['text_smtp'] = $this->language->get('text_smtp');
$this->data['entry_name'] = $this->language->get('entry_name');
$this->data['entry_url'] = $this->language->get('entry_url');
$this->data['entry_owner'] = $this->language->get('entry_owner');
$this->data['entry_address'] = $this->language->get('entry_address');
$this->data['entry_email'] = $this->language->get('entry_email');
....
....
....
$this->data['tab_server'] = $this->language->get('tab_server');
Code: Select all
$this->load->language('setting/setting')
Code: Select all
$this->data = array_merge($this->data, $this->load->language('setting/setting'));
2. Made an errors array
The code for each error is exactly the same. Might as well just code it once and loop through each error:
I Removed all this:
Code: Select all
if (isset($this->error['warning'])) {
$this->data['error_warning'] = $this->error['warning'];
} else {
$this->data['error_warning'] = '';
}
if (isset($this->error['name'])) {
$this->data['error_name'] = $this->error['name'];
} else {
$this->data['error_name'] = '';
}
if (isset($this->error['url'])) {
$this->data['error_url'] = $this->error['url'];
} else {
$this->data['error_url'] = '';
}
if (isset($this->error['owner'])) {
$this->data['error_owner'] = $this->error['owner'];
} else {
$this->data['error_owner'] = '';
}
if (isset($this->error['address'])) {
$this->data['error_address'] = $this->error['address'];
} else {
$this->data['error_address'] = '';
}
....
....
.....
....
....
if (isset($this->error['admin_limit'])) {
$this->data['error_admin_limit'] = $this->error['admin_limit'];
} else {
$this->data['error_admin_limit'] = '';
}
Code: Select all
$errors = array(
'warning',
'name',
'url',
'owner',
'address',
'email',
'telephone',
'title',
'image_thumb',
'image_popup',
'image_category',
'image_product',
'image_additional',
'image_related',
'image_cart',
'error_filename',
'catalog_limit',
'admin_limit'
);
foreach($errors as $error) {
if (isset($this->error[$error])) {
$this->data['error_' . $error] = $this->error[$error];
} else {
$this->data['error_' . $error] = '';
}
}
Again, the code for each field on the view is the exact same if/else with only the field name changing. But why bother hardcoding it when our current standard is to name the db fields the same as the form post fields. Instead, following that design, we can just loop through them as variables.
So I deleted all this:
Code: Select all
if (isset($this->request->post['config_name'])) {
$this->data['config_name'] = $this->request->post['config_name'];
} else {
$this->data['config_name'] = $this->config->get('config_name');
}
if (isset($this->request->post['config_url'])) {
$this->data['config_url'] = $this->request->post['config_url'];
} else {
$this->data['config_url'] = $this->config->get('config_url');
}
if (isset($this->request->post['config_owner'])) {
$this->data['config_owner'] = $this->request->post['config_owner'];
} else {
$this->data['config_owner'] = $this->config->get('config_owner');
}
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');
}
if (isset($this->request->post['config_email'])) {
$this->data['config_email'] = $this->request->post['config_email'];
} else {
$this->data['config_email'] = $this->config->get('config_email');
}
....
...
...
....
if (isset($this->request->post['config_error_filename'])) {
$this->data['config_error_filename'] = $this->request->post['config_error_filename'];
} else {
$this->data['config_error_filename'] = $this->config->get('config_error_filename');
}
Code: Select all
$settings = $this->model_setting_setting->getSetting('config');
foreach ($settings as $key => $value) {
if (isset($this->request->post[$key])) {
$this->data[$key] = $this->request->post[$key];
} else {
$this->data[$key] = $value;
}
}
This also makes it easier to add new fields. You no longer need to edit the controller to add the new field set. Simply add it to the tpl and language file and you are done. This makes development of the core as well as mods much easier and reduces the excess copy/paste code. The same changes can be made to product, category, coupons, etc. All files can benefit from this. Thousands of lines of code can be removed and development efficiency can be increased substantially.
It also stays inline with keeping the framework separate from the app. I'd like this to be the new standard to follow for future development. It also doesn't break any existing code since there are no functional changes so it is backwards compatible.
Thoughts?