Jump To …

Drupal7.php

We expect (but do not insist) the file to be PSR-compatible.

The name of the file must be $unique_name.php. If your name happens to be identical to another script, we will notify you and you must modify suitably.

The name of the class must be Netenberg_Script_$unique_name.

The class must derive from Netenberg_Script.

class Netenberg_Script_Drupal7 extends Netenberg_Script
{

This function is called as part of the actual installation process (Step 3).

    public function install($parameters)
    {

This is a singleton that you can use to access control panel-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $control_panel = Zend_Registry::get('control_panel');

This is a singleton that you can use to access operating system-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $operating_system = Zend_Registry::get('operating_system');

This is an abstracted cURL object. You may use it for the sake of simplicity and also for ease of debugging. The full extent of this singleton is (will be made) available in the guide.

        $curl = new Netenberg_cURL;

You are encouraged to employ the usage of steps as follows:

 $step = 0;

 log_('DEBUG', sprintf(_('Step %d'), ++$step));
 ...
 ...
 ...

 log_('DEBUG', sprintf(_('Step %d'), ++$step));
 ...
 ...
 ...
        $step = 0;

        $settings_php = sprintf(
            '%s/%s/sites/default/settings.php',
            $parameters['document_root'],
            $parameters['directory']
        );

In this step, a fresh database is being created via the control panel singleton.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        list(
            $parameters['mysql_hostname'],
            $parameters['mysql_username'],
            $parameters['mysql_password'],
            $parameters['mysql_database']
        ) = $control_panel->insertMySQL();

In this step, the source archive is being downloaded and extracted to the desired directory via the control panel singleton.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $operating_system->transpose(
            'http://ftp.drupal.org/files/projects/drupal-7.27.tar.gz',
            array(
                'drupal-7.27/*' => sprintf(
                    '%s/%s',
                    $parameters['document_root'],
                    $parameters['directory']
                ),
            )
        );

$operating_system->cp() used to copy file/folder from one location to another location

You can write any number of copy statements as required or as instructed in the installation guidelines $operating_system->cp() fucntion takes two mandatory arguments. path to the source file/folder, and path to the destination file/folder

In this step, default.settings.php is copied and renamed to settings.php.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $operating_system->cp(sprintf(
            '%s/%s/sites/default/default.settings.php',
            $parameters['document_root'],
            $parameters['directory']
        ), $settings_php);

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        if (!$control_panel->hassuEXEC()) {
            $operating_system->chmod($settings_php, 666, false);
        }

$operating_system->chmod() used to set permissions.

You can write any number of chmod statements as required or as instructed in the installation guidelines $operating_system->chmod() fucntion takes three mandatory arguments. path to the specified file/folder, permissions i.e 777 for directory or may be 666 or 644 for a file etc., true (for recursive) or false (for non-recursive).

In this step, permissions of sites/default/files directory has been changed to 777 i.e. read-write-execute permissions to all three user levels owner, group and others.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $operating_system->mkdir(sprintf(
            '%s/%s/sites/default/files',
            $parameters['document_root'],
            $parameters['directory']
        ), 777);

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $_htaccess = sprintf(
            '%s/%s/.htaccess',
            $parameters['document_root'],
            $parameters['directory']
        );
        $contents = file_get_contents($_htaccess);

In this step, we are editing parts of .htaccess file as required.

        $contents = preg_replace('#Options#', '# Options', $contents);
        $contents = preg_replace('#php_#', '# php_', $contents);
        file_put_contents($_htaccess, $contents);

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $url = sprintf(
            'http://%s/%s/install.php',
            $parameters['domain'],
            $parameters['directory']
        );

In this step, we invoke the Drupal::7 installation wizard (step=2).

$curl->request is a function used to send Request to the URL. $curl->request() takes 5 arguments, i.e. URL to which request has to be sent, METHOD i.e. GET or POST, POSTFIELDS, which is present only for POST method, otherwise an empty array, HTTP HEADERS, and OPTIONS

getFields() user-defined function is called to get the formbuildid and form_id fields from the response, which must be passed as POST parameters.

Here we are making a POST Request to http://%s/%s/install.php, where %s refer to domain and directory respectively.

        $fields = $this->getFields($url, $curl);
        $curl->request(
            $url,
            'POST',
            array(
                'form_build_id' => $fields['form_build_id'],
                'form_id' => $fields['form_id'],
                'op' => 'Save and continue',
                'profile' => 'standard',
            ),
            array(),
            array()
        );

Here we are making a POST Request to http://%s/%s/install.php?profile=standard, where %s refer to domain and directory respectively.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $url = sprintf(
            'http://%s/%s/install.php?profile=standard',
            $parameters['domain'],
            $parameters['directory']
        );
        $fields = $this->getFields($url, $curl);
        $curl->request(
            $url,
            'POST',
            array(
                'form_build_id' => $fields['form_build_id'],
                'form_id' => $fields['form_id'],
                'locale' => 'en',
                'op' => 'Save and continue',
            ),
            array(),
            array()
        );

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $url = sprintf(
            'http://%s/%s/install.php?locale=en&profile=standard',
            $parameters['domain'],
            $parameters['directory']
        );
        $fields = $this->getFields($url, $curl);

Here we are making a POST Request to http://%s/%s/install.php?locale=en&profile=standard, where %s refer to domain and directory respectively.

