Cs-Cart using classes

Some times cs-cart add-ons are getting larger than a 200 lines of code. Controller actions get longer, functionality requires more code. For example my ShopFeed addon is around 2800 lines of php code. Not including smarty templates. Putting code in func.php is the obvious solution. But there you have to work with functional code and the worse is that func.php is included in any case. If your addon is for backend, func.php is included even in frontend calls. A technic I developed over time is to pack my code in classes so I keep my controllers shorter and include classes from controller file. It works fine but sometimes is error prone and relative includes are boring…
Since 4.x series cs-cart core implements autloading for their Tygh library. After taking a look at mail marketing addon I got a new perspective. Autoloader also looks in addons directories for Tygh extensions!

So, if you create in your addon for example myaddon and a class named MyClass, you have to:

file: app/addons/myaddon/Tygh/Something/MyClass.php

namespace Tygh\Something;
class MyClass {
  // your code
}

in any place:

use Tygh\Something\MyClass;

$a = new MyClass();

That’s it! No requires, not loading uneeded code. Comfort of development, no server overload.

Keep your controllers short. Follow the suggestion that is said for any MVC framework, move code to a class. For example, if you have a controller like this

file: addons/myaddon/controllers/backend/products.post.php

if( $mode=="update") {
  // many lines of code

}

refactor to:

file: addons/myaddon/Tygh/Slx/MyControllerAction.php

namespace Tygh\Slx;
class MycontrollerAction {
  public function updatePost($productId) {
    // many lines of code
  }
}

file: addons/myaddon/controllers/backend/products.post.php

use Tygh\Slx\MyControllerAction;
if( $mode=="update") {
  $a = new MyControllerAction();
  $a->updatePost($product_id);
  return;
}

You controller is now readable and it want evolve to a monster like some you see in the core of some projects.
A real life example is the controller from my slxEaseInventory addon, it looks like:
file: app/addons/slx_ease_inventory/controllers/backend/ease_inventory.php

use Tygh\SlxEaseInventory\EaseInventory2;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

	if( $mode=='update_opt_inventory' ) {
        $product_id = $_REQUEST['product_id'];
        $inAmounts = $_REQUEST['amount'];
        $inVarIds = $_REQUEST['varId'];
        $data = array();
        foreach($_REQUEST['combId'] as $idx => $vc) {
            if( isset($inAmounts[$idx]) ) {
                $data[$vc] = array( 
                    'amount'=> (int)$inAmounts[$idx],
                    'varId' => $inVarIds[$idx],
                    );
            }
        }
        
        $il = new EaseInventory2($product_id);
        $il->updateInventory($data);
        $suffix = ".update?product_id=". $product_id . "&selected_section=inventory2";
        return array(CONTROLLER_STATUS_OK, "products$suffix");
    }
}

Is the controller clean? The code that actually does the job is in three classes, summing around 600 lines. Can you picture all that code in the controller? or having it in func.php, which means 600 would be loaded in every page view, even in frontend? 600 lines more might not seem an issue, but how about 6000 lines? there are cs-cart installation with 10 or more heavy duty addons.

If you need a function in a template lets name it myTplFunc, there is no workaround declare it to func.php, but it is long, or calls other functions you created in func.php then pack that functionality to a class and from the function call the class method. For example:

file: app/addons/myaddon/func.php

function myFuncA($a, $b) {
}

function myFuncB($c, $d) {
}

function myTplFunc($e) {
  // ...
  $r = myFuncA(1,2);
  $r2 = myFuncB(3,4);
  return $r2;
}

Refactor to:
file: addons/myaddon/Tygh/Slx/TplClass.php

namespace Tygh\Slx;
class TplClass {
  private function myFuncA($a, $b) {
  }
  private function myFuncB($c, $d) {
  }

  public function tplFunc($e) {
    // ...
    $r = $this->myFuncA(1,2);
    $r2 = $this->myFuncB(3,4);
    return $r2;
  }
}

file addons/myaddon/func.php

  use Tygh\Slx\TplClass;

  function myTplFunc($e) {
    return new TplClass()->tplFunc($e);
  }

Note: Slx in namespace is just an example. It can be what ever suites you.

Advantages: file func.php now is only 4 lines long. That means only 4 lines are loaded in every page view. All OOP benefits apply to your code.