#!/usr/bin/env php
<?php

class SupeeCheck
{
    public $_missing_patches = array();
    public $_ignore_patches = null;
    public $_magento_path;
    public $_exit_code = 0;

    public function run()
    {
        try {
            $this->checkSupee11155();
            $this->checkSupee11086();
            $this->checkSupee10975();
            $this->checkSupee10888();
            $this->checkSupee10752();
            $this->checkSupee10570();
            $this->checkSupee10415();
            $this->checkSupee10266();
            $this->checkSupee9767();
            $this->checkSupee9652();
            $this->checkSupee8967();
            $this->checkSupee8788();
            $this->checkSupee7405();
            $this->checkSupee7405v11();
            $this->checkSupee6788();

            $this->_missing_patches = array_unique($this->_missing_patches);
            natsort($this->_missing_patches);

            if (!$this->_missing_patches)
            {
                $ignored_text = '';
                if ($this->_ignore_patches)
                {
                    $ignored_text = '. ignored: ';
                    $ignored_text .= implode(', ', $this->_ignore_patches);
                }
                $this->_exit_code = 0;
                return 'OK: no missing patch found'.$ignored_text;
            }
            else
            {
                $this->_exit_code = 2;
                return 'CRITICAL: Missing patche/s: ' . implode(', ', $this->_missing_patches);
            }

        }
        catch (Exception $e)
        {
            //$e->getMessage()
            $this->_exit_code = 1;
            return 'WARNING: ' . $e->getMessage();
        }
    }

    public function checkSupee11155($name = '11155')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-11155_for_CE_1.7.0.2.sh