        $curl->request(
            $url,
            'POST',
            array(
                'driver' => 'mysql',
                'form_build_id' => $fields['form_build_id'],
                'form_id' => $fields['form_id'],

$parameters['mysql_database'] refers to MySQL Database.

                'mysql[database]' => $parameters['mysql_database'],
                'mysql[db_prefix]' => '',

$parameters['mysql_hostname'] refers to MySQL Hostname.

                'mysql[host]' => $parameters['mysql_hostname'],

$parameters['mysql_password'] refers to MySQL Password.

                'mysql[password]' => $parameters['mysql_password'],
                'mysql[port]' => '',

$parameters['mysql_username'] refers to MySQL Username.

                'mysql[username]' => $parameters['mysql_username'],
                'op' => 'Save and continue',
                'sqlite[database]' => 'sites/default/files/.ht.sqlite',
                'sqlite[db_prefix]' => '',
            ),
            array(),
            array()
        );

Here we are making a POST Request to http://%s/%s/install.php?locale=en&op=startprofile=standard, where %s refer to domain and directory respectively.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $curl->request(
            sprintf(
                'http://%s/%s/install.php?id=1&locale=en&op=start&profile=standard',
                $parameters['domain'],
                $parameters['directory']
            ),
            'POST',
            array(),
            array(),
            array()
        );

Here we are making POST Requests to http://%s/%s/install.php?id=1&locale=en&op=do&profile=standard, where %s refer to domain and directory respectively.

In this step cURL request will run inside the condition gets satisfied.

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        while (true) {
            list(
                $curl_exec, $curl_errno, $curl_error, $curl_getinfo
            ) = $curl->request(
                sprintf(
                    'http://%s/%s/install.php?id=1&locale=en&op=do&profile=standard',
                    $parameters['domain'],
                    $parameters['directory']
                ),
                'POST',
                array(),
                array(),
                array()
            );
            $curl_exec[1] = json_decode($curl_exec[1], true);
            if ($curl_exec[1]['percentage'] == '100') {
                break;
            }
        }

        log_('DEBUG', sprintf(_('Step %d'), ++$step));
        $url = sprintf(
            'http://%s/%s/install.php?locale=en&profile=standard',
            $parameters['domain'],
            $parameters['directory']
        );
        $fields = $this->getFields($url, $curl);

list( $curlexec, $curlerrno, $curlerror, $curlgetinfo ) used to receive the headers and body and other cURL related information, where $curl_exec is an array which consists response headers and response body.

Here we are making POST Requests to http://%s/%s/install.php?locale=en&profile=standard, where %s refer to domain and directory respectively.

        list(
            $curl_exec, $curl_errno, $curl_error, $curl_getinfo
        ) = $curl->request(
            $url,
            'POST',
            array(

$parameters['account_email'] refers to value entered in the Email Field before the actual installation process starts.

                'account[mail]' => $parameters['account_mail'],

$parameters['account_name'] refers to value entered in the Username Field before the actual installation process starts.

                'account[name]' => $parameters['account_name'],

$parameters['accountpasspass1'] refers to value entered in the Password Field before the actual installation process starts.

                'account[pass][pass1]' => $parameters['account_pass_pass1'],

$parameters['accountpasspass2'] refers to value entered in the Password (Repeat) Field before the actual installation process starts.

                'account[pass][pass2]' => $parameters['account_pass_pass2'],
                'clean_url' => '0',
                'date_default_timezone' => 'UTC',
                'form_build_id' => $fields['form_build_id'],
                'form_id' => $fields['form_id'],
                'op' => 'Save and continue',
                'site_default_country' => '',
                
                'site_mail' => $parameters['account_mail'],

$parameters['site_name'] refers to value entered in the Site Name Field before the actual installation process starts.

                'site_name' => $parameters['site_name'],
                'update_status_module[1]' => '1',
                'update_status_module[2]' => '2',
            ),
            array(),
            array()
        );

