This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

In concrete5.6 and later, core classes are overridden and extended by creating a file that corresponds to a core class stub, which extends the actual core class. This is somewhat different from how concrete5 handled overriding core classes in the past.

That may sound confusing-- but once you're familiar with the basic concept, you will likely find it clever and quite useful when building sites with unique requirements in concrete5.

Note: If you are new to the general concept of concrete5 overrides, it would be wise to check out another article before continuing: Change Things Without Hurting Anything: Overrides

As an example the 'User' class actually extends the 'Concrete5_Model_User' class which is the class that contains all of the properties and methods you would interact with via the 'User' class.

// location: concrete/core/models/user.php
class Concrete5_Model_User extends Object {

    public $uID '';
    public $uName = '';
    public $uGroups = array();
    public $superUser = false;
    public $uTimezone = NULL;

    // ...Remaining code below
}

// location: concrete/models/user.php
class User extends Concrete5_Model_User {}

Technically speaking, if you were not overriding the core class the following two snippets would, beyond some technicalities(__CLASS__ etc), result in functionally identical instances.

$user = new User;
$same_user = new Concrete5_Model_User;

Of course one would always use the former constructor to honor any overrides that may exist now or into the future.

The magic in all of this is that while taking advantage of the file overrides system you may already be familiar with in concrete5, you no longer have to override the entire class . Instead, you can simply extend the core class, adding and/or modifying only the methods and properties you are interested in. You can even add additional methods if you are so inclined.

As example, let's wake someone up in the middle of the night if there is an exception logged on our site by overriding the Log::write() method

// original location: concrete/libraries/log.php
// override location: libraries/log.php

class LogEntry extends Concrete5_Library_LogEntry {}
class Log extends Concrete5_Library_Log {

/**
 * Both of these methods are used for sending
 * emails so we are overriding both
 * 
 * Note that we are then calling the parent
 * method afterwards. This allows us to add functionality
 * to methods and maintain their original purpose
 */
public function close() {
        if($this->log === LOG_TYPE_EXCEPTIONS) {
            self::wakeUpAdmin($this->sessionText);
        }
        parent::close();
    }
    public static function addEntry($message, $namespace = false) {
        if($namespace === LOG_TYPE_EXCEPTIONS) {
            self::wakeUpAdmin($message);    
        }
        parent::addEntry($message, $namespace);
    }

    /**
     * This is a new method we've just added
     */
    protected static function wakeUpAdmin($message) {
        $mh = Loader::helper('mail/helper');
        $mh->setSubject(t('Site Exception Occurred'));
        $mh->setBody($this->sessionText);
        $mh->to('sleeplessinportland@example.com', 'John Admin');
        $mh->sendMail();
    }
}     

One thing you may notice in the above example is that while we are only overriding the 'Log' class, we are also including 'class LogEntry extends Concrete5_Library_LogEntry {}'.

This is because both of these classes are included in the original 'log.php' file. Remember, when overriding a file in concrete5 the original file is never included and therefore, as in this case, any class definitions in that file will never occur. Because of this we need to be sure to copy over all definitions into our new file. Even if do not plan on extending them.

Before I leave you there are a few more things to note about concrete5 overrides.

  • This approach is intended for single site development, not concrete5 Addon development.

  • Although the new override system allows for a more elegant way of adding functionality to core classes, one should remain vigilant in the face of concrete5 core upgrades. Stuff may very well change over time!

  • Not all files can be overridden in this manner. Only files that extend the core classes can be extended with overrides.

Loading Conversation