Class Not Found Error with custom Class Concrete5.8

2.3k views Asked by At

New to C5 and Namespaces. Trying to add my own class, but keep getting error that it can't find the class, even though PHPstorm seems to know where it is. Seems simple enough but I'm missing something.

Path to class application/src/cpi/funcs/Utils.php

Class

<?php

namespace Application\Src\Cpi\Funcs;

defined('C5_EXECUTE') or die(_("Access Denied."));

class Utils
{

    public function Getcreditcard_year($y = 10)
    {
        $currentYear = date("Y");
        $currentYearVal = date("y");
        $year_list = array();

        for ($i = 1; $i <= $y; $i++) { 
            $year_list[$currentYearVal] = $currentYear;
            $currentYear = $currentYear + 1;
            $currentYearVal = $currentYearVal + 1;
        } 
        return $year_list;
    }
}
?>

Code in View

<?php
use Application\Src\Cpi\Funcs\Utils;
$years = new Utils();
//$years->Getcreditcard_year();
?>
2

There are 2 answers

3
Gianni Acciarri On

A few core features have been updated in Concrete5.8 that change the way you should use namespaces. You have two options to go about this.

Option 1:

Concrete5.8 has had some minor updates to its core Routing which now uses application/src/concrete/ instead of application/src/ to search for your custom classes, and is triggered to look in to that folder when a class has \Application\Concrete\ in its namespace. Basically, you would do the following:

Class

Update the namespace of your class and move it to application/src/Concrete/Cpi/Funcs/Utils.php

<?php 
namespace Application\Concrete\Cpi\Funcs;

class Utils{
    ...
}

Code In View

use \Application\Concrete\Cpi\Funcs\Utils
...

Option 2

Re-enable the legacy Routing to read in application/src/ when \Application\Src\ is used in a class's namespace.

C5 core team have created a function to enable legacy namespaces, enableLegacyNamespace(), which you need call during the bootstrap. I've added the coded in my application/bootstrap/start.php file. Not sure if it is the best place to enable it but it works. The file now looks like this:

<?php
use Concrete\Core\Application\Application;
use Concrete\Core\Foundation\ClassLoader;

/*
 * ----------------------------------------------------------------------------
 * Instantiate concrete5
 * ----------------------------------------------------------------------------
 */

// This line allows us now to use \Application\Src\ in our class namespace
ClassLoader::getInstance()->enableLegacyNamespace();

$app = new Application();

...

Using this option means you don't have to modify or move your class and can use as you have it set up currently.

Just sharing some advice

I have my concrete5.8 sites to use both options. For my custom classes, I use option 2 but when I want to overwrite or expand a core class I use option 1 and place the file inside application/src/concrete/ and use the \Application\Concrete\ namespacing.

e.g.
Say, I want to extend the core PageController class. First, I create the php file and add it under application/src/concrete/. The file path would look like this: application\src\Concrete\Page\Controller\PageController.php. I am trying to mimic the folder path of its core file which is found in concrete\src\Page\Controller\PageController.php.

Class

<?php
namespace Application\Concrete\Page\Controller;

...

class PageController extends \Concrete\Core\Page\Controller\PageController
{
    ...
}

Then overwrite the core alias pathing with your custom alias inside application/config/app.php so concrete knows to read from a custom class instead:

return [
  'aliases' => [
    // extend the page controller class
    'PageController' => '\Application\Concrete\Page\Controller\PageController',
];

Hope this helps.

Cheers.

0
Chelsea Saffold On

Gianni's answer is still valid on c5 8.5.1, incase anyone is wondering. The correct path is application/src/Concrete, not application/src/concrete. If the c is not capitalized, c5 will through an error for not being able to find your class.