In this step, we check if the installation was successful.

        if (strpos(
            $curl_exec[1], 'Congratulations, you installed Drupal'
        ) !== false) {
            log_('DEBUG', sprintf(_('Step %d'), ++$step));
            $operating_system->chmod(sprintf(
                '%s/%s/sites/default/settings.php',
                $parameters['document_root'],
                $parameters['directory']
            ), 644, false);

This indicates a success status (and is mandatory).

            log_('DEBUG', 'Success');

This allows the core system to register this installation within the user account (and is mandatory).

            return parent::install($parameters);
        }

This indicates a failure status (and is mandatory).

        log_('DEBUG', 'Failure');

        return false;
    }

This function fetches values of all the hidden fields in the response of specified URL, which is taken as parameter.

    public function getFields($url, $curl)
    {
        $fields = array();
        list(
            $curl_exec, $curl_errno, $curl_error, $curl_getinfo
        ) = $curl->request(
            $url,
            'GET',
            array(),
            array(),
            array()
        );
        $dom_document = new DOMDocument;
        $dom_document->loadHTML($curl_exec[1]);
        $forms = $dom_document->getElementsByTagName('form');
        if ($forms) {
            foreach ($forms as $form) {
                $inputs = $form->getElementsByTagName('input');
                if ($inputs) {
                    foreach ($inputs as $input) {
                        if ($input->getAttribute('type') === 'hidden') {
                            $fields[
                                $input->getAttribute('name')
                            ] = $input->getAttribute('value');
                        }
                    }
                }
            }
        }

        return $fields;
    }

This function validates the password.

    public function getCallbackPassword($contents)
    {

This statement checks whether password contains atleast one lowercase character.

        if (!preg_match('#[a-z]#', $contents)) {
            return false;
        }

This statement checks whether password contains atleast one uppercase character.

        if (!preg_match('#[A-Z]#', $contents)) {
            return false;
        }

This statement checks whether password contains atleast one digit.

        if (!preg_match('#[0-9]#', $contents)) {
            return false;
        }

This statement checks whether password contains atleast one special character.

        if (!preg_match('#[`\-=\[\]\;\',./~!@\#$%^&*()_+{}|:"<>?]#', $contents)) {
            return false;
        }

        return true;
    }

This function validates the username. Here the function is checking whether username contains any special characters.

    public function getCallbackUsername($contents)
    {
        if (preg_match('#[`\=\[\]\;\',/~!@\#$%^&*()+{}|:"<>?]#', $contents)) {
            return false;
        }

        return true;
    }

This function provides the category (and is mandatory).

    public function getCategory()
    {
        return _('Portals/CMS');
    }

This function provides the description (and is mandatory).

    public function getDescription()
    {
        return _('Drupal is an open source content management platform powering millions of websites and applications. It\'s built, used, and supported by an active and diverse community of people around the world. Use Drupal to build everything from personal blogs to enterprise applications. Thousands of add-on modules and designs let you build any site you can imagine.');
    }

This function provides the details of an installed copy (and is mandatory).

$parameters is a dictionary that contains domain, directory, and document_root.

    public function getDetails($parameters)
    {
        $bootstrap_inc = sprintf(
            '%s/%s/includes/bootstrap.inc',
            $parameters['document_root'],
            $parameters['directory']
        );
        if (!is_file($bootstrap_inc)) {
            return false;
        }
        $contents = file_get_contents($bootstrap_inc);

This statemnt performs a regular expression match on version of the installed copy on the contents of bootstrap.inc file.

        preg_match('#VERSION\',\s*\'([\d+\.]+)\'#', $contents, $version);

        return array(
            'version' => $version[1],
        );
    }

