public function createArticleCategory($input)
 {
     $parentChannel = isset($input['parentid']) ? $input['parentid'] : $this->getArticleChannel();
     return $this->createChannel($input, $parentChannel, vB_Page::getArticleConversPageTemplate(), vB_Page::getArticleChannelPageTemplate(), vB_Api_UserGroup::CHANNEL_OWNER_SYSGROUPID);
 }
 public function add($data, array $options = array('nodeonly' => false))
 {
     $options += array('skipDupCheck' => true);
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     // VBV-833: we allow interfaces to not specify a parent. Main channel should be used in that case
     if (!isset($data['parentid']) or $data['parentid'] <= 0) {
         $data['parentid'] = vB::getDbAssertor()->getField('vBForum:channel', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::CONDITIONS_KEY => array('guid' => vB_Channel::DEFAULT_CHANNEL_PARENT)));
     } else {
         // if we are not using the default channel parent, we need to check for pagetemplates
         if (!isset($data['templates'])) {
             $parent = vB::getDbAssertor()->getRow('vBForum:channel', array(vB_dB_Query::COLUMNS_KEY => array('nodeid', 'guid'), vB_dB_Query::CONDITIONS_KEY => array('nodeid' => $data['parentid'])));
             switch ($parent['guid']) {
                 case vB_Channel::DEFAULT_SOCIALGROUP_PARENT:
                     // This is done only when saving from activity stream configuration, once it is removed we can get rid of this
                     $data['templates']['vB5_Route_Channel'] = vB_Page::getSGCategoryPageTemplate();
                     $data['templates']['vB5_Route_Conversation'] = vB_Page::getSGCategoryConversPageTemplate();
                     $data['category'] = 1;
                     break;
                 case vB_Channel::DEFAULT_ARTICLE_PARENT:
                     // articles
                     $data['templates']['vB5_Route_Channel'] = vB_Page::getArticleChannelPageTemplate();
                     $data['templates']['vB5_Route_Conversation'] = vB_Page::getArticleConversPageTemplate();
                     break;
                 default:
                     // use inherited from parent channel
                     break;
             }
         }
     }
     if (!isset($data['guid'])) {
         // creating guid
         $data['guid'] = vB_Xml_Export_Channel::createGUID($data);
     }
     // parse options array
     if (isset($data['options'])) {
         if (is_array($data['options'])) {
             $value = $this->buildChannelOptions(0, $data['options']);
             if ($value !== FALSE) {
                 $data['options'] = $value;
             } else {
                 // do not update field
                 unset($data['options']);
             }
         } else {
             // should we accept raw ints as updates?
             unset($data['options']);
         }
     }
     if (empty($data['urlident']) and !empty($data['title'])) {
         $data['urlident'] = $this->getUniqueUrlIdent($data['title']);
     }
     if (!isset($options['nodeonly']) || !$options['nodeonly']) {
         // if we are going to create pages, verify that prefix/regex generated is valid BEFORE creating the node
         vB5_Route_Channel::validatePrefix($data);
     }
     try {
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         $result = parent::add($data, $options);
         if (!isset($options['nodeonly']) || !$options['nodeonly']) {
             $this->nodeLibrary->clearCacheEvents($result['nodeid']);
             $this->createChannelPages($result['nodeid'], $data);
         }
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     //and announce that the cached channel structure has changed.
     $result['cacheEvents'][] = 'vB_ChannelStructure_chg';
     if (isset($data['filedataid']) and vB::getUserContext()->getChannelPermission('forumpermissions', 'canuploadchannelicon', $result['nodeid'])) {
         $this->qryAfterAdd[] = array('definition' => 'incrementFiledataRefcountAndMakePublic', 'data' => array('filedataid' => $data['filedataid']));
     }
     if (!$skipTransaction) {
         //The child classes that have their own transactions all set this to true so afterAdd is always called just once.
         $this->afterAdd($result['nodeid'], $data, $options, $result['cacheEvents'], $result['nodeVals']);
     }
     if (!defined('VB_AREA') or !in_array(VB_AREA, array('Install', 'Upgrade'))) {
         vB::getUserContext()->rebuildGroupAccess();
         vB::getUserContext()->reloadUserPerms();
         vB_Channel::rebuildChannelTypes();
     }
     return $result;
 }