Creating Custom Code in the Application Directory

The easiest way to add this custom code to your Concrete CMS website is in the application/src directory. First, we'll add our PostList class (which extends Concrete\Core\Page\PageList) to the directory:

application/src/Page/PostList.php

Then, we'll make sure that our class is namespaced appropriately.

namespace Application\Page;

class PostList extends Concrete\Core\Page\PageList
{


}

Finally, in our application/bootstrap/autoload.php we'll register Application\Page as pointing to application/src/Page, using a custom PSR-4 autoloader

This goes in application/bootstrap/autoload.php:

$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader();
$classLoader->addPrefix('Application\\Page', DIR_APPLICATION . '/' . DIRNAME_CLASSES . '/Page');
$classLoader->register();

That's it! Concrete now knows that any class found in the namespace Application\Page will be loadable from application/src/Page/. Since this is standard PSR-4 behavior, you can now create multiple hierarchies of classes within the Application\Page namespace, and they will map directly (with case sensitivity) to the files found in application/src/Page and below.

Legacy Support

Users of Concrete prior to version 8 might be a little confused here. In 5.7.5.10 and earlier, you could add this file by simply namespacing it Application\Src\Page, and placing it in the same spot, no custom autoloader required. What gives?

Simply: we didn't like the look of \Src. It's not semantically pleasing, and it doesn't make a ton of sense when intermingled with code that doesn't have src. Better to add extra autoloading code for these custom behaviors, than to have a system that doesn't make as much sense and has a ton of inconsistencies.

However, if your website relies on custom code like this, and you don't want to re-namespace all your classes (and add custom autoloader code) you can re-enable this legacy support by adding this array to application/config/app.php:

'enable_legacy_src_namespace' => true

this will re-enable the autoloading of classes found in application/src/ to the namespace Application\Src.

Adding Custom Doctrine ORM Entities in the Application Directory

Is the code you'd like to add to application/src a Doctrine ORM entity? This is a custom class, mapped to a database table using PHP annotations. If so, you won't even need to create a custom autoloader; one is already mapped and ready to. Simply create your entity in application/src/Entity, and give it a namespace starting at Application\Entity. For example:

src/application/src/Entity/User/RegistrationRecord.php

will be found automatically, if the proper namespace and class is used:

namespace Application\Entity\User;
class RegistrationRecord
{

}

Important Note

You'll want to make sure that you import the ORM annotation namespace into this entity, in order to use this autoloader. So make sure your entity class looks like this:

namespace Application\Entity\User;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="UserRegistrationRecords")
 */
class RegistrationRecord
{

    /**
     * @ORM\Id @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

Instead of this:

namespace Application\Entity\User;

/**
 * @Entity
 * @Table(name="UserRegistrationRecords")
 */
class RegistrationRecord
{

    /**
     * @Id @ORM\Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

Interested in why this is the case? You'll want to read this..

Including Classes with Composer in your Concrete Project

Want to use Composer to download and install external libraries for your website? Information on that is coming soon.