This function builds the form presented to the user (Step 1) (and is mandatory). It is built upon the Zend_Form component of Zend Framework.

    public function getForm()
    {

This is a singleton that you can use to access control panel-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $control_panel = Zend_Registry::get('control_panel');

This is an abstracted form object derived from Zend_Form. The full extent of this class is (will be made) available in the guide.

        $form = new Netenberg_Form();

This statement adds the domain selector (and is mandatory).

        $form->addElement('select', 'domain', array(
            'label' => _('Domain'),
            'multiOptions' => $control_panel->getDomains(),
            'required' => true,
        ));

This statement adds the directory selector (and is mandatory).

        $form->addElement('text', 'directory', array(
            'description' => _('Leave this field empty if you want to install in the web root for the domain you\'ve selected (i.e., http://domain.com/ ). If you\'d like to install in a subdirectory, please enter the path to the directory relative to the web root for your domain. The final destination subdirectory should not exist, but all others can exist (e.g., http://domain.com/some/sub/directory - In this case, "directory" should not already exist).'),
            'filters' => array(new Netenberg_Filter_Directory()),
            'label' => _('Directory'),
            'validators' => array(new Netenberg_Validate_Directory()),
        ));

This statement adds the username textfield (and is mandatory).

        $form->addElement('text', 'account_name', array(
            'description' => sprintf(_('maximum %d characters; must only contain alphanumeric characters'), 60),
            'label' => _('Username'),
            'required' => true,
            'validators' => array(

This validator statement checks whether username field contains more than 60 characters.

                array('StringLength', false, array(
                    'max' => 60,
                )),

This validator statement checks whether username field contains any special characters by calling getCallbackUsername function which is written above.

                array('Callback', false, array(
                    'callback' => array($this, 'getCallbackUsername'),
                )),
            )
        ));

This statement adds the password textfield (and is mandatory).

        $form->addElement('password', 'account_pass_pass1', array(
            'description' => sprintf(_('minimum %d characters; maximum %d characters; must contain one uppercase and one lowercase and one number and one special character'), 6, 128),
            'label' => _('Password'),
            'required' => true,
            'validators' => array(

This validator statement checks whether length of the password entered is in-between 6 and 128 characters.

                array('StringLength', false, array(
                    'min' => 6,
                    'max' => 128,
                )),

This validator statement checks whether password field contains atleast one uppercase character, atleast one lowercase character, atleast one digit and atleast speicla character by calling getCallbackPassword function which is written above.

                array('Callback', false, array(
                    'callback' => array($this, 'getCallbackPassword'),
                )),
            )
        ));

This statement adds the password repeat textfield (and is mandatory).

        $form->addElement('password', 'account_pass_pass2', array(
            'label' => _('Password (Repeat)'),
            'required' => true,

This validator statement checks whether this field is identical to value of Password Textfield.

            'validators' => array(
                array('Identical', false, array(
                    'token' => 'account_pass_pass1',
                )),
            ),
        ));

This statement adds the email (and is mandatory).

        $form->addElement('text', 'account_mail', array(
            'label' => _('Email'),
            'required' => true,

This validator statement checks whether this field contains a valid Email Address.

            'validators' => array(
                array('EmailAddress', false),
            ),
        ));

This statement adds the Name of the Drupal Site (and is mandatory).

        $form->addElement('text', 'site_name', array(
            'description' => _('maximum 128 characters'),
            'label' => _('Site Name'),
            'required' => true,
            'validators' => array(
                array('StringLength', false, array(
                    'max' => 128,
                )),
            )
        ));

This statement adds the Submit button to the form (and is mandatory).

        $form->addElement('button', 'submit');

This statement adds the Reset button to the form (and is mandatory).

        $form->addElement('button', 'reset');

This statement places the domain and directory selectors under the display group Location Details.

        $form->addDisplayGroup(
            array('domain', 'directory'),
            'location_details',
            array(
                'decorators' => $form->getDefaultGroupDecorator(),
                'disableLoadDefaultDecorators' => true,
                'legend' => 'Location Details',
            )
        );

This statement places the account_name, accountpasspass1, accountpasspass2 and account_email under the display group Administrator Details.

        $form->addDisplayGroup(
            array(
                'account_name',
                'account_pass_pass1',
                'account_pass_pass2',
                'account_mail',
            ),
            'administrator_details',
            array(
                'decorators' => $form->getDefaultGroupDecorator(),
                'disableLoadDefaultDecorators' => true,
                'legend' => _('Administrator Details'),
            )
        );

This statement places the site_name under the display group Other Deatils.

        $form->addDisplayGroup(
            array('site_name'),
            'other_details',
            array(
                'decorators' => $form->getDefaultGroupDecorator(),
                'disableLoadDefaultDecorators' => true,
                'legend' => _('Other Details'),
            )
        );

This statement places the Submit and Reset buttons in end of the form.

        $form->addDisplayGroup(
            array('submit', 'reset'),
            'buttons',
            array(
                'decorators' => $form->getButtonGroupDecorator(),
                'disableLoadDefaultDecorators' => true,
            )
        );

        return $form;
    }

This function provides the image (and is mandatory).

    public function getImage()
    {
        return 'http://drupal.org/files/druplicon.small_.png';
    }

