/**
  * This method returns HTML code for the IntraACL toolbar,
  * for the $title editing mode.
  *
  * Looks like the following:
  * Page protection: <selectbox>. [Additional ACL ↓] [Used content ↓] [Edit ACL] ... [Manage Quick ACL]
  *
  * Options for selectbox:
  * - [no custom rights] - use only category/namespace rights
  * - [ACL:Page/XXX] - use custom ACL
  * - [Right 1] - use ACL template 1
  * - [Right 2] - use ACL template 2
  * - ...
  * ACL templates are detected using HACLSecurityDescriptor::isSinglePredefinedRightInclusion()
  * So if ACL:Page/XXX is really the inclusion of a single right template, it will be detected.
  */
 static function get($title, $nonreadable)
 {
     global $wgUser, $wgRequest, $haclgContLang, $wgContLang, $haclgHaloScriptPath, $wgScriptPath, $wgOut, $haclgOpenWikiAccess;
     self::addToolbarLinks($wgOut);
     $ns = $wgContLang->getNsText(HACL_NS_ACL);
     $canModify = true;
     $options = array(array('value' => 'unprotected', 'name' => wfMsg('hacl_toolbar_unprotected'), 'title' => wfMsg('hacl_toolbar_unprotected')));
     if (!is_object($title)) {
         $title = Title::newFromText($title);
     }
     if ($title->getNamespace() == HACL_NS_ACL) {
         return '';
     }
     // $found = "is current page SD in the list?"
     $found = false;
     // The list of ACLs which have effect on $title, but are not ACL:Page/$title by themselves
     // I.e. category and namespace ACLs
     $globalACL = array();
     $pageSDId = NULL;
     if ($title->exists()) {
         // Check SD modification rights
         $pageSDTitle = Title::newFromText(IACLDefinition::nameOfSD(IACL::PE_PAGE, $title));
         $pageSD = IACLDefinition::getSDForPE(IACL::PE_PAGE, $title->getArticleId());
         if ($pageSD) {
             $realPageSDId = $pageSDId = array($pageSD['pe_type'], $pageSD['pe_id']);
             $canModify = $pageSDTitle->userCan('edit');
             // Check if page SD is a single predefined right inclusion
             if ($pageSD['single_child']) {
                 $pageSDId = $pageSD['single_child'];
                 // But don't change $realPageSDId
             } else {
                 $found = true;
                 $options[] = array('current' => true, 'value' => implode('-', $pageSDId), 'name' => $pageSDTitle->getFullText(), 'title' => $pageSDTitle->getFullText());
             }
         } else {
             // Get protected categories this article belongs to (for hint)
             $categories = IACLStorage::get('Util')->getParentCategoryIDs($title->getArticleId());
             foreach ($categories as &$cat) {
                 $cat = array(IACL::PE_CATEGORY, $cat);
             }
             unset($cat);
             // prevent reference bugs
             $defs = IACLDefinition::select(array('pe' => $categories));
             foreach ($defs as $def) {
                 $globalACL[] = $def['def_title'];
             }
         }
     }
     // Add Quick ACLs
     $quickacl = IACLQuickacl::newForUserId($wgUser->getId());
     $default = $quickacl->default_pe_id;
     $hasQuickACL = false;
     foreach ($quickacl->getPEIds() as $def) {
         $hasQuickACL = true;
         $sdTitle = IACLDefinition::getSDTitle($def);
         if (!$sdTitle) {
             continue;
         }
         $option = array('value' => implode('-', $def), 'current' => $def == $pageSDId, 'name' => $sdTitle->getPrefixedText(), 'title' => $sdTitle->getPrefixedText());
         $found = $found || $option['current'];
         if ($default == $def) {
             if (!$title->exists()) {
                 // Select default option for new articles
                 $option['current'] = true;
             }
             // Always insert default SD as the second option
             array_splice($options, 1, 0, array($option));
         } else {
             $options[] = $option;
         }
     }
     // If page SD is not yet in the list, insert it as the second option
     if ($pageSDId && !$found) {
         $sdTitle = IACLDefinition::getSDTitle($pageSDId);
         array_splice($options, 1, 0, array(array('name' => $sdTitle->getPrefixedText(), 'value' => implode('-', $pageSDId), 'current' => true, 'title' => $sdTitle->getPrefixedText())));
     }
     // Alter selection using request data (hacl_protected_with)
     if ($canModify && ($st = $wgRequest->getVal('hacl_protected_with'))) {
         foreach ($options as &$o) {
             $o['current'] = $o['value'] == $st;
         }
         unset($o);
         // prevent reference bugs
     }
     $selectedIndex = false;
     foreach ($options as $i => $o) {
         if (!empty($o['current'])) {
             $selectedIndex = $i;
         }
     }
     // Check if page namespace has an ACL (for hint)
     if (!$pageSDId && !$globalACL) {
         $sdTitle = IACLDefinition::getSDTitle(array(IACL::PE_NAMESPACE, $title->getNamespace()));
         if ($sdTitle->exists()) {
             $globalACL[] = $sdTitle;
         }
     }
     if ($globalACL) {
         foreach ($globalACL as &$t) {
             if ($haclgOpenWikiAccess || $t->userCan('read')) {
                 $t = Xml::element('a', array('href' => $t->getLocalUrl(), 'target' => '_blank'), $t->getText());
             }
         }
         unset($t);
         // prevent reference bugs
         $globalACL = implode(', ', $globalACL);
     }
     // Check if the article does include any content
     $anyLinks = $embeddedToolbar = false;
     if ($title->exists()) {
         if (!$pageSDId) {
             $pageSDId = '';
         }
         $c = false;
         foreach ($wgRequest->getValues() as $k => $v) {
             if (substr($k, 0, 7) == 'sd_emb_' && $v !== "") {
                 $c = true;
                 break;
             }
         }
         if ($c) {
             // If there were any changes in the embedded content
             // toolbar, display it initially
             $embeddedToolbar = self::getEmbeddedHtml($title->getArticleId(), $realPageSDId[0], $realPageSDId[1]);
         } else {
             // Else only check for imagelinks/templatelinks existence
             $dbr = wfGetDB(DB_SLAVE);
             $res = $dbr->query($dbr->selectSQLText('imagelinks', '1', array('il_from' => $title->getArticleId()), __METHOD__, array('GROUP BY' => 'il_from')) . ' UNION ' . $dbr->selectSQLText('templatelinks', '1', array('tl_from' => $title->getArticleId()), __METHOD__, array('GROUP BY' => 'tl_from')), __METHOD__);
             $res = $res->fetchObject();
             if ($res) {
                 $anyLinks = true;
             }
         }
     }
     // Link to Quick ACL manage page
     $quick_acl_link = Title::newFromText('Special:IntraACL')->getLocalUrl(array('action' => 'quickaccess'));
     // Run template
     ob_start();
     require dirname(__FILE__) . '/../templates/HACL_Toolbar.tpl.php';
     $html = ob_get_contents();
     ob_end_clean();
     return $html;
 }
 /**
  * Manage Quick Access ACL list
  */
 public function html_quickaccess(&$args)
 {
     global $wgOut, $wgUser, $wgScript, $haclgHaloScriptPath, $wgRequest;
     /* Handle save request */
     $args = $wgRequest->getValues();
     $like = empty($args['like']) ? '' : $args['like'];
     if (!empty($args['save'])) {
         $ids = array();
         $default = NULL;
         foreach ($args as $k => $v) {
             if (substr($k, 0, 3) == 'qa_' && $k !== 'qa_default') {
                 $ids[] = array_map('intval', explode('-', substr($k, 3), 2));
             }
         }
         $default = !empty($args['qa_default']) ? array_map('intval', explode('-', $args['qa_default'], 2)) : NULL;
         $quickacl = new IACLQuickacl($wgUser->getId(), $ids, $default);
         $quickacl->save();
         // FIXME Terminate MediaWiki more correctly
         wfGetDB(DB_MASTER)->commit();
         header("Location: {$wgScript}?title=Special:IntraACL&action=quickaccess&like=" . urlencode($like));
         exit;
     }
     /* Load data */
     $total = 0;
     $titles = IACLStorage::get('SD')->getSDPages('right', $like, NULL, NULL, NULL, $total);
     $quickacl = IACLQuickacl::newForUserId($wgUser->getId());
     $quickacl_ids = $quickacl->getPEIds();
     $defs = IACLDefinition::newFromTitles($titles);
     $templates = array();
     foreach ($titles as $k => $title) {
         if (isset($defs[$k])) {
             $pe = array($defs[$k]['pe_type'], $defs[$k]['pe_id']);
             $templates[] = array('default' => $quickacl->default_pe_id == $pe, 'selected' => array_key_exists(implode('-', $pe), $quickacl_ids), 'editlink' => $wgScript . '?title=Special:IntraACL&action=acl&sd=' . urlencode($title->getText()), 'viewlink' => $title->getLocalUrl(), 'title' => $title, 'id' => implode('-', $pe));
         }
     }
     /* Run template */
     ob_start();
     require dirname(__FILE__) . '/../templates/HACL_QuickACL.tpl.php';
     $html = ob_get_contents();
     ob_end_clean();
     $wgOut->setPageTitle(wfMsg('hacl_qacl_manage'));
     $wgOut->addHTML($html);
 }