Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Recommended Posts

So, I'm working on an older addon that requires core changes which maybe not your favorite.... but for addons that require core changes... what about defines in (admin or catalog) includes/languages/english.php?
 

Is there a best practice? Should theses be moved to their own file language file? Or something else?

Link to comment
Share on other sites

  • Replies 65
  • Created
  • Last Reply

My advice in this case...

 

Sit down and spend some time thinking about the function of the addon.  What does it do, how does it do it.  Can it be changed to a more modular idea (eg, a box or content module).  

 

Typical example:

 

- member approval

In an existing addon made some years ago, there is all manner of core code changes, which for back then was fine.  I took the idea (disallow checkout until approved) and recoded it into a Header Tag.  That header tag module grabs the ID of the logged in customer, looks at what page they are attempting to access and if that page is checkout_* it returns them back to shopping_cart.php with a messagestack saying "you are not yet approved!".  So...no core changes, it is a simple drop in module, turn it on in admin, done.

 

Another example:

Something more complicated.  A system to allow credit balances and a way to spend them.  An existing addon changes -loads- of core files.  With some lateral thinking I was able to get that down to 1 core change (and that could have been done with a hook, I just didn't have time to properly finish it).  So instead of a bunch of core changes, it is just turn on a couple of modules and that is it...the whole system in place ready to go.

 

Of course, some addons are so invasive, that there is no option but to change core.  In this case, instead of adding a bunch of code to 10 or 15 files, you could explore the Hook system, and addin your own hooks.  The hooks admin page shows what hooks are doing and where they are - so if you ever then come to upgrade, you know which files have been touched (by hooks)...

 

In general, take the idea of the existing addon, and see what can be done to minimise it's invasiveness.  Of course, that also depends on the skill level of coding and intimate osc knowledge - some people cannot see code for what it is.  In this case, they have no option but to change core or to farm out the changes to someone who can see ways to achieve the "dont abuse the core" ethos...

 

Make sense ?

Link to comment
Share on other sites

@@burt, you hit the nail on the head here;

 

 Of course, that also depends on the skill level of coding and intimate osc knowledge - some people cannot see code for what it is.

 

I have easily removed the reference to filenames.php and also removed much of the use of TABLE_ to reduce the changes in database_tables.php ... And in the case of "this" addon I should even be able to update the now included content module to include all the required sql for install.

 

Its a start I guess.... but at the end of the day I just don't have the skill to see the bigger picture "in code". Don't get me wrong... I see the "big picture" for OsC... just no clue how to code it....

Link to comment
Share on other sites

@@greasemonkey

 

Scott maybe a few of us could tackle a contribution and see what we can do with it.  It would be a good learning experience both from a coding point of view as well as an opportunity to put some of these best practices to good use.   I'm sure if we get stuck or start down the wrong path that someone would step up and set us straight -- and enjoy doing it too.  (w00t)   I'm in if you'd want to have a go at it.

 

Dan

Link to comment
Share on other sites

@@Dan Cole I too enjoy it. This is how I've learned to manage much of the code in my own store. Don't get me wrong... I hire coders often... most important when I do hire a coder, because of what I've learned I don't feel as though I can been taken advantage of (I have been in the past).

 

In this case I'm in over my head.

 

@@burt, ok I was going to reply in more detail... but I have a feeling this may get off track. So I will keep it brief... The addon in question (SPPC) is many years old and as mentioned requires dozens of core file changes, and on top, hasn't been updated significantly since 2008. There have been others (like me) who have tried to keep this addon "working" and I think this is all I'm capable of.

 

As a shop owner I'm definitely not the right person to be making the changes this addon requires for long term viability (short term ... 2.3.x .... I think I can handle) inside the future OsC (say 2.4 as an example). That said, as I mentioned to Dan.... I have learned TONS by doing much of this type of work myself... and I enjoy it doing it in my spare time. And I believe it helps the community if I can (because know one else is......) make this addon "more" responsive friendly to install for the newcomers to both OsC (in particular for those interested in responsive).

Link to comment
Share on other sites

@@greasemonkey I specifically did not @mention any names as my post was not aimed at anyone in particular.  And definitely not aimed at the likes of you and Dan and others who know who they are, the ones who do support osc and its dev's.  

 

As for SPPC, here's some thoughts to ponder...

 

At it's heart what does it do:

 

1.  allow to create groups

2.  allow to assign customers to group

3.  allow to assign different prices per group

4.  show assigned price if customer is in a group

5.  use price to work out cost

6.  a bunch of other over-engineered stuff that hardly anyone uses

 

Break it down;

 

1.  allow to create groups.

Admin side:

1a.  new box (or addition to existing box to link to new groups page).  No core changes...

1b.  new page + lang file for adding/editing/deleting groups (retail, wholesale, etc etc).  No core changes...

Shop Side:  

None.

 

2.  assign customer(s) to group

Admin side:

New dropdown in customers.php.  Unfortunately a core code change.

Possible to make a new page to assign csutomers to group.  In this case, more work, but no core changes.

Shop Side:

None

 

3. assign price for each group per product

Admin side:

New input boxes in categories.php.  COre code change :(

Possible to make a new page to assign price - product - group.  In this case, more work, but no core changes.

Shop Side:

None

 

4. show assigned price if customer is in group

Shop Side:

Product Info content module to show the price for the group of the logged in customer.  No core changes.

Admin Side:

Install the content module

 

5.  Use group prices

Shop Side:

Order Total module which works out the difference between the "retail" group (the default group) and the "assigned" group of the logged in customer.  Order Total Module now reduces the Total to pay by that amount.  In effect a discount module.

Admin Side:

Install the Order Total module

 

I guess a "Simple SPPC"...

 

SQL needed:

 

a.  groups table

b.  customer_group column in customers table

c.  groups_prices_products table

Link to comment
Share on other sites

@@burt,

 

2.  assign customer(s) to group

Admin side:

Possible to make a new page to assign csutomers to group.  In this case, more work, but no core changes.

ok step 2 done... just made a new file (assign_customers_group.php) and new link from new box

 

Now have no core changes admin/includes/filenames.php, admin/customers.php, admin/includes/languages/english/customers.php and admin/includes/boxes/customers.php

Link to comment
Share on other sites

I see another great progress here.

Scott asked how would it be possible to change/improve the SPPC addon and burt offered very good guidance. I think what some of us lack is the understanding of how things could be made easier. I myself many times over engineere things and then have my eyes opened by henry or burt with an easier solution.

 

Why not have a thread where people could ask how to make addon X or Y better with no core changes and then people with more experience and knowledge could offer rough guidance as burt just did for SPPC.

 

I have another addon in my mind and would very much like guidance there too. And i am sure there more out there...

 

I think shopowners also want to participate and not just be a bystander.

If we would wait and hope that some dev or pro coder comes and upgrades addon X or Y then we can wait for eternity since that is not likely to happen.

Link to comment
Share on other sites

@@Tsimi Maybe this (these) should go into their own threads.... I'll let the mods decide.

 

That said, I've moved all the required sql into the login content module included with my file set. Including the un-install... This worries me.

 

Questions;

 

Do you think anyone is dumb enough to un-install and then wonder where all the SPPC data went? Should the un-install of the content module maybe "not" blow out all SPPC data? What is the best practice in this regard?

 

Lambros, I know you have done this with your Wishlist mod... And others please comment.

 

@@burt, further to your post. In my spare time I'm going to update a few more items in the current file set (more for my own education) and then start working on a SPPC "Lite". Removing much of the "less" used features.

 

@@Dan Cole, I welcome your help if you are interested... Keeping in mind this is a (very) part time project with no timeline whatsoever... and I will need a fair amount of help with the catalog side in particular.

Link to comment
Share on other sites

  • 2 months later...

@@greasemonkey I specifically did not @mention any names as my post was not aimed at anyone in particular.  And definitely not aimed at the likes of you and Dan and others who know who they are, the ones who do support osc and its dev's.  

 

As for SPPC, here's some thoughts to ponder...

 

At it's heart what does it do:

 

1.  allow to create groups

2.  allow to assign customers to group

3.  allow to assign different prices per group

4.  show assigned price if customer is in a group

5.  use price to work out cost

6.  a bunch of other over-engineered stuff that hardly anyone uses

 

Break it down;

 

1.  allow to create groups.

Admin side:

1a.  new box (or addition to existing box to link to new groups page).  No core changes...

1b.  new page + lang file for adding/editing/deleting groups (retail, wholesale, etc etc).  No core changes...

Shop Side:  

None.

 

2.  assign customer(s) to group

Admin side:

New dropdown in customers.php.  Unfortunately a core code change.

Possible to make a new page to assign csutomers to group.  In this case, more work, but no core changes.

Shop Side:

None

 

3. assign price for each group per product

Admin side:

New input boxes in categories.php.  COre code change :(

Possible to make a new page to assign price - product - group.  In this case, more work, but no core changes.

Shop Side:

None

 

4. show assigned price if customer is in group

Shop Side:

Product Info content module to show the price for the group of the logged in customer.  No core changes.

Admin Side:

Install the content module

 

5.  Use group prices

Shop Side:

Order Total module which works out the difference between the "retail" group (the default group) and the "assigned" group of the logged in customer.  Order Total Module now reduces the Total to pay by that amount.  In effect a discount module.

Admin Side:

Install the Order Total module

 

I guess a "Simple SPPC"...

 

SQL needed:

 

a.  groups table

b.  customer_group column in customers table

c.  groups_prices_products table

 

Just was thinking to give this a try. Now I'm wondering if it wouldn't be enough for 99.9% of all stores just to have 2 groups: retail and wholesale??

Would be much easier just add  a wholesale customer option. What do you think about.

 

Did anyone else begin already working on this??

Link to comment
Share on other sites

@@raiwa

 

I have figured out but I should change price functions finaly and could not avoid a small core changes.

:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Link to comment
Share on other sites

@@raiwa I've redone (amateurish I'm sure) much of the admin to have much less core changes.

 

Remove the attribute, mail & newsletter functions (which I would bet almost no one uses different attributes per pricing level) and you are almost there....

 

I was going to release what I had done today anyway... To fix some errors.

 

Please Rainer help (or take over where I left off)... cause I feel its well beyond my skill level. I just uploaded a new package to the "old" SPPC.... which can still stick around for those who must have "full" functionality.

 

http://addons.oscommerce.com/info/716

Link to comment
Share on other sites

Hello Scott @@greasemonkey,

 

I would like very much to give you a help, but my approach is different. I try to start the SPPC from scratch instead to strip featured from the old version.

I would rather call it SPPC ultra light reloaded. However I'll have a look on your last version when I find some time.

 

@@Gergely, @@burt,

 

Here is what I did:

 

Database changes:

ALTER TABLE `customers` ADD `customers_wholesale` CHAR(1) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL ;
ALTER TABLE `products` ADD `products_ws_price` DECIMAL(15,4) NOT NULL AFTER `products_price`;

Admin changes:

- Add a retail/wholesale selection drop down to customers.php

  Add a wholesale customer flag to the customer listing in customers.php

- Add wholesale net and gross price input field to categories.php

 

Catalog changes:

- create a product_info content module showing the wholesale price if customer is logged in, wholesale customer and wholesale price > 0

- modified shopping_cart class (function calculate and function get_products):

 use wholesale price if customer is logged in, wholesale customer and wholesale price > 0

 

Example for function calculate:

        $product_query = tep_db_query("select products_id, products_price, products_ws_price, products_tax_class_id, products_weight from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
        if ($product = tep_db_fetch_array($product_query)) {
          $prid = $product['products_id'];
          $products_tax = tep_get_tax_rate($product['products_tax_class_id']);
          if ( tep_session_is_registered('customer_id') && MODULE_CONTENT_PRODUCT_INFO_WS_PRICE_STATUS == 'True' && $product['products_ws_price'] > 0 ) {
          	$products_price = $product['products_ws_price'];
          } else {
          	$products_price = $product['products_price'];
          }

MODULE_CONTENT_PRODUCT_INFO_WS_PRICE_STATUS is only true if customer is wholesale customer:

    function isEnabled() {    	
    	$check_customer_query = tep_db_query("select customers_wholesale from customers where customers_id = '" . (int)$customer_id . "'");
    	$check_customer = tep_db_fetch_array($check_customer_query);
    	if (tep_session_is_registered('customer_id') && MODULE_CONTENT_PRODUCT_INFO_WS_PRICE_STATUS == 'True' ) {
    		return $this->enabled;
    	} else {
    		$this->enabled = false;
    	}
    }

Now one problem:

I wanted to include in module a shopping cart class extension to apply the modifications to the function calculate and function get_products, couldn't get it to work.

The class extension loads correct, but the modified prices do not apply. When I modifie the shopping_cart class itself it works.

Any ideas??

 

Resume:

I know that the core changes are not ideal from the installing process point of view:

 

Discussion:

Easy installation and no core file changes versus user friendly:

If we add 2 new files: customer group and wholesale prices to Admin, we have no core changes but the daily user has to move to 2 places for adding wholesale customer and wholesale price.

With my solution they add/modify a product and introduce the wholesale price in the same place where they put the normal price instead to close product => go to wholesale price page => search product => open product => add wholesale price.

Not so a big difference for flagging wholesale customer, but also 2 pages to manage.

 

On catalog:

I believe modifying the shopping_cart class makes the wholesale price applying more transparent to the cutomer than to have to wait until the order confirmation page to see the discount reflected on order totals.

If it will be possible to get the class extension to work via module, no core change neither.

 

Limits:

- only one additional wholesale group => enough for most store needs??

- no attribute wholesale price for now, can be added

- no different wholesale tax, standard tax settings apply => enough for most store needs??

- no wholesale shipping prices, can be realised with different shipping modules via wholesale customer checks

 

regards

Rainer

 

PS: if you are interested to try I can pack a zip

Link to comment
Share on other sites

@@raiwa I think your way is the way forward.

 

If someone requires more features they can use the original (hopefully I've made it a tad easier).

 

Let me know if you require help... I'm happy to test.

I'll compile a zip with all files and changes the next days

 

Just found an error in one posted function, this is the correct version, the above one was a dev version:

    function isEnabled() {
    	global $customer_id;    	
    	$check_customer_query = tep_db_query("select customers_wholesale from customers where customers_id = '" . (int)$customer_id . "'");
    	$check_customer = tep_db_fetch_array($check_customer_query);
    if (tep_session_is_registered('customer_id') && $check_customer['customers_wholesale'] == '1' ) {
    		return $this->enabled;
    	} else {
    		$this->enabled = false;
    	}
    }

Thank You!!

Rainer

Link to comment
Share on other sites

@@raiwa

 

We should thinking together in community and have to change the core price display codebase. I didnt find any good solution but I wonder that you could get without codebase changing.

Here is my research results: http://www.oscommerce.com/forums/topic/408019-new-sppc-addon-for-v234-bs-v24/#entry1732301

:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Link to comment
Share on other sites

In a "simple" SPPC module, does the "new price" of the product have to be shown everywhere ?

Why ?

Keep it simple in a simple module. Show the new price at the product_info page only...

 

An alternative;  HOOK the product price ?

Link to comment
Share on other sites

Inside the new content module you should call a NEW shopping_extended_cart_class

 

So you create a new class and extend the original shopping_cart class with it.

 

Goodluck!!

I tried this and the problem was that when I added a product to the shopping cart I got the message that product xy has been successfully added to the shopping cart but the cart showed empty. I only had the modified functions in the extended class, would I need to repeat all functions in the extended  shopping cart class??

Link to comment
Share on other sites

In a "simple" SPPC module, does the "new price" of the product have to be shown everywhere ?

 

Why ?

 

Keep it simple in a simple module. Show the new price at the product_info page only...

 

An alternative;  HOOK the product price ?

Yes, i did so, showed only in product info the wholesale price via content module. But if we extend the currency class, like gergely suggested, we can show the wholesale price evrywhere with only one modification via extended currency class.

Link to comment
Share on other sites

@@wHiTeHaT, @@burt, @@Gergely,

 

One general problem I found regarding class extensions:

 

If one add on (module or whatever) extends lets say for example the currency class:

Add on A:

   class currencies_modA extends currencies {

And I need to extend the currency class again by another add on B:

   class currencies_modB extends currencies {

My modifications from Add on A will be lost, I have to extend currencies_modA instead, to get both extensions working:

class currencies_modB extends currencies_modA {

Is this correct??

 

Then it would be necessary for each class extension to analyse first if a class has already an extension:

I imagine it could be done like this:

get_declared_classes,

then check if the parent class has already exensions by searching for class extensions beginning with the same name like the parent class, check for the class parent (class_parents) and extend the last loaded extension class instead of the parent class.

 

And what happens if someone has the glorious idea to give the extension class a different name:

myfantasyname extends currencies {

Am I right with this or I'm missing some basic method to do this different??

 

Thank You!!

Link to comment
Share on other sites

Class extentions are prevail on the class itself. Use exact if statement declaration to prevent conflict.

 

If is_enabled() then extend class by your way.

xml module description try manage these conflicts http://library.oscommerce.com/Online&en&oscom_2_4&developers&apps

:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Link to comment
Share on other sites

@@wHiTeHaT, @@Gergely,

Got it to work for now only modifying application_top.php like follows:
 

// include shopping cart class
  require(DIR_WS_CLASSES . 'shopping_cart.php');
  require(DIR_WS_CLASSES . 'shopping_cart_mod.php');

********************

// create the shopping cart
  if (!tep_session_is_registered('cart') || !is_object($cart)) {
    tep_session_register('cart');
    $cart = new shoppingCart;
    $cart = new shoppingCartMod();
  }

When I begin to move:

    $cart = new shoppingCartMod();

out of the if statemnet it doesn't work.

I also tried to separate this:

  if (!tep_session_is_registered('cart') || !is_object($cart)) {
    tep_session_register('cart');
    $cart = new shoppingCartMod;
  }

Tried to move it at the end of application_top or into a own header_tag module, no way. any ideas??

The shopping cart class extension is this:
includes/classes/shopping_cart_mod.php:

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2012 osCommerce

  Released under the GNU General Public License
*/
  if (class_exists('shoppingCart')) {
    class shoppingCartMod extends shoppingCart {

    public function calculate() {
      global $currencies;

      $this->total = 0;
      $this->weight = 0;
      if (!is_array($this->contents)) return 0;

      reset($this->contents);
      while (list($products_id, ) = each($this->contents)) {
        $qty = $this->contents[$products_id]['qty'];

// products price
        $product_query = tep_db_query("select products_id, products_price, products_ws_price, products_tax_class_id, products_weight from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
        if ($product = tep_db_fetch_array($product_query)) {
          $prid = $product['products_id'];
          $products_tax = tep_get_tax_rate($product['products_tax_class_id']);
          if ( tep_session_is_registered('customer_id') && MODULE_CONTENT_PRODUCT_INFO_WS_PRICE_STATUS == 'True' && $product['products_ws_price'] > 0 ) {
          	$products_price = $product['products_ws_price'];
          } else {
          	$products_price = $product['products_price'];
          }
          $products_weight = $product['products_weight'];

          $specials_query = tep_db_query("select specials_new_products_price from " . TABLE_SPECIALS . " where products_id = '" . (int)$prid . "' and status = '1'");
          if (tep_db_num_rows ($specials_query)) {
            $specials = tep_db_fetch_array($specials_query);
            $products_price = $specials['specials_new_products_price'];
          }

          $this->total += $currencies->calculate_price($products_price, $products_tax, $qty);
          $this->weight += ($qty * $products_weight);
        }

// attributes price
        if (isset($this->contents[$products_id]['attributes'])) {
          reset($this->contents[$products_id]['attributes']);
          while (list($option, $value) = each($this->contents[$products_id]['attributes'])) {
            $attribute_price_query = tep_db_query("select options_values_price, price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " where products_id = '" . (int)$prid . "' and options_id = '" . (int)$option . "' and options_values_id = '" . (int)$value . "'");
            $attribute_price = tep_db_fetch_array($attribute_price_query);
            if ($attribute_price['price_prefix'] == '+') {
              $this->total += $currencies->calculate_price($attribute_price['options_values_price'], $products_tax, $qty);
            } else {
              $this->total -= $currencies->calculate_price($attribute_price['options_values_price'], $products_tax, $qty);
            }
          }
        }
      }
    }

    public function get_products() {
      global $languages_id;

      if (!is_array($this->contents)) return false;

      $products_array = array();
      reset($this->contents);
      while (list($products_id, ) = each($this->contents)) {
        $products_query = tep_db_query("select p.products_id, pd.products_name, p.products_model, p.products_image, p.products_price, p.products_ws_price, p.products_weight, p.products_tax_class_id from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_id = '" . (int)$products_id . "' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "'");
        if ($products = tep_db_fetch_array($products_query)) {
          $prid = $products['products_id'];
          if ( tep_session_is_registered('customer_id') && MODULE_CONTENT_PRODUCT_INFO_WS_PRICE_STATUS == 'True' && $products['products_ws_price'] > 0 ) {
          	$products_price = $products['products_ws_price'];
          } else {
          	$products_price = $products['products_price'];
          }

          $specials_query = tep_db_query("select specials_new_products_price from " . TABLE_SPECIALS . " where products_id = '" . (int)$prid . "' and status = '1'");
          if (tep_db_num_rows($specials_query)) {
            $specials = tep_db_fetch_array($specials_query);
            $products_price = $specials['specials_new_products_price'];
          }

          $products_array[] = array('id' => $products_id,
                                    'name' => $products['products_name'],
                                    'model' => $products['products_model'],
                                    'image' => $products['products_image'],
                                    'price' => $products_price,
                                    'quantity' => $this->contents[$products_id]['qty'],
                                    'weight' => $products['products_weight'],
                                    'final_price' => ($products_price + $this->attributes_price($products_id)),
                                    'tax_class_id' => $products['products_tax_class_id'],
                                    'attributes' => (isset($this->contents[$products_id]['attributes']) ? $this->contents[$products_id]['attributes'] : ''));
        }
      }

      return $products_array;
    }
   }
  }
?>

Thanks

 

PS: I deleted the session between each test

Link to comment
Share on other sites

@@raiwa
I dont know the real reason but somehow the SESSION and the global class $cart has logic conflict when you would like to extend shopping cart.

:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...