This function provides the name (and is mandatory). The name must be unique.

    public function getName()
    {
        return 'Drupal :: 7';
    }

This function provides the post-installation overview (and is mandatory).

$parameters is a dictionary that contains the values supplied by the user like domain, directory and username and/or password and/or email etc.

    public function getItems($parameters)
    {
        return array(

This statement provides the URL for Backend page. Backend page is a login-page which is used to login into Administrator's Account.

            _('Backend') => array(
                sprintf(
                    '<a href="http://%s/%s" target="_blank">http://%s/%s/</a>',
                    $parameters['domain'],
                    $parameters['directory'],
                    $parameters['domain'],
                    $parameters['directory']
                ),
                sprintf(_('Username: %s'), $parameters['account_name']),
                sprintf(_('Password: %s'), $parameters['account_pass_pass1']),
            ),
        );
    }

This function provides the requirements (and is mandatory).

    public function getRequirements()
    {

This is a singleton that you can use to access control panel-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $control_panel = Zend_Registry::get('control_panel');

        $apache = $control_panel->getApache();
        $mysql = $control_panel->getMySQL();
        $php = $control_panel->getPHP();

        return array(

This statement checks whether enough space is available in your account to install this script.

            'Disk Space' => (
                $control_panel->getSize() >= $this->getSize()
            )? true: false,

This statement checks whether installed Apache's version is greater than 1.

            'Apache 1+' => (
                strpos($apache, 'Apache/1') !== false
                or
                strpos($apache, 'Apache/2') !== false
            )? true: false,

This statement checks whether installed MySQL's version is greater than 5.0.15.

            'MySQL 5.0.15+' => (preg_match(
                '#Distrib (5\.0\.1[5-9]|5\.0\.[2-9]|5\.[1-9])#', $mysql
            ) === 1)? true: false,

This statement checks whether installed PHP's version is greater than 5.2.5

            'PHP 5.2.5+' => (preg_match(
                '#PHP Version\s*=>\s*(5\.2\.[5-9]|5\.2\.[0-9]{2}|5\.[3-9])#', $php
            ) === 1)? true: false,
        );
    }

This function provides the size (in bytes) (and is mandatory).

    public function getSize()
    {
        return 12792627;
    }

This function provides the slug (and is mandatory). The slug must be unique.

    public function getSlug()
    {
        return 'drupal-7';
    }

This function provides the URLs (and is mandatory).

We expect (but do not insist) URLs for four pages to be part of the array. They are URLs of Home, Community, Documentation and Support or Forum pages.

    public function getUrls()
    {
        return array(
            _('Home') => 'http://drupal.org',
            _('Community') => 'http://drupal.org/community',
            _('Documentation') => 'http://drupal.org/documentation',
            _('Support') => 'http://drupal.org/support',
        );
    }

This function provides the version (and is mandatory).

    public function getVersion()
    {
        return '7.27';
    }

This function is called as part of the actual uninstallation process

$parameters is a dictionary that contains the values supplied by the user in addition to a few system-specific values. The full extent of this dictionary is (will be made) available in the guide.

    public function uninstall($parameters)
    {

This is a singleton that you can use to access control panel-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $control_panel = Zend_Registry::get('control_panel');

This is a singleton that you can use to access operating system-specific functions (see below for examples). The full extent of this singleton is (will be made) available in the guide.

        $operating_system = Zend_Registry::get('operating_system');

        $settings_php = sprintf(
            '%s/%s/sites/default/settings.php',
            $parameters['document_root'],
            $parameters['directory']
        );
        if (!is_file($settings_php)) {
            return false;
        }

This statement fetches the contents of settings.php

        $contents = file_get_contents($settings_php);

This statement performs a regular expression match to fetch database name from the contents of settings.php

        preg_match_all(
            '#\'database\'\s*=>\s*\'([^\']*)#', $contents, $database
        );

This statement performs a regular expression match to fetch database username from the contents of settings.php

        preg_match_all(
            '#\'username\'\s*=>\s*\'([^\']*)#', $contents, $mysql_username
        );

In this step, we remove the database via the control panel singleton.

        $control_panel->deleteMySQL($mysql_username[1][4], $database[1][5]);

In this step, we remove the directory via the operating system singleton.

        $operating_system->dispose(sprintf(
            '%s/%s', $parameters['document_root'], $parameters['directory']
        ));

This allows the core system to unregister this installation within the user account (and is mandatory).

        return parent::uninstall($parameters);
    }
}