I can not find how to write in log files of extentions Language Manager the following information:
-user name
-name of the constant
- old value
- new value

Please see the image example of language constant

As I understand I need to write a hook and put this code in it:

JLog::add('user:'.$userName .' constantName:'.$constantName.' oldValue:'.$oldValue.' newValue:'.$newValue,JLog::INFO,'com_language.monitoring');

But as I am new to Joomla, I do not know how to do it in a proper way, so after updating Joomla version everything still works.

Thank you

1 Answer 1


Usually you would use "onContentBeforeSave" function of content-type plugin, but for some reason com_languages doesn't launch "onContentBeforeSave" and "onContentAfterSave" events. However there is another option. A bit more ugly, using system plugin and onAfterRoute event.

First at all, we need XML file with some info about plugin (required by Joomla! installer), nothing fancy. Be sure that 'group' is set to 'system':

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.5" type="plugin" group="system">
<author>Brad Markle</author>
<copyright>Some copyright Info</copyright>
<license>Your License</license>
<authorEmail>[email protected]</authorEmail>
<authorUrl>Your url</authorUrl>
<description>Extension description</description>
    <filename plugin="loglangoverrides">loglangoverrides.php</filename>

When we have our XML file, we can jump into PHP code:


// No direct access
defined("_JEXEC") or die;

// Create plugin class. 'plgSystem' part is a MUST
class plgSystemLogLangOverrides extends JPlugin {

    // Define onAfterRoute() function. This approach have one great con. 
    // If Joomla! encounters during save process, it will still log info.
    // You can experiment with other System Plugin Events, described here:
    // https://docs.joomla.org/Plugin/Events/System#onAfterDispatch
    public function onAfterRoute() {
        $jinput = JFactory::getApplication()->input;

        // We should get 'task', to run script only during lang-overrive saving.
        // Tasks for override saving are override.save, override.apply
        // and override.save2new (depends which button you've clicked)
        $task = $jinput->getString("task", "");

        // Now we check this is the task we are looking for
        if (in_array($task, array('override.save', 'overrides.delete','override.apply', 'override.save2new')) !== false) {
            // Import JLog stuff. As far as I know it's not needed
            // anymore, just an old habit

            // Here we get 'jform' array from $_POST array using JInput
            $formData = $jinput->get('jform', '', 'array');

            // Get username
            $userName = JFactory::getUser()->username;

            // Get constant name from $formData array
            $constantName = $formData['key'];

            // Here we are trying to get an old value if exists.
            // You can find function getOldValue below
            $oldValue = self::getOldValue($constantName);

            // Get new value from array
            $newValue = $formData['override'];

            // Add new JLogger (required), let it save entries to
            // '/administrator/logs/com_languages.overrides.log.php' file
            JLog::addLogger(array('text_file' => 'com_languages.overrides.log.php'));

            // Add entry to log (you only need message)
            JLog::add('user:' . $userName . ' constantName:' . $constantName . ' oldValue:' . $oldValue . ' newValue:' . $newValue);

    // function to get an old value of an override. Most is just 'stolen'
    // from
    // /administrator/components/com_languages/models/override.php -> 
    // save() function
    protected function getOldValue($key) {
        // We must getApplication to be able to get language and client
        $app = JFactory::getApplication();

        // Add com_languages helper, required for parseFile function
        require_once JPATH_ROOT . '/administrator/components/com_languages/helpers/languages.php';

        // Import filesystem stuff - just like previous jimport,
        // probably just an old habit

        // Get client (admin or site)
        $client = $app->getUserState('com_languages.overrides.filter.client', 0);

        // Get language
        $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB');

        $client = $client ? 'administrator' : 'site';

        // Get override file
        $filename = constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini';
        $strings = LanguagesHelper::parseFile($filename);

        // Check if selected constant exists. If yes - return 'old value'
        if (isset($strings[$key])) {
            return $strings[$key];

        // else return 'NO_OLD_VALUE'
        return 'NO_OLD_VALUE';


And that's all. Actually more comments than code itself. If you don't want to get too much into details, just save XML part as 'loglangoverrides.xml' and PHP part as 'loglangoverrides.php', zip it and install on your Joomla! instance.

Best regards and good luck!

P.S. This code is not very well tested.

  • Thank you Krossfire, can you please precise what folder should I put those files in? Sorry, I am new to Joomla.
    – Alex Ros
    Jul 13, 2016 at 1:38
  • Don't 'sorry', everyone must start somewhere. You should compress those files into single archive supported by your server's PHP version (tar, tar.gz, zip, bz2, etc.). Then login to Joomla! admin panel, bo to Extensions->Manage->Install. There switch to 'Upload Package File' tab (if not already selected), choose your archive with plugin and click 'Upload & Install'. Then go to Extensions->Plugins, in searchbox enter 'override' and search. It should display newly installed plugin - enable it and you are ready to go. And here is compressed plugin, if required: goo.gl/rEK75u
    – Krossfire
    Jul 13, 2016 at 11:57
  • 1
    Krossfire, just found one small code correction to make to make it fully operational ( you wrote overriVe.save2new and forgot delete task ). So please change it in your answer to ` if (in_array($task, array('override.save', 'overrides.delete','override.apply', 'override.save2new')) !== false) {`
    – Alex Ros
    Jul 13, 2016 at 22:04
  • Alex Ros, thank you very much for pointing it out. Fixed already, best regards.
    – Krossfire
    Jul 14, 2016 at 23:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.