<?PHP
#
#   FILE:  Pages.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2012 Edward Almasy and Internet Scout
#   http://scout.wisc.edu
#

/**
* Free-form page plugin.
*/
class Pages extends Plugin {

    # ---- STANDARD PLUGIN METHODS -------------------------------------------

    /**
    * Set the plugin attributes.  At minimum this method MUST set $this->Name
    * and $this->Version.  This is called when the plugin is initially loaded.
    */
    function Register()
    {
        $this->Name = "Pages";
        $this->Version = "1.0.6";
        $this->Description = "Allows the creation and editing of additional"
                ." web pages with free-form HTML content";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array(
                "CWISCore" => "2.4.1");
        $this->EnabledByDefault = FALSE;

        $this->CfgSetup["PrivilegeToAuthor"] = array(
                "Type" => "Privileges",
                "Label" => "Privilege to Author",
                "Help" => "Privilege required to author new pages.",
                "AllowMultiple" => FALSE
                );
        $this->CfgSetup["PrivilegeToEdit"] = array(
                "Type" => "Privileges",
                "Label" => "Privilege to Edit",
                "Help" => "Privilege required to edit existing pages.",
                "AllowMultiple" => FALSE
                );
    }

    /**
    * Initialize the plugin.  This is called after all plugins have been loaded
    * but before any methods for this plugin (other than Register() or Initialize())
    * have been called.
    * @return NULL if initialization was successful, otherwise a string containing
    *       an error message indicating why initialization failed.
    */
    function Initialize()
    {
        $PFactory = new Pages_PageFactory();
        $CleanUrls = $PFactory->GetCleanUrls();
        foreach ($CleanUrls as $PageId => $Url)
        {
            if (strlen($Url))
            {
                $GLOBALS["AF"]->AddCleanUrl("%^".$Url."$%", "P_Pages_DisplayPage",
                        array("ID" => $PageId));
            }
        }
    }