        if (!$this->fileContain('app/code/core/Mage/Core/Model/Email/Template/Filter.php', 'protected function _getVariable($value, $default = \'{no_value_defined}\')'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Adminhtml/controllers/SitemapController.php', 'const MAXIMUM_SITEMAP_NAME_LENGTH = '))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee11086($name = '11086')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-11086_CE_1.9.2.4_v1.sh.sh

        if (!$this->filesExists(array('app/code/core/Mage/Adminhtml/Model/Email/PathValidator.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php', 'public function preDispatch()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10975($name = '10975')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10975_for_CE_1.9.2.0-1.9.3.3.sh

        if (!$this->filesExists(array('app/code/core/Zend/Controller/Request/Http.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Adminhtml/Block/Customer/Group/Edit.php', 'public function getDeleteUrl()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10888($name = '10888')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10888_for_CE_1.9.2.0-1.9.2.4.sh

        if (!$this->filesExists(array('app/locale/en_US/template/email/admin_new_user_notification.html')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Admin/Model/User.php', 'public function getUserCreateAdditionalEmail()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10752($name = '10752')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10752_for_CE_1.9.2.0-1.9.2.4.sh

        if (!$this->filesExists(array('app/code/core/Zend/Filter/PregReplace.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Admin/Model/User.php', 'protected function getSession()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10570($name = '10570')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10752_for_CE_1.9.2.0-1.9.2.4.sh

        if (!$this->fileContain('app/Mage.php', '$message = addcslashes($message, \'<?\');'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Core/Model/Session/Abstract/Varien.php', 'const VALIDATOR_SESSION_EXPIRE_TIMESTAMP    = \'session_expire_timestamp\';'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10415($name = '10415')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10415_for_CE_1.9.2.2.sh

        if (!$this->filesExists(array('app/code/core/Zend/Form/Decorator/Form.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Api/Helper/Data.php', 'public function getCacheId()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee10266($name = '10266')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-10266_for_CE_1.9.1.1.sh

        if (!$this->filesExists(array('app/code/core/Zend/Serializer/Adapter/PhpCode.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Admin/Model/Session.php', 'protected function logoutIndirect()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee9767($name = '9767')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-9767v2_for_CE_1.9.1.0-1.9.3.0.sh

        if (!$this->filesExists(array('app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Core/Controller/Front/Action.php', 'protected function isFormkeyValidationOnCheckoutEnabled()'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee9652($name = '9652')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-9652_for_CE_1.5.0.1-1.9.3.1.sh

        if (!$this->fileContain('lib/Zend/Mail/Transport/Sendmail.php', 'throw new Zend_Mail_Transport_Exception(\'Potential code injection in From header\');'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee8967($name = '8967')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-8967_for_CE_1.5.0.0-1.9.2.4.sh

        if (!$this->fileContain('app/code/core/Mage/Payment/Model/Method/Cc.php', '\'MC\'  => \'/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/\','))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee8788($name = '8788')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-8788_for_CE_1.9.2.2.sh

        if (!$this->filesExists(array('app/code/core/Mage/Centinel/Model/Api/Client.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php', 'public function getDeleteButtonHtml($type = \'\')'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if ($this->filesExists('skin/adminhtml/default/default/media/flex.swf'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee7405($name = '7405v1.0')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }

        if (!$this->filesExists('app/code/core/Mage/Authorizenet/Helper/Admin.php'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->filesExists('app/code/core/Mage/ImportExport/etc/system.xml'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Admin/Model/Resource/User.php', 'protected function _unserializeExtraData(Mage_Core_Model_Abstract $user)'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee7405v11($name = '7405v1.1')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-7405_v1.1_for_CE_1.9.2.2.sh

        if (!$this->fileContain('app/code/core/Mage/Core/Model/Config.php', 'protected function _makeEventsLowerCase($area, Varien_Simplexml_Config $mergeModel)'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function checkSupee6788($name = '6788')
    {
        if ($this->isSupeeIgnored($name))
        {
            return true;
        }
        //Based on SUPEE-6788_for_CE_1.8.0.0.sh

        if (!$this->filesExists(array('app/code/core/Mage/Adminhtml/Block/Permissions/Variable.php')))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        if (!$this->fileContain('app/code/core/Mage/Core/Controller/Varien/Router/Admin.php', 'public function addModule($frontName, $moduleName, $routeName)'))
        {
            $this->_missing_patches[] = $name;
            return false;
        }

        return true;
    }

    public function fileContain($file, $needle)
    {
        $path = $this->getMagentoPath() . $file;

        //check if file exists
        if (!$this->filesExists(array($file)))
        {
            return false;
        }

        //check if needle is in content
        $content = file_get_contents($path);
        return strpos($content, $needle) !== false;
    }

    public function filesExists($files)
    {
        if (is_string($files))
        {
            $files = array($files);
        }
        foreach ($files as $file)
        {
            $path = $this->getMagentoPath() . $file;
            if (!file_exists($path))
            {
                return false;
            }
        }

        return true;
    }

    public function isSupeeIgnored($name)
    {
        $this->prepareSupeeIgnored();
        if (in_array($name, $this->_ignore_patches))
        {
            return true;
        }
        return false;
    }

    protected function prepareSupeeIgnored()
    {
        if (is_null($this->_ignore_patches))
        {
            $options = $this->getCliOptions();
            $ignore = array();
            if (array_key_exists('i', $options) && trim($options['i']) != '')
            {
                $ignore = (array)explode(',', $options['i']);
                array_walk($ignore, 'trim');
                $ignore = array_unique($ignore);
                $ignore = array_filter($ignore);
            }
            $this->_ignore_patches = $ignore;
        }
        return $this;
    }

    public function getMagentoPath()
    {
        if (!$this->_magento_path)
        {
            $options = $this->getCliOptions();

            //check if option passed
            if (!array_key_exists('p', $options) || !trim($options['p']))
            {
                throw new ErrorException('No arguments! Please use "xxxx.php -p /path/to/magento/root/ [-i SUPEE-Number]"');
            }

            $path = trim($options['p']);

            //check if path exists
            if (!file_exists($path))
            {
                throw new ErrorException('Wrong path!');
            }

            //add trailing slash
            $path = rtrim($path, '/') . '/';

            //check if magento
            if (!file_exists($path . 'app/Mage.php'))
            {
                throw new ErrorException('No Magento Installation found!');
            }

            $this->_magento_path = $path;
        }

        return $this->_magento_path;
    }

    public function getExitCode()
    {
        return $this->_exit_code;
    }

    public function getCliOptions()
    {
        return getopt("p:i:");
    }
}

$check = new SupeeCheck();
echo $check->run() ."\n";
exit($check->getExitCode());
