10

I have seen screenshots of a solution, there the Joomla version is getting detected by only accessing the page via http.

E.g. the solution displayed all 3 digits of a version of Joomla. e.g. 2.5.28, or 1.0.x and so on by only accessing the webpage via http.

I want to create a small application to be informed about the version installed on the server. Since I do not have always full access to the FTP storage, I would like to know how I can extract the Joomla version from a simple HTTP GET.

14

Ok so this is what I was writing yesterday.

For Joomla 2.5 and 3.x only

  1. Check if the http:// prefix is missing from the URL. If it is, then it adds it. Note that In this case I have not taken https:// into consideration.
  2. It then tries to get the Joomla manifest file and checks whether is exists/is readable.
  3. If it exists then it gets the value from the <version> tag.
  4. If the XML file is not readable, then I have written a fallback to get the TinyMCE version. Again, it will try to read the value from the <version> tag.
  5. From here on, I spent quite a long time going through the release notes for each Joomla version to see which versions has a TinyMCE update. Those that did, I added to the switch block further own in the code. This approach will not give the exact version apart from 2 of them, but it will give an average. I was thinking about detecting the jQuery version but then realised that a lot of people update the core version to the latest which would then make the results inaccurate.
  6. If the TinyMCE version cannot be found (so basically a non-Joomla site), then the function will return Unknown.

Note: This script uses CURL so make sure it's enabled on your server.


class JoomlaVersions
{
    public function getJoomlaVersion($site)
    {
        // Add http prefix if missing
        if (strpos($site,'http://') === false)
        {
            $site = 'http://'.$site;
        }

        // Get the number value from the <version> tag in the XML file
        $dom = new DOMDocument;
        $url = $site . '/administrator/manifests/files/joomla.xml';
        libxml_use_internal_errors(true);

        $exists = $this->XMLexists($url);

        if( $exists )
        {
            $dom->load($url);
            $versions = $dom->getElementsByTagName('version');

            foreach ($versions as $version) 
            {
                return $version->nodeValue;
            }
        }
        else 
        {
            $mce = $this->getTinyMCEversion($site);

            if($mce)
            {
                // Base Joomla version on the TinyMCE version
                switch ($mce)
                {
                    case '3.5.6':
                        $joomla = '3.0.0 - 3.1.6';
                        break;
                    case '4.0.10':
                        $joomla = '3.2.0 - 3.2.1';
                        break;
                    case '4.0.12':
                        $joomla = '3.2.2';
                        break;
                    case '4.0.18':
                        $joomla = '3.2.3 - 3.2.4';
                        break;
                    case '4.0.22':
                        $joomla = '3.3.0';
                        break;
                    case '4.0.28':
                        $joomla = '3.3.1 - 3.3.6';
                        break; 
                    case '4.1.7':
                        $joomla = '3.4.0';
                        break; 
                    default:
                        $joomla = '3.x';
                }

                return $joomla;
            }
            else 
            {
                return 'Unknown';
            }
        }   
    }

    // Get TinyMCE Version 
    private function getTinyMCEversion($site)
    {
        $tinymce = $site . '/plugins/editors/tinymce/tinymce.xml';      
        libxml_use_internal_errors(true);

        $exists = $this->XMLexists($tinymce);

        if( $exists )
        {
            $dom->load($tinymce);
            $vTag = $dom->getElementsByTagName('version');

            foreach ($vTag as $tag) 
            {
                return $tag->nodeValue;
            }
        }
    }

    // Check file exists using CURL
    private function XMLexists($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_exec($ch);
        $getinfo = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $getinfo;
    }

}

Then call the function like so:

$version = new JoomlaVersions;
echo $version->getJoomlaVersion('http://joomla.org');

I've created a module on my website as a Tool for other users:

Joomla Version Detection Tool

I've also created a Github repository if you wish to fork it or submit pull requests:

Joomla Version Detect Github Repo

Anyway, as some of you know, I'm not a backend developer so there are probably a lot of improvements which can be made to the code. If you have another solution or can update what I currently have, be sure to post it as a new answer.

  • great solution! Anyway it implies, that you have access to the /administrator/manifests/files/joomla.xml file. So this is not always the case. The other mentioned page has a solution, which detects the version only on the GET of the / page. So it is fully unclear how this is done. The apache logs tell only a simple get to / of the domain, nothing more. – hkais Jan 24 '15 at 14:15
  • 1
    I've added a Github repository link to the answer. – Lodder Jan 24 '15 at 14:18
  • Excellent answer which also helps answer the question I asked at joomla.stackexchange.com/q/182/120 – Neil Robertson Jan 25 '15 at 0:04
  • @Joomjunk I tried the script on your site to check several Joomla sites. Not working. The response is empty. – user5204 May 6 '15 at 21:04
  • @Marc - Some sites work, others won't due to the host not allowing read permissions for certain XML files which is how my the version detection works. There is another site that uses different methods for detecting the version, however I'm unsure as to how they do this. If I can figure out a more appropriate way of doing this, I will implement it. – Lodder May 6 '15 at 23:17
3

If you are interested only in versions of sites you manage, then you can create and install a small plugin which shares Joomla version by opening plugin URL, for example
http://example.com/plugins/getversion/getversion.php?configuredSecret

  • I did not need it yet so I don't have the code. But based on Lodder's answer, you can see how to read Joomla! mainfest file /administrator/manifests/files/joomla.xml in order to return the version number.

Note mostly for newbies: configuredSecret is one of classical approaches to share publicly visible channel only to authorized requests. It is commonly used for connecting two systems if there is no better way to protect integrating connection.

  • administrator/manifests/files/joomla.xml is the answer, for joomla 2.5 at least – Lynob Jun 27 '16 at 10:37
  • @Lynob – sure. In this case, the OP would like to have lightweight application which receives only single number, not entire XML file. So your solution is suitable for fat client, my solution for thin client. – miroxlav Jun 27 '16 at 12:39
0

I'll add this as a separate answer, as it's not exactly a code solution.

I've developed a Firefox extension that performs 2 XHR requests. The first one to the Joomla API site to get the latest version, the other to the joomla.xml file of the current website you're viewing. It will then compare the two versions and console.log() the result.

URL: https://github.com/C-Lodder/joomla-update-checker

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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