    /**
    * Perform any work needed when the plugin is first installed (for example,
    * creating database tables).
    * @return NULL if installation succeeded, otherwise a string containing
    *       an error message indicating why installation failed.
    */
    function Install()
    {
        # initialize default configuration settings
        $this->ConfigSetting("PrivilegeToAuthor", PRIV_MYRESOURCEADMIN);
        $this->ConfigSetting("PrivilegeToEdit", PRIV_RESOURCEADMIN);

        # set up database tables
        $Queries = array(
                "CREATE TABLE IF NOT EXISTS Pages_Pages (
                    PageId      INT NOT NULL AUTO_INCREMENT,
                    PageTitle   TEXT,
                    PageContent MEDIUMTEXT,
                    AuthorId    INT NOT NULL,
                    EditorId    INT,
                    CreatedOn   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    UpdatedOn   TIMESTAMP DEFAULT 0,
                    CleanUrl    TEXT,
                    INDEX       (PageId),
                    INDEX       (AuthorId))",
                "CREATE TABLE IF NOT EXISTS Pages_Privileges (
                    PageId      INT NOT NULL,
                    Privilege   INT NOT NULL,
                    INDEX       (PageId))",
                );
        foreach ($Queries as $Query)
        {
            $Result = $this->DB->Query($Query);
            if ($Result === FALSE) {  break;  }
        }
        return ($Result === FALSE) ? "Database setup failed." : NULL;
    }

    /**
    * Upgrade this plugin from a previous version.
    * @param string $PreviousVersion String contining previous version number.
    * @return null|string NULL if successful or error message string if not.
    */
    function Upgrade($PreviousVersion)
    {
        # ugprade from versions < 1.0.1 to 1.0.1
        if (version_compare($PreviousVersion, "1.0.1", "<"))
        {
            $PrivilegeToAuthor = $this->ConfigSetting("PrivilegeToAuthor");
            $PrivilegeToEdit = $this->ConfigSetting("PrivilegeToEdit");

            # if authoring privilege is an array because it hasn't been edited
            # since the plugin was installed
            if (is_array($PrivilegeToAuthor))
            {
                $this->ConfigSetting("PrivilegeToAuthor", array_shift($PrivilegeToAuthor));
            }

            # if editing privilege is an array because it hasn't been edited
            # since the plugin was installed
            if (is_array($PrivilegeToEdit))
            {
                $this->ConfigSetting("PrivilegeToEdit", array_shift($PrivilegeToEdit));
            }
        }

        # ugprade from versions < 1.0.2 to 1.0.2
        if (version_compare($PreviousVersion, "1.0.2", "<"))
        {
            # add clean URL column to database
            $Result = $this->DB->Query("ALTER TABLE Pages_Pages"
                    ." ADD COLUMN CleanUrl TEXT");
            if ($Result === FALSE) {  return "Upgrade failed adding"
                    ." \"CleanUrl\" column to database.";  }
        }

        # ugprade from versions < 1.0.5 to 1.0.5
        if (version_compare($PreviousVersion, "1.0.5", "<"))
        {
            # convert content column in database to larger type
            $Result = $this->DB->Query("ALTER TABLE Pages_Pages"
                    ." MODIFY COLUMN PageContent MEDIUMTEXT");
            if ($Result === FALSE) {  return "Upgrade failed converting"
                    ." \"PageContent\" column to MEDIUMTEXT.";  }
        }

        # report success to caller
        return NULL;
    }

    /**
    * Perform any work needed when the plugin is uninstalled.
    * @return NULL if uninstall succeeded, otherwise a string containing
    *       an error message indicating why uninstall failed.
    */
    function Uninstall()
    {
        $this->DB->Query("DROP TABLE Pages_Pages");
        $this->DB->Query("DROP TABLE Pages_Privileges");
        return NULL;
    }

    /**
    * Hook the events into the application framework.
    * @return Returns an array of events to be hooked into the application
    *      framework.
    */
    function HookEvents()
    {
        $Events = array(
                "EVENT_MODIFY_SECONDARY_NAV" => "AddMenuOptions",
                );
        if ($this->ConfigSetting("PrivilegeToEdit") == PRIV_SYSADMIN)
        {
            $Events["EVENT_SYSTEM_ADMINISTRATION_MENU"] = "AddAdminMenuItems";
        }
        elseif ($this->ConfigSetting("PrivilegeToEdit") == PRIV_USERADMIN)
        {
            $Events["EVENT_USER_ADMINISTRATION_MENU"] = "AddAdminMenuItems";
        }
        elseif ($this->ConfigSetting("PrivilegeToEdit") == PRIV_COLLECTIONADMIN)
        {
            $Events["EVENT_COLLECTION_ADMINISTRATION_MENU"] = "AddAdminMenuItems";
        }
        return $Events;
    }


    # ---- HOOKED METHODS ----------------------------------------------------

    function AddAdminMenuItems()
    {
        return array(
                "index.php?P=P_Pages_EditPage&amp;ID=NEW" => "Add New Page",
                "index.php?P=P_Pages_ListPages" => "List Pages",
                );
    }

    function AddMenuOptions($NavItems)
    {
        # build up list of nav items to add
        if ($GLOBALS["G_User"]->HasPriv(
                $this->ConfigSetting("PrivilegeToAuthor"))
                || $GLOBALS["G_User"]->HasPriv(
                $this->ConfigSetting("PrivilegeToEdit")))
        {
            if ($GLOBALS["G_User"]->HasPriv(
                    $this->ConfigSetting("PrivilegeToAuthor")))
            {
                $MyNavItems["Add New Page"] =
                        "index.php?P=P_Pages_EditPage&amp;ID=NEW";
            }
            $MyNavItems["List Pages"] = "index.php?P=P_Pages_ListPages";
        }

        # if there are nav items to add
        if (isset($MyNavItems))
        {
            # step through options to add new entries at most desirable spot
            $NewNavItems = array();
            $NeedToAddMyOptions = TRUE;
            foreach ($NavItems as $Label => $Link)
            {
                if ($NeedToAddMyOptions &&
                        (($Label == "Administration") || ($Label == "Log Out")))
                {
                    $NewNavItems = $NewNavItems + $MyNavItems;
                    $NeedToAddMyOptions = FALSE;
                }
                $NewNavItems[$Label] = $Link;
            }
            if ($NeedToAddMyOptions) {  $NewNavItems = $NewNavItems + $MyNavItems;  }
        }
        else
        {
            # return nav item list unchanged
            $NewNavItems = $NavItems;
        }

        # return new list of nav options to caller
        return array("NavItems" => $NewNavItems);
    }


    # ---- CALLABLE METHODS --------------------------------------------------

    # (no externally-callable methods)


    # ---- PRIVATE METHODS ---------------------------------------------------

    /**
    * Object constructor.
    */
    function __construct()
    {
        $this->DB = new Database();
    }

    private $DB;
}
