summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authormodela bitweaver <spiderr@bitweaver.org>2021-02-01 13:19:04 -0500
committermodela bitweaver <spiderr@bitweaver.org>2021-02-01 13:19:04 -0500
commitcbc7f033fa1c1f186e887ce47a961375a4f8ca1e (patch)
tree4efbd2fa802ef541370ac0d74858441192aeaf33 /includes
parentd4245cf34238651275c1a74a45ec40955ebcf9b9 (diff)
downloadarticles-cbc7f033fa1c1f186e887ce47a961375a4f8ca1e.tar.gz
articles-cbc7f033fa1c1f186e887ce47a961375a4f8ca1e.tar.bz2
articles-cbc7f033fa1c1f186e887ce47a961375a4f8ca1e.zip
move classes to includes/classes and use PKG_CLASS/INCLUDE_PATH constants
Diffstat (limited to 'includes')
-rw-r--r--includes/classes/BitArticle.php712
-rw-r--r--includes/classes/BitArticleTopic.php465
-rw-r--r--includes/classes/BitArticleType.php157
3 files changed, 1334 insertions, 0 deletions
diff --git a/includes/classes/BitArticle.php b/includes/classes/BitArticle.php
new file mode 100644
index 0000000..cc1c7c1
--- /dev/null
+++ b/includes/classes/BitArticle.php
@@ -0,0 +1,712 @@
+<?php
+/**
+ * Article class is used when accessing BitArticles. It is based on TikiSample
+ * and builds on core bitweaver functionality, such as the Liberty CMS engine.
+ *
+ * @version $Header$
+ * @package articles
+ *
+ * @copyright 2004-15 bitweaver.org
+ * Copyright( c )2003 tikwiki.org
+ * Copyright( c )2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
+ * All Rights Reserved. See below for details and a complete list of authors.
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details
+ *
+ * $Id$
+ *
+ * @author wolffy <wolff_borg@yahoo.com.au>
+ * @version $Revision$
+ */
+
+/**
+ * Required setup
+ */
+require_once( ARTICLES_PKG_CLASS_PATH.'BitArticleTopic.php' );
+require_once( ARTICLES_PKG_CLASS_PATH.'BitArticleType.php' );
+require_once( LIBERTY_PKG_PATH.'LibertyMime.php' );
+require_once( LIBERTY_PKG_PATH.'LibertyComment.php' );
+
+define( 'BITARTICLE_CONTENT_TYPE_GUID', 'bitarticle' );
+
+/**
+ * @package articles
+ */
+class BitArticle extends LibertyMime
+{
+ /**
+ * Primary key for articles
+ */
+ public $mArticleId;
+ public $mTypeId;
+ public $mTopicId;
+
+ /**
+ * Initiate the articles class
+ * @param $pArticleId article id of the article we want to view
+ * @param $pContentId content id of the article we want to view
+ * @access private
+ **/
+ function __construct($pArticleId=NULL, $pContentId=NULL)
+ {
+ parent::__construct();
+ $this->registerContentType(
+ BITARTICLE_CONTENT_TYPE_GUID, array(
+ 'content_type_guid' => BITARTICLE_CONTENT_TYPE_GUID,
+ 'content_name' => 'Article',
+ 'handler_class' => 'BitArticle',
+ 'handler_package' => 'articles',
+ 'handler_file' => 'includes/classes/BitArticle.php',
+ 'maintainer_url' => 'http://www.bitweaver.org'
+ ));
+ $this->mContentId = $pContentId;
+ $this->mArticleId = $pArticleId;
+ $this->mTypeId = NULL;
+ $this->mTopicId = NULL;
+ $this->mContentTypeGuid = BITARTICLE_CONTENT_TYPE_GUID;
+ $this->mDate = new BitDate();
+ $offset = $this->mDate->get_display_offset();
+
+ // Permission setup
+ $this->mViewContentPerm = 'p_articles_read';
+ $this->mCreateContentPerm = 'p_articles_submit';
+ $this->mUpdateContentPerm = 'p_articles_update';
+ $this->mAdminContentPerm = 'p_articles_admin';
+ }
+
+ /**
+ * Load the data from the database
+ * @access public
+ **/
+ public function load($pContentId = NULL, $pPluginParams = NULL)
+ {
+ if ( @$this->verifyId( $this->mArticleId ) || @$this->verifyId( $this->mContentId ) ) {
+ // LibertyContent::load()assumes you have joined already, and will not execute any sql!
+ // This is a significant performance optimization
+ $lookupColumn = @$this->verifyId( $this->mArticleId ) ? 'article_id' : 'content_id';
+ $bindVars[] = $lookupId = @BitBase::verifyId( $this->mArticleId ) ? $this->mArticleId : $this->mContentId;
+ $this->getServicesSql( 'content_load_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
+
+ $query = "SELECT a.*, lc.*, atype.*, atopic.*, lch.hits,
+ uue.`login` AS `modifier_user`, uue.`real_name` AS `modifier_real_name`,
+ uuc.`login` AS `creator_user`, uuc.`real_name` AS `creator_real_name` ,
+ la.`attachment_id` AS `primary_attachment_id`, lf.`file_name` AS `image_attachment_path` $selectSql
+ FROM `".BIT_DB_PREFIX."articles` a
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_types` atype ON( atype.`article_type_id` = a.`article_type_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_topics` atopic ON( atopic.`topic_id` = a.`topic_id` )
+ INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON( lc.`content_id` = a.`content_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON( lch.`content_id` = lc.`content_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."users_users` uue ON( uue.`user_id` = lc.`modifier_user_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."users_users` uuc ON( uuc.`user_id` = lc.`user_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` la ON( la.`content_id` = lc.`content_id` AND la.`is_primary` = 'y' )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf ON( lf.`file_id` = la.`foreign_id` )
+ $joinSql
+ WHERE a.`$lookupColumn`=? $whereSql";
+ $result = $this->mDb->query( $query, $bindVars );
+
+ global $gBitSystem;
+ if ( $result && $result->numRows() ) {
+ $this->mInfo = $result->fetchRow();
+
+ // if a custom image for the article exists, use that, then use an attachment, then use the topic image
+ $isTopicImage = false;
+
+ $this->mContentId = $this->mInfo['content_id'];
+ $this->mArticleId = $this->mInfo['article_id'];
+ $this->mTopicId = $this->mInfo['topic_id'];
+ $this->mTypeId = $this->mInfo['article_type_id'];
+
+ $this->mInfo['thumbnail_url'] = static::getImageThumbnails( $this->mInfo );
+ $this->mInfo['creator'] = ( !empty( $this->mInfo['creator_real_name'] ) ? $this->mInfo['creator_real_name'] : $this->mInfo['creator_user'] );
+ $this->mInfo['editor'] = ( !empty( $this->mInfo['modifier_real_name'] ) ? $this->mInfo['modifier_real_name'] : $this->mInfo['modifier_user'] );
+ $this->mInfo['display_url'] = $this->getDisplayUrl();
+ // we need the raw data to display in the textarea
+ $this->mInfo['raw'] = $this->mInfo['data'];
+ // here we have the displayed data without the ...split... stuff
+ $this->mInfo['data'] = preg_replace( LIBERTY_SPLIT_REGEX, "", $this->mInfo['data'] );
+
+ $comment = new LibertyComment();
+ $this->mInfo['num_comments'] = $comment->getNumComments( $this->mInfo['content_id'] );
+
+ LibertyMime::load();
+
+ if ( !empty( $this->mInfo['primary_attachment_id'] ) && !empty( $this->mStorage[$this->mInfo['primary_attachment_id']] )) {
+ $this->mInfo['primary_attachment'] = &$this->mStorage[$this->mInfo['primary_attachment_id']];
+ }
+
+ $this->mInfo['parsed'] = $this->parseData();
+ } else {
+ $this->mArticleId = NULL;
+ }
+ }
+
+ return( count( $this->mInfo ) );
+ }
+
+ /**
+ * Store article data after submission
+ * @param array pParamHash of values that will be used to store the page
+ * @return bool TRUE on success, FALSE if store could not occur. If FALSE, $this->mErrors will have reason why
+ * @access public
+ **/
+ public function store(&$pParamHash)
+ {
+ global $gBitSystem;
+ $this->StartTrans();
+ if ( $this->verify( $pParamHash )&& LibertyMime::store( $pParamHash ) ) {
+ $table = BIT_DB_PREFIX."articles";
+
+ if ( $this->isValid() ) {
+ $result = $this->mDb->associateUpdate( $table, $pParamHash['article_store'], array( "article_id" => $this->mArticleId ));
+ } else {
+ $pParamHash['article_store']['content_id'] = $pParamHash['content_id'];
+ if ( isset( $pParamHash['article_id'] )&& is_numeric( $pParamHash['article_id'] ) ) {
+ // if pParamHash['article_id'] is set, someone is requesting a particular article_id. Use with caution!
+ $pParamHash['article_store']['article_id'] = $pParamHash['article_id'];
+ } else {
+ $pParamHash['article_store']['article_id'] = $this->mDb->GenID( 'articles_article_id_seq' );
+ }
+ $this->mArticleId = $pParamHash['article_store']['article_id'];
+ $result = $this->mDb->associateInsert( $table, $pParamHash['article_store'] );
+ }
+
+ $this->CompleteTrans();
+ $this->load();
+ }
+ return ( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * Make sure the data is safe to store
+ * @param pParamHash be sure to pass by reference in case we need to make modifcations to the hash
+ * @param array pParams reference to hash of values that will be used to store the page, they will be modified where necessary
+ * @return bool TRUE on success, FALSE if verify failed. If FALSE, $this->mErrors will have reason why
+ * @access private
+ **/
+ public function verify(&$pParamHash)
+ {
+ global $gBitUser, $gBitSystem;
+
+ // make sure we're all loaded up of we have a mArticleId
+ if ( $this->mArticleId && empty( $this->mInfo ) ) {
+ $this->load();
+ }
+
+ if ( @$this->verifyId( $this->mInfo['content_id'] ) ) {
+ $pParamHash['content_id'] = $this->mInfo['content_id'];
+ }
+
+ // It is possible a derived class set this to something different
+ if ( empty( $pParamHash['content_type_guid'] )&& !empty( $this->mContentTypeGuid ) ) {
+ $pParamHash['content_type_guid'] = $this->mContentTypeGuid;
+ }
+
+ if ( @$this->verifyId( $pParamHash['content_id'] ) ) {
+ $pParamHash['article_store']['content_id'] = $pParamHash['content_id'];
+ }
+
+ if ( !empty( $pParamHash['author_name'] ) ) {
+ $pParamHash['article_store']['author_name'] = $pParamHash['author_name'];
+ }
+
+ if ( @$this->verifyId( $pParamHash['topic_id'] ) ) {
+ $pParamHash['article_store']['topic_id'] =(int) $pParamHash['topic_id'];
+ }
+
+ if ( @$this->verifyId( $pParamHash['article_type_id'] ) ) {
+ $pParamHash['article_store']['article_type_id'] =(int) $pParamHash['article_type_id'];
+ }
+
+ if ( !empty( $pParamHash['format_guid'] ) ) {
+ $pParamHash['content_store']['format_guid'] = $pParamHash['format_guid'];
+ }
+
+ // we do the substr on load. otherwise we need to store the same data twice.
+ if ( !empty( $pParamHash['edit'] ) ) {
+ $pParamHash['content_store']['data'] = $pParamHash['edit'];
+ }
+
+ if ( !empty( $pParamHash['rating'] ) ) {
+ $pParamHash['article_store']['rating'] =(int) ( $pParamHash['rating'] );
+ }
+
+ // check for name issues, first truncate length if too long
+ if ( !empty( $pParamHash['title'] ) ) {
+ if ( !$this->isValid() ) {
+ if ( empty( $pParamHash['title'] ) ) {
+ $this->mErrors['title'] = 'You must specify a title.';
+ } else {
+ $pParamHash['content_store']['title'] = substr( $pParamHash['title'], 0, BIT_CONTENT_MAX_TITLE_LEN );
+ }
+ } else {
+ $pParamHash['content_store']['title'] =( isset( $pParamHash['title'] ))? substr( $pParamHash['title'], 0, BIT_CONTENT_MAX_TITLE_LEN ): '';
+ }
+ } elseif ( empty( $pParamHash['title'] ) ) {
+ // no name specified
+ $this->mErrors['title'] = 'You must specify a title';
+ }
+
+ if ( !empty( $pParamHash['publish_Month'] ) ) {
+ $dateString = $this->mDate->gmmktime(
+ $pParamHash['publish_Hour'],
+ $pParamHash['publish_Minute'],
+ isset($pParamHash['publish_Second']) ? $pParamHash['publish_Second'] : 0,
+ $pParamHash['publish_Month'],
+ $pParamHash['publish_Day'],
+ $pParamHash['publish_Year']
+ );
+
+ $timestamp = $this->mDate->getUTCFromDisplayDate( $dateString );
+ if ($timestamp !== -1) {
+ $pParamHash['publish_date'] = $timestamp;
+ }
+ }
+ if ( !empty( $pParamHash['publish_date'] ) ) {
+ $pParamHash['article_store']['publish_date'] = $pParamHash['publish_date'];
+ }
+
+ if ( !empty( $pParamHash['expire_Month'] ) ) {
+ $dateString = $this->mDate->gmmktime(
+ $pParamHash['expire_Hour'],
+ $pParamHash['expire_Minute'],
+ isset($pParamHash['expire_Second']) ? $pParamHash['expire_Second'] : 0,
+ $pParamHash['expire_Month'],
+ $pParamHash['expire_Day'],
+ $pParamHash['expire_Year']
+ );
+
+ $timestamp = $this->mDate->getUTCFromDisplayDate( $dateString );
+ if ($timestamp !== -1) {
+ $pParamHash['expire_date'] = $timestamp;
+ }
+ }
+ if ( !empty( $pParamHash['expire_date'] ) ) {
+ $pParamHash['article_store']['expire_date'] = $pParamHash['expire_date'];
+ }
+
+ if ( @$this->verifyId( $pParamHash['status_id'] ) ) {
+ if ($pParamHash['status_id'] > ARTICLE_STATUS_PENDING) {
+ if ( $gBitUser->hasPermission( 'p_articles_approve_submission' )) {
+ $pParamHash['article_store']['status_id'] =(int) ( $pParamHash['status_id'] );
+ } else {
+ $pParamHash['article_store']['status_id'] = ARTICLE_STATUS_PENDING;
+ }
+ } else {
+ $pParamHash['article_store']['status_id'] =(int) ( $pParamHash['status_id'] );
+ }
+ } elseif ( @$this->verifyId( $this->mInfo['status_id'] ) ) {
+ $pParamHash['article_store']['status_id'] = $this->mInfo['status_id'];
+ } else {
+ if ( $gBitUser->hasPermission( 'p_articles_approve_submission' ) || $gBitUser->hasPermission( 'p_articles_auto_approve' ) ) {
+ $pParamHash['article_store']['status_id'] = ARTICLE_STATUS_APPROVED;
+ } else {
+ $pParamHash['article_store']['status_id'] = ARTICLE_STATUS_PENDING; // Default status
+ }
+ }
+
+ // content preferences
+ $prefs = array();
+ if ( $gBitUser->hasPermission( 'p_liberty_enter_html' ) ) {
+ $prefs[] = 'content_enter_html';
+ }
+
+ foreach ($prefs as $pref) {
+ if ( !empty( $pParamHash['preferences'][$pref] ) ) {
+ $pParamHash['preferences_store'][$pref] = $pParamHash['preferences'][$pref];
+ } else {
+ $pParamHash['preferences_store'][$pref] = NULL;
+ }
+ }
+
+ if ( array_search( $pParamHash['article_store']['status_id'], array( ARTICLE_STATUS_DENIED, ARTICLE_STATUS_DRAFT, ARTICLE_STATUS_PENDING ) ) ) {
+ $this->mInfo["no_index"] = true ;
+ }
+
+ // if we have an error we get them all by checking parent classes for additional errors
+ if ( count( $this->mErrors ) > 0 ) {
+ parent::verify( $pParamHash );
+ }
+
+ return( count( $this->mErrors )== 0 );
+ }
+
+ /**
+ * Deal with images and text, modify them apprpriately that they can be returned to the form.
+ * @param $previewData data submitted by form - generally $_REQUEST
+ * @return array of data compatible with article form
+ * @access public
+ **/
+ public function preparePreview($pParamHash)
+ {
+ global $gBitSystem, $gBitUser;
+
+ $data = $pParamHash;
+ $this->verify( $data );
+ $data = array_merge( $pParamHash, $data['content_store'], $data['article_store'] );
+ $data['raw'] = $data['edit'];
+
+ if ( empty( $data['user_id'] ) ) {
+ $data['user_id'] = $gBitUser->mUserId;
+ }
+
+ if ( empty( $data['hits'] ) ) {
+ $data['hits'] = 0;
+ }
+
+ if ( empty( $data['publish_date'] ) ) {
+ $data['publish_date'] = $gBitSystem->getUTCTime();
+ }
+
+ if ( empty( $data['article_type_id'] ) ) {
+ $data['article_type_id'] = 1;
+ }
+
+ if ( empty( $data['topic_id'] ) ) {
+ $data['topic_id'] = 1;
+ }
+
+ if ( empty( $data['parsed'] ) ) {
+ $data['no_cache'] = TRUE;
+ $data['parsed'] = $this->parseData( $data );
+ // replace the split syntax with a horizontal rule
+ $data['parsed'] = preg_replace( LIBERTY_SPLIT_REGEX, "<hr />", $data['parsed'] );
+ }
+
+ $articleType = new BitArticleType( $data['article_type_id'] );
+ $articleTopic = new BitArticleTopic( $data['topic_id'] );
+ $data = array_merge( $data, $articleType->mInfo, $articleTopic->mInfo );
+
+ return $data;
+ }
+
+ /**
+ * Get the URL for any given article image
+ * @param $pParamHash pass in full set of data returned from article query
+ * @return url to image
+ * @access public
+ **/
+ public static function getImageThumbnails($pParamHash)
+ {
+ global $gBitSystem, $gThumbSizes;
+ $ret = NULL;
+
+ $thumbHash['mime_image'] = FALSE;
+ if ( !empty( $pParamHash['image_attachment_path'] )) {
+ $thumbHash['source_file'] = $pParamHash['image_attachment_path'];
+ $ret = liberty_fetch_thumbnails( $thumbHash );
+ } elseif ( !empty( $pParamHash['has_topic_image'] ) && $pParamHash['has_topic_image'] == 'y' ) {
+return BitArticleTopic::getTopicImageStorageUrl( $pParamHash['topic_id'] );
+ $thumbHash['source_file'] = preg_replace( "#^/+#", "", BitArticleTopic::getTopicImageStorageUrl( $pParamHash['topic_id'] ));
+ $ret = liberty_fetch_thumbnails( $thumbHash );
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Removes currently loaded article
+ * @return bool TRUE on success, FALSE on failure
+ * @access public
+ **/
+ public function expunge()
+ {
+ $ret = FALSE;
+ if ( $this->isValid() ) {
+ $this->StartTrans();
+ $query = "DELETE FROM `".BIT_DB_PREFIX."articles` WHERE `content_id` = ?";
+ $result = $this->mDb->query( $query, array( $this->mContentId ) );
+ if ( LibertyMime::expunge() ) {
+ $ret = TRUE;
+ $this->CompleteTrans();
+ } else {
+ $this->RollbackTrans();
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Check if there is an article loaded
+ * @return bool TRUE on success, FALSE on failure
+ * @access public
+ **/
+ public function isValid()
+ {
+ return( $this->verifyId( $this->mArticleId ) && $this->verifyId( $this->mContentId ) );
+ }
+
+ /**
+ * This function generates a list of records from the liberty_content database for use in a list page
+ * @param $pParamHash contains an array of conditions to sort by
+ * @return array of articles
+ * @access public
+ **/
+ public function getList(&$pParamHash)
+ {
+ global $gBitSystem, $gBitUser, $gLibertySystem;
+
+ if ( empty( $pParamHash['sort_mode'] ) ) {
+ // no idea what this is supposed to do
+ //$pParamHash['sort_mode'] = $gBitSystem->isFeatureActive('articles_auto_approve') ? 'order_key_desc' : 'publish_date_desc';
+ $pParamHash['sort_mode'] = 'publish_date_desc';
+ }
+
+ LibertyContent::prepGetList( $pParamHash );
+
+ $joinSql = '';
+ $selectSql = '';
+ $bindVars = array();
+ array_push( $bindVars, $this->mContentTypeGuid );
+ $this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars, NULL, $pParamHash );
+
+ $find = $pParamHash['find'];
+ if ( is_array( $find ) ) {
+ // you can use an array of articles
+ $whereSql .= " AND lc.`title` IN( ".implode( ',',array_fill( 0, count( $find ),'?' ) )." )";
+ $bindVars = array_merge( $bindVars, $find );
+ } elseif ( is_string( $find ) ) {
+ // or a string
+ $whereSql .= " AND UPPER( lc.`title` ) LIKE ? ";
+ $bindVars[] = '%'.strtoupper( $find ).'%';
+ } elseif ( @$this->verifyId( $pParamHash['user_id'] ) ) {
+ // or gate on a user
+ $whereSql .= " AND lc.`user_id` = ? ";
+ $bindVars[] = (int) $pParamHash['user_id'];
+ }
+
+ if ( @$this->verifyId( $pParamHash['status_id'] ) ) {
+ $whereSql .= " AND a.`status_id` = ? ";
+ $bindVars[] = $pParamHash['status_id'];
+ }
+
+ if ( @$this->verifyId( $pParamHash['type_id'] ) ) {
+ $whereSql .= " AND a.`article_type_id` = ? ";
+ $bindVars[] = (int) $pParamHash['type_id'];
+ }
+
+ // TODO: we need to check if the article wants to be viewed before / after respective dates
+ // someone better at SQL please get this working without an additional db call - xing
+ $now = $gBitSystem->getUTCTime();
+ if ( !empty( $pParamHash['show_future'] ) && !empty( $pParamHash['show_expired'] ) && $gBitUser->hasPermission( 'p_articles_admin' )) {
+ // this will show all articles at once - future, current and expired
+ } elseif ( !empty( $pParamHash['show_future'] ) && $gBitUser->hasPermission( 'p_articles_admin' )) {
+ // hide expired articles
+ $whereSql .= " AND ( a.`expire_date` > ? OR atype.`show_post_expire` = ? ) ";
+ $bindVars[] = (int) $now;
+ $bindVars[] = 'y';
+ } elseif ( !empty( $pParamHash['show_expired'] ) && $gBitUser->hasPermission( 'p_articles_admin' )) {
+ // hide future articles
+ $whereSql .= " AND ( a.`publish_date` < ? OR atype.`show_pre_publ` = ? ) ";
+ $bindVars[] = (int) $now;
+ $bindVars[] = 'y';
+ } elseif ( !empty( $pParamHash['get_future'] )) {
+ // show only future
+ // if we're trying to view these articles, we better have the perms to do so
+ if ( !$gBitUser->hasPermission( 'p_articles_admin' )) {
+ return array();
+ }
+ $whereSql .= " AND a.`publish_date` > ?";
+ $bindVars[] = (int) $now;
+ } elseif ( !empty( $pParamHash['get_expired'] )) {
+ // show only expired articles
+ // if we're trying to view these articles, we better have the perms to do so
+ if ( !$gBitUser->hasPermission( 'p_articles_admin' )) {
+ return array();
+ }
+ $whereSql .= " AND a.`expire_date` < ? ";
+ $bindVars[] = (int) $now;
+ } else {
+ // hide future and expired articles - this is the default behaviour
+ // we need all these AND and ORs to ensure that other conditions such as status_id are respected as well
+ $whereSql .= " AND (( a.`publish_date` > a.`expire_date` ) OR (( a.`publish_date` < ? OR atype.`show_pre_publ` = ? ) AND ( a.`expire_date` > ? OR atype.`show_post_expire` = ? ))) ";
+ $bindVars[] = (int) $now;
+ $bindVars[] = 'y';
+ $bindVars[] = (int) $now;
+ $bindVars[] = 'y';
+ }
+
+ if ( @$this->verifyId( $pParamHash['topic_id'] ) ) {
+ $whereSql .= " AND a.`topic_id` = ? ";
+ $bindVars[] = (int) $pParamHash['topic_id'];
+ } elseif ( !empty( $pParamHash['topic'] ) ) {
+ $whereSql .= " AND UPPER( atopic.`topic_name` ) = ? ";
+ $bindVars[] = strtoupper( $pParamHash['topic'] );
+ } else {
+ $whereSql .= " AND ( atopic.`active_topic` != 'n' OR atopic.`active_topic` IS NULL ) ";
+ //$whereSql .= " AND atopic.`active_topic` != 'n' ";
+ }
+
+ // Oracle is very particular about naming multiple columns, so need to explicity name them ORA-00918: column ambiguously defined
+ $query =
+ "SELECT
+ a.`article_id`, a.`description`, a.`author_name`, a.`publish_date`, a.`expire_date`, a.`rating`,
+ atopic.`topic_id`, atopic.`topic_name`, atopic.`has_topic_image`, atopic.`active_topic`,
+ astatus.`status_id`, astatus.`status_name`,
+ lch.`hits`,
+ atype.*, lc.*, la.`attachment_id` AS `primary_attachment_id`, lf.`file_name` AS `image_attachment_path` $selectSql
+ FROM `".BIT_DB_PREFIX."articles` a
+ INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON( lc.`content_id` = a.`content_id` )
+ INNER JOIN `".BIT_DB_PREFIX."article_status` astatus ON( astatus.`status_id` = a.`status_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON( lc.`content_id` = lch.`content_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_topics` atopic ON( atopic.`topic_id` = a.`topic_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_types` atype ON( atype.`article_type_id` = a.`article_type_id` )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` la ON( la.`content_id` = lc.`content_id` AND la.`is_primary` = 'y' )
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf ON( lf.`file_id` = la.`foreign_id` )
+ $joinSql
+ WHERE lc.`content_type_guid` = ? $whereSql
+ ORDER BY ".$this->mDb->convertSortmode( $pParamHash['sort_mode'] );
+
+ $query_cant = "SELECT COUNT( * )FROM `".BIT_DB_PREFIX."articles` a
+ INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON lc.`content_id` = a.`content_id`
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_topics` atopic ON atopic.`topic_id` = a.`topic_id` $joinSql
+ LEFT OUTER JOIN `".BIT_DB_PREFIX."article_types` atype ON atype.`article_type_id` = a.`article_type_id`
+ WHERE lc.`content_type_guid` = ? $whereSql";
+
+ $result = $this->mDb->query( $query, $bindVars, $pParamHash['max_records'], $pParamHash['offset'] );
+ $ret = array();
+ $comment = new LibertyComment();
+ while ( $res = $result->fetchRow() ) {
+ // get this stuff parsed
+ $res = array_merge( $this->parseSplit( $res, $gBitSystem->getConfig( 'articles_description_length', 500 )), $res );
+
+ $res['thumbnail_url'] = static::getImageThumbnails( $res );
+ $res['num_comments'] = $comment->getNumComments( $res['content_id'] );
+ $res['display_url'] = self::getDisplayUrlFromHash( $res );
+ $res['display_link'] = $this->getDisplayLink( $res['title'], $res );
+
+ // fetch the primary attachment that we can display the file on the front page if needed
+ $res['primary_attachment'] = LibertyMime::loadAttachment( $res['primary_attachment_id'] );
+
+ $ret[] = $res;
+ }
+
+ $pParamHash["cant"] = $this->mDb->getOne( $query_cant, $bindVars );
+
+ LibertyContent::postGetList( $pParamHash );
+
+ return $ret;
+ }
+
+ /**
+ * Returns include file that will setup vars for display
+ * @return the fully specified path to file to be included
+ */
+ public function getRenderFile()
+ {
+ return ARTICLES_PKG_PATH."display_article_inc.php";
+ }
+
+ /**
+ * Get a list of articles that are to be published in the future
+ *
+ * @param array $pParamHash contains listing options - same as getList()
+ * @access public
+ * @return array of articles
+ */
+ public function getFutureList(&$pParamHash)
+ {
+ $pParamHash['get_future'] = TRUE;
+ return( $this->getList( $pParamHash ));
+ }
+
+ /**
+ * Get list of articles that have expired and are not displayed on the site anymore
+ *
+ * @param array $pParamHash contains listing options - same as getList()
+ * @access public
+ * @return array of articles
+ */
+ public function getExpiredList(&$pParamHash)
+ {
+ $pParamHash['get_expired'] = TRUE;
+ return( $this->getList( $pParamHash ));
+ }
+
+ /**
+ * Generates the URL to the article
+ * @return the link to the full article
+ */
+ public static function getDisplayUrlFromHash(&$pParamHash)
+ {
+ global $gBitSystem;
+
+ $ret = NULL;
+
+ if ( @BitBase::verifyId( $pParamHash['article_id'] ) ) {
+ if ( $gBitSystem->isFeatureActive( 'pretty_urls_extended' ) ) {
+ // Not needed since it's a number: $ret = ARTICLES_PKG_URL."view/".$this->mArticleId;
+ $ret = ARTICLES_PKG_URL.$pParamHash['article_id'];
+ } elseif ( $gBitSystem->isFeatureActive( 'pretty_urls' ) ) {
+ $ret = ARTICLES_PKG_URL.$pParamHash['article_id'];
+ } else {
+ $ret = ARTICLES_PKG_URL."read.php?article_id=".$pParamHash['article_id'];
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Function that returns link to display an image
+ * @return the url to display the gallery.
+ */
+ public function getDisplayUrl()
+ {
+ $info = array( 'article_id' => $this->mArticleId );
+ return self::getDisplayUrlFromHash( $info );
+ }
+
+ /**
+ * get a list of all available statuses
+ * @return an array of available statuses
+ * @access public
+ **/
+ public function getStatusList()
+ {
+ global $gBitSystem;
+ $query = "SELECT * FROM `".BIT_DB_PREFIX."article_status`";
+ $result = $gBitSystem->mDb->query( $query );
+ return $result->getRows();
+ }
+
+ /**
+ * set the status of an article
+ * @param $pStatusId new status id of the article
+ * @param $pArticleId of the article that is being changed - if not set, it will attemtp to change the currently loaded article
+ * @return new status of article on success - else returns NULL
+ * @access public
+ **/
+ public function setStatus($pStatusId, $pArticleId = NULL, $pContentId = NULL)
+ {
+ global $gBitSystem;
+ $validStatuses = array( ARTICLE_STATUS_DENIED, ARTICLE_STATUS_DRAFT, ARTICLE_STATUS_PENDING, ARTICLE_STATUS_APPROVED, ARTICLE_STATUS_RETIRED );
+
+ if ( !in_array( $pStatusId, $validStatuses ) ) {
+ $this->mErrors[] = "Invalid article status";
+ return FALSE;
+ }
+
+ if( empty( $pContentId ) and $this->isValid()) $pContentId = $this->mContentId ;
+ if( empty( $pArticleId ) and $this->isValid()) $pArticleId = $this->mArticleId ;
+ if( !empty( $pContentId ) and !$this->isValid()) $this->mContentId = $pContentId ;
+ if( !empty( $pArticleId ) and !$this->isValid()) $this->mArticleId = $pArticleId ;
+
+ if ( empty( $pArticleId ) && $this->isValid() ) {
+ $pArticleId = $this->mArticleId;
+ }
+
+ if ( @$this->verifyId( $pArticleId ) ) {
+ $sql = "UPDATE `".BIT_DB_PREFIX."articles` SET `status_id` = ? WHERE `article_id` = ?";
+ $rs = $this->mDb->query( $sql, array( $pStatusId, $pArticleId ));
+ // Calling the index function for approved articles ...
+ if ( $gBitSystem->isPackageActive( 'search' ) ) {
+ include_once( SEARCH_PKG_PATH.'refresh_functions.php' );
+ if ($pStatusId == ARTICLE_STATUS_APPROVED) {
+ refresh_index($this);
+ } elseif (!$pStatusId == ARTICLE_STATUS_RETIRED) {
+ delete_index($pContentId); // delete it from the search index unless retired ...
+ }
+ }
+ return $pStatusId;
+ }
+ }
+}
diff --git a/includes/classes/BitArticleTopic.php b/includes/classes/BitArticleTopic.php
new file mode 100644
index 0000000..f2c59b9
--- /dev/null
+++ b/includes/classes/BitArticleTopic.php
@@ -0,0 +1,465 @@
+<?php
+/**
+ * @version $Header$
+ * @package articles
+ *
+ * @copyright Copyright (c) 2004-2006, bitweaver.org
+ * All Rights Reserved. See below for details and a complete list of authors.
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details.
+ */
+
+/**
+ * Required setup
+ */
+global $gBitSystem;
+require_once( KERNEL_PKG_PATH."BitBase.php" );
+require_once( ARTICLES_PKG_CLASS_PATH.'BitArticle.php' );
+
+/**
+ * @package articles
+ */
+class BitArticleTopic extends BitBase {
+ var $mTopicId;
+
+ function __construct($iTopicId = NULL, $iTopicName = NULL) {
+ $this->mTopicId = NULL;
+ parent::__construct();
+ if ($iTopicId || $iTopicName) {
+ $this->loadTopic(array('topic_id'=>$iTopicId, 'topic_name'=>$iTopicName));
+ }
+ }
+
+ function isValid() {
+ return ($this->verifyId($this->mTopicId));
+ }
+
+ function loadTopic($iParamHash = NULL) {
+ $whereSQL = ' WHERE artt.';
+ $ret = NULL;
+
+ if (@$this->verifyId($iParamHash['topic_id']) || !empty($iParamHash['topic_name'])) {
+ $whereSQL .= "`".((@$this->verifyId($iParamHash['topic_id']) || $this->mTopicId) ? 'topic_id' : 'topic_name')."` = ?";
+ $bindVars = array((@$this->verifyId($iParamHash['topic_id']) ? (int)$iParamHash['topic_id'] : ($this->mTopicId ? $this->mTopicId : $iParamHash['topic_name'])) );
+
+ $sql = "SELECT artt.*".
+ "FROM `".BIT_DB_PREFIX."article_topics` artt ".
+ $whereSQL;
+ $this->mInfo = $this->mDb->getRow($sql, $bindVars);
+
+ if( !empty( $this->mInfo['topic_id'] ) ) {
+ $this->mTopicId = $this->mInfo['topic_id'];
+
+ if ($this->mInfo['has_topic_image']) {
+ $this->mInfo['topic_image_url'] = $this->getTopicImageStorageUrl(NULL, FALSE, TRUE);
+ } else {
+ $this->mInfo['topic_image_url'] = NULL;
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ function verify(&$iParamHash) {
+ // Validate the (optional) topic_id parameter
+ if (@$this->verifyId($iParamHash['topic_id'])) {
+ $cleanHash['topic_id'] = (int)$iParamHash['topic_id'];
+ } else {
+ $cleanHash['topic_id'] = NULL;
+ }
+
+ // Was an acceptable name given?
+ if (empty($iParamHash['topic_name']) || ($iParamHash['topic_name'] == '')) {
+ $this->mErrors['topic_name'] = tra("Invalid or blank topic name supplied");
+ } else if (empty($iParamHash['topic_id'])) {
+ $ret = $this->getTopicList( array( 'topic_name' => $iParamHash['topic_name'] ) );
+ if ( sizeof( $ret ) ) {
+ $this->mErrors['topic_name'] = 'Topic "'.$iParamHash['topic_name'].'" already exists. Please choose a different name.';
+ } else {
+ $cleanHash['topic_name'] = $iParamHash['topic_name'];
+ }
+ }
+ else {
+ $cleanHash['topic_name'] = $iParamHash['topic_name'];
+ }
+
+
+ // Whether the topic is active or not
+ if ( empty($iParamHash['active_topic']) || (strtoupper($iParamHash['active_topic']) != 'CHECKED' && strtoupper($iParamHash['active_topic']) != 'ON' && strtoupper($iParamHash['active_topic']) != 'Y')) {
+ if (@$this->verifyId($cleanHash['topic_id'])) {
+ $cleanHash['active_topic'] = 'n';
+ } else {
+ // Probably a new topic so lets go ahead and enable it
+ $cleanHash['active_topic'] = 'y';
+ }
+ } else {
+ $cleanHash['active_topic'] = 'y';
+ }
+
+ if (empty($iParamHash['created'])) {
+ global $gBitSystem;
+ $cleanHash['created'] = $gBitSystem->getUTCTime();
+ }
+
+ $iParamHash = $cleanHash;
+
+ return(count($this->mErrors) == 0);
+ }
+
+ function storeTopic($iParamHash = NULL) {
+ global $gLibertySystem;
+ global $gBitUser;
+
+ if ($this->verify($iParamHash)) {
+ if (!$iParamHash['topic_id']) {
+ $topicId = $this->mDb->GenID('article_topics_id_seq');
+ } else {
+ $topicId = $this->mTopicId;
+ }
+
+ if( !empty( $_FILES['upload'] ) && $_FILES['upload']['tmp_name'] ) {
+ $checkFunc = liberty_get_function( 'can_thumbnail' );
+ if( $checkFunc( $_FILES['upload']['type'] )) {
+ $fileHash = $_FILES['upload'];
+ $fileHash['dest_branch'] = $this->getTopicImageBaseUrl( $topicId );
+ $fileHash['source_file'] = $fileHash['tmp_name'];
+ liberty_clear_thumbnails( $fileHash );
+ liberty_generate_thumbnails( $fileHash );
+ $iParamHash['has_topic_image'] = 'y';
+ } else {
+ $this->mErrors = tra( "The file you uploaded doesn't appear to be a valid image. The reported mime type is" ).": ".$_FILES['upload']['type'];
+ }
+ }
+
+ if( $iParamHash['topic_id'] ) {
+ $this->mDb->associateUpdate( BIT_DB_PREFIX."article_topics", $iParamHash, array( 'topic_id' => $iParamHash['topic_id'] ) );
+ } else {
+ $iParamHash['topic_id'] = $topicId;
+ $this->mDb->associateInsert( BIT_DB_PREFIX."article_topics", $iParamHash );
+ }
+ }
+ $this->mTopicId = $iParamHash['topic_id'];
+ }
+
+ /**
+ * Work out the path to the image for this article
+ * @param $pTopicId id of the article we need the image path for
+ * @param $pBasePathOnly bool TRUE / FALSE - specify whether you want full path or just base path
+ * @return path on success, FALSE on failure
+ * @access public
+ **/
+ function getTopicImageBaseUrl( $pTopicId = NULL ) {
+ $ret = FALSE;
+ if( !@BitBase::verifyId( $pTopicId ) && $this->isValid() ) {
+ $pTopicId = $this->mTopicId;
+ }
+
+ if( @BitBase::verifyId( $pTopicId )) {
+ $ret = LibertyMime::getStorageUrl( 'topics/'.$pTopicId );
+ }
+ return $ret;
+ }
+
+ /**
+ * Get the full URL to the needed thumbnail
+ *
+ * @param numeric $pTopicId Topic ID of topic in question
+ * @access public
+ * @return Path to thumbnail, FALSE on failure
+ */
+ function getTopicImageThumbUrl( $pTopicId = NULL ) {
+ global $gBitSystem;
+ $ret = FALSE;
+ if( !@BitBase::verifyId( $pTopicId ) && $this->isValid() ) {
+ $pTopicId = $this->mTopicId;
+ }
+
+ if( @BitBase::verifyId( $pTopicId )) {
+ $ret = STORAGE_PKG_URL.ARTICLES_PKG_NAME.'/topic_'.$pTopicId.'.jpg';
+ }
+ return $ret;
+ }
+
+ public static function getTopicList( $pOptionHash=NULL ) {
+ global $gBitSystem;
+
+ $where = '';
+ $bindVars = array();
+ if( !empty( $pOptionHash['active_topic'] ) ) {
+ $where = " WHERE artt.`active_topic` = 'y' ";
+ }
+ if ( !empty( $pOptionHash['topic_name'] ) ) {
+ $where = " WHERE artt.`topic_name` = ? ";
+ $bindVars[] = $pOptionHash['topic_name'];
+ }
+
+ $query = "SELECT artt.*
+ FROM `".BIT_DB_PREFIX."article_topics` artt
+ $where ORDER BY artt.`topic_name`";
+
+ $result = $gBitSystem->mDb->query( $query, $bindVars );
+
+ $ret = array();
+
+ while( $res = $result->fetchRow() ) {
+ $res["num_articles"] = $gBitSystem->mDb->getOne( "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."articles` WHERE `topic_id`= ?", array( $res["topic_id"] ) );
+ if( empty( $res['topic_image_url'] ) && $res['has_topic_image'] == 'y' ) {
+ $res['topic_image_url'] = self::getTopicImageStorageUrl( $res['topic_id'] );
+ }
+
+ $ret[] = $res;
+ }
+
+ return $ret;
+ }
+
+ function removeTopicImage() {
+ if( $this->mTopicId ) {
+ if( file_exists($this->getTopicImageStoragePath() ) ) {
+ @unlink( $this->getTopicImageStoragePath() );
+ }
+ $sql = "UPDATE `".BIT_DB_PREFIX."article_topics` SET `has_topic_image` = 'n' WHERE `topic_id` = ?";
+ $rs = $this->mDb->query($sql, array($this->mTopicId));
+ $this->mInfo['has_topic_image'] = 'n';
+ }
+ }
+
+ function activateTopic() {
+ $this->setActivation(TRUE);
+ }
+
+ function deactivateTopic() {
+ $this->setActivation(FALSE);
+ }
+
+ function setActivation($iIsActive = FALSE) {
+ $sql = "UPDATE `".BIT_DB_PREFIX."article_topics` SET `active_topic` = '".($iIsActive ? 'y' : 'n')."' WHERE `topic_id` = ?";
+ $rs = $this->mDb->query($sql, array($this->mTopicId));
+ $this->mInfo['active_topic'] = ($iIsActive ? 'y' : 'n');
+ }
+
+ function getTopicArticles() {
+ if (!$this->mTopicId) {
+ return NULL;
+ }
+
+ $sql = "SELECT `article_id` FROM `".BIT_DB_PREFIX."articles` WHERE `topic_id` = ?";
+ $rs = $this->mDb->query($sql, array($this->mTopicId));
+
+ $ret = array();
+ while ($row = $rs->fetchRow()) {
+ $tmpArticle = new BitArticle($row['article_id']);
+ $tmpArticle->load();
+ $ret[] = $tmpArticle;
+ }
+ }
+
+ function removeTopic($iRemoveArticles = FALSE) {
+ if (!$this->mTopicId) {
+ return NULL;
+ }
+
+ $this->removeTopicImage();
+
+ if ($iRemoveArticles == TRUE) {
+ $topicArticles = $this->getTopicArticles();
+ for ($articleCount = 0; $articleCount < count($topicArticles); $articleCount++) {
+ $topicArticles[$articleCount]->expunge();
+ }
+ } else {
+ $sql = "UPDATE `".BIT_DB_PREFIX."articles` SET `topic_id` = ? WHERE `topic_id` = ?";
+ $rs = $this->mDb->query($sql, array(NULL, $this->mTopicId));
+ }
+
+ $sql = "DELETE FROM `".BIT_DB_PREFIX."article_topics` WHERE `topic_id` = ?";
+ $rs = $this->mDb->query($sql, array($this->mTopicId));
+ }
+
+
+
+
+ /*****************************************************************************
+ * Image functions needed for backward compatability - these are needed to *
+ * handle old article image style images that are not attachments. generally *
+ * these functions are deprecated but needed for legacy code *
+ ****************************************************************************/
+
+ /**
+ * Get the name of the article image file
+ *
+ * @param array $pTopicId article id
+ * @access public
+ * @return TRUE on success, FALSE on failure
+ */
+ function getTopicImageStorageName( $pTopicId = NULL ) {
+ if( !@BitBase::verifyId( $pTopicId ) ) {
+ if( $this->isValid() ) {
+ $pTopicId = $this->mTopicId;
+ } else {
+ return NULL;
+ }
+ }
+
+ global $gBitSystem;
+ return "topic_$pTopicId.".$gBitSystem->getConfig( 'liberty_thumbnail_format', 'jpg' );
+ }
+
+ /**
+ * Work out the path to the image for this article
+ * @param $pTopicId id of the article we need the image path for
+ * @param $pBasePathOnly bool TRUE / FALSE - specify whether you want full path or just base path
+ * @return path on success, FALSE on failure
+ * @access public
+ **/
+ function getTopicImageStoragePath( $pTopicId = NULL, $pBasePathOnly = FALSE ) {
+ $path = self::getArticleImageStoragePath( NULL, TRUE );
+
+ if( $pBasePathOnly ) {
+ return $path;
+ }
+
+ if( !@BitBase::verifyId( $pTopicId ) ) {
+ if( $this->isValid() ) {
+ $pTopicId = $this->mTopicId;
+ } else {
+ return NULL;
+ }
+ }
+
+ if( !empty( $pTopicId ) ) {
+ return $path.self::getTopicImageStorageName( $pTopicId );
+ } else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Work out the URL to the image for this article
+ * @param $pTopicId id of the article we need the image path for
+ * @param $pBasePathOnly bool TRUE / FALSE - specify whether you want full path or just base path
+ * @return URL on success, FALSE on failure
+ * @access public
+ **/
+ function getTopicImageStorageUrl( $pTopicId = NULL, $pBasePathOnly = FALSE, $pForceRefresh = FALSE ) {
+ global $gBitSystem;
+ $ret = FALSE;
+
+ // first we check to see if this is a new type thumbnail. if that fails we'll use the old method
+ if( !( $ret = self::getTopicImageThumbUrl( $pTopicId ))) {
+ $url = self::getArticleImageStorageUrl( NULL, TRUE );
+ if( $pBasePathOnly ) {
+ return $url;
+ }
+
+ if( !@BitBase::verifyId( $pTopicId ) ) {
+ if( $this->isValid() ) {
+ $pTopicId = $this->mTopicId;
+ } else {
+ return NULL;
+ }
+ }
+
+ if( is_file( self::getTopicImageStoragePath( NULL, TRUE ).self::getTopicImageStorageName( $pTopicId ))) {
+ $ret = $url.self::getTopicImageStorageName( $pTopicId ).( $pForceRefresh ? "?".$gBitSystem->getUTCTime() : '' );
+ }
+ }
+
+ return str_replace( "//", "/", $ret );
+ }
+
+
+
+
+ /*****************************************************************************
+ * Image functions needed for backward compatability - these are needed to *
+ * handle old article image style images that are not attachments. generally *
+ * these functions are deprecated but needed for legacy code *
+ * *
+ * the legacy code below here should go at some point. this code is old and *
+ * fugly. In fact, a lot of the code in here is fugly. we should use *
+ * pigoenholes to do this topic thing, now that pigoenholes can have primary *
+ * attachments. *
+ ****************************************************************************/
+
+ /**
+ * Get the name of the article image file
+ *
+ * @param array $pArticleId article id
+ * @access public
+ * @return TRUE on success, FALSE on failure
+ */
+ function getArticleImageStorageName( $pArticleId = NULL ) {
+ if( !@BitBase::verifyId( $pArticleId ) ) {
+ if( $this->isValid() ) {
+ $pArticleId = $this->mArticleId;
+ } else {
+ return NULL;
+ }
+ }
+
+ return "article_$pArticleId.jpg";
+ }
+
+ /**
+ * Work out the path to the image for this article
+ * @param $pArticleId id of the article we need the image path for
+ * @param $pBasePathOnly bool TRUE / FALSE - specify whether you want full path or just base path
+ * @return path on success, FALSE on failure
+ * @access public
+ **/
+ function getArticleImageStoragePath( $pArticleId = NULL, $pBasePathOnly = FALSE ) {
+ $path = STORAGE_PKG_PATH.ARTICLES_PKG_NAME.'/';
+ if( !is_dir( $path ) ) {
+ mkdir_p( $path );
+ }
+
+ if( $pBasePathOnly ) {
+ return $path;
+ }
+
+ if( !@BitBase::verifyId( $pArticleId ) ) {
+ if( $this->isValid() ) {
+ $pArticleId = $this->mArticleId;
+ } else {
+ return NULL;
+ }
+ }
+
+ if( !empty( $pArticleId ) ) {
+ return $path.self::getArticleImageStorageName( $pArticleId );
+ } else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Work out the URL to the image for this article
+ * @param $pArticleId id of the article we need the image path for
+ * @param $pBasePathOnly bool TRUE / FALSE - specify whether you want full path or just base path
+ * @return URL on success, FALSE on failure
+ * @access public
+ **/
+ function getArticleImageStorageUrl( $pArticleId = NULL, $pBasePathOnly = FALSE, $pForceRefresh = FALSE ) {
+ global $gBitSystem;
+ $url = STORAGE_PKG_URL.ARTICLES_PKG_NAME.'/';
+ if( $pBasePathOnly ) {
+ return $url;
+ }
+
+ if( !@BitBase::verifyId( $pArticleId ) ) {
+ if( $this->isValid() ) {
+ $pArticleId = $this->mArticleId;
+ } else {
+ return NULL;
+ }
+ }
+
+ if( is_file( self::getArticleImageStoragePath( NULL, TRUE ).self::getArticleImageStorageName( $pArticleId ) ) ) {
+ return $url.self::getArticleImageStorageName( $pArticleId ).( $pForceRefresh ? "?".$gBitSystem->getUTCTime() : '' );
+ } else {
+ return FALSE;
+ }
+ }
+}
+
+?>
diff --git a/includes/classes/BitArticleType.php b/includes/classes/BitArticleType.php
new file mode 100644
index 0000000..55f0fc9
--- /dev/null
+++ b/includes/classes/BitArticleType.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * @version $Header$
+ * @package articles
+ *
+ * @copyright Copyright (c) 2004-2006, bitweaver.org
+ * All Rights Reserved. See below for details and a complete list of authors.
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details.
+ */
+
+/**
+ * Required setup
+ */
+require_once (KERNEL_PKG_PATH."BitBase.php");
+require_once(ARTICLES_PKG_CLASS_PATH.'BitArticle.php');
+
+/**
+ * @package articles
+ */
+class BitArticleType extends BitBase
+{
+ public $mTypeId;
+
+ public function __construct($iTypeId = NULL)
+ {
+ $this->mTypeId = NULL;
+ parent::__construct();
+ if ($iTypeId) {
+ $this->loadType($iTypeId);
+ }
+ }
+
+ public function isValid()
+ {
+ return (@BitBase::verifyId($this->mTypeId));
+ }
+
+ public function loadType($iTypeId)
+ {
+ $ret = NULL;
+
+ if (!$this->mTypeId) {
+ $this->mTypeId = $iTypeId;
+ }
+
+ if ($this->mTypeId) {
+ $sql = "SELECT * FROM `".BIT_DB_PREFIX."article_types` WHERE `article_type_id` = ?";
+
+ if( $ret = $this->mDb->getRow( $sql, array( $this->mTypeId ) ) ) {
+ $ret['num_articles'] = $this->mDb->getOne('SELECT COUNT(*) FROM `'.BIT_DB_PREFIX.'articles` WHERE `article_type_id` = ?', array($ret['article_type_id']));
+ }
+ }
+ $this->mInfo = $ret;
+
+ return $ret;
+ }
+
+ public function verify(&$iParamHash)
+ {
+ $isNewType = FALSE;
+
+ // Validate the (optional) topic_id parameter
+ if (@BitBase::verifyId($iParamHash['article_type_id'])) {
+ $cleanHash['article_type_id'] = (int) $iParamHash['article_type_id'];
+ } else {
+ $isNewType = TRUE;
+ $cleanHash['article_type_id'] = NULL;
+ }
+
+ if (!$isNewType) {
+ $cleanHash['use_ratings'] = (!empty($iParamHash['use_ratings']) ? ($iParamHash['use_ratings']) : 'n');
+ $cleanHash['show_pre_publ'] = (!empty($iParamHash['show_pre_publ']) ? ($iParamHash['show_pre_publ']) : 'n');
+ $cleanHash['show_post_expire'] = (!empty($iParamHash['show_post_expire']) ? ($iParamHash['show_post_expire']) : 'n');
+ $cleanHash['heading_only'] = (!empty($iParamHash['heading_only']) ? ($iParamHash['heading_only']) : 'n');
+ $cleanHash['allow_comments'] = (!empty($iParamHash['allow_comments']) ? ($iParamHash['allow_comments']) : 'n');
+ $cleanHash['comment_can_rate_article'] = (!empty($iParamHash['comment_can_rate_article']) ? ($iParamHash['comment_can_rate_article']) : 'n');
+ $cleanHash['show_image'] = (!empty($iParamHash['show_image']) ? ($iParamHash['show_image']) : 'n');
+ $cleanHash['show_avatar'] = (!empty($iParamHash['show_avatar']) ? ($iParamHash['show_avatar']) : 'n');
+ $cleanHash['show_author'] = (!empty($iParamHash['show_author']) ? ($iParamHash['show_author']) : 'n');
+ $cleanHash['show_pubdate'] = (!empty($iParamHash['show_pubdate']) ? ($iParamHash['show_pubdate']) : 'n');
+ $cleanHash['show_expdate'] = (!empty($iParamHash['show_expdate']) ? ($iParamHash['show_expdate']) : 'n');
+ $cleanHash['show_reads'] = (!empty($iParamHash['show_reads']) ? ($iParamHash['show_reads']) : 'n');
+ $cleanHash['show_size'] = (!empty($iParamHash['show_size']) ? ($iParamHash['show_size']) : 'n');
+ $cleanHash['creator_edit'] = (!empty($iParamHash['creator_edit']) ? ($iParamHash['creator_edit']) : 'n');
+ $cleanHash['type_name'] = (!empty($iParamHash['type_name']) ? ($iParamHash['type_name']) : NULL);
+ } else {
+ // Was an acceptable name given?
+ if (empty($iParamHash['type_name']) || ($iParamHash['type_name'] == '')) {
+ $this->mErrors['type_name'] = tra("Invalid or blank article type name supplied");
+ } else {
+ $cleanHash['type_name'] = $iParamHash['type_name'];
+ }
+ }
+
+ $iParamHash = $cleanHash;
+ return(count($this->mErrors) == 0);
+ }
+
+ public function storeType(&$iParamHash)
+ {
+ global $gLibertySystem;
+ global $gBitUser;
+
+ if ($this->verify($iParamHash)) {
+ if (!$iParamHash['article_type_id']) {
+ if (empty($this->mTopicId)) {
+ $typeId = $this->mDb->GenID('article_types_id_seq');
+ } else {
+ $typeId = $this->mTopicId;
+ }
+ } else {
+ $typeId = $iParamHash['article_type_id'];
+ }
+
+ if ($iParamHash['article_type_id']) {
+ $this->mDb->associateUpdate(BIT_DB_PREFIX."article_types", $iParamHash, array( 'article_type_id'=> $iParamHash['article_type_id']));
+ } else {
+ $iParamHash['article_type_id'] = $typeId;
+ $this->mDb->associateInsert(BIT_DB_PREFIX."article_types", $iParamHash);
+ }
+ }
+ $this->mTypeId = $iParamHash['article_type_id'];
+ }
+
+ public function removeType($iTypeId = NULL)
+ {
+ if (!$iTypeId) {
+ if (!$this->mTypeId) {
+ $this->mErrors[] = tra("Invalid type id given");
+ return NULL;
+ } else {
+ $iTypeId = $this->mTypeId;
+ }
+ } else {
+ $iTypeId = (int)($iTypeId);
+ }
+
+ $sql = "DELETE FROM `".BIT_DB_PREFIX."article_types` WHERE `article_type_id` = ?";
+ $rs = $this->mDb->query($sql, array($iTypeId));
+ }
+
+ public static function getTypeList()
+ {
+ global $gBitSystem;
+
+ $query = "SELECT * FROM `" . BIT_DB_PREFIX . "article_types`";
+ $result = $gBitSystem->mDb->query( $query, array() );
+ $ret = array();
+
+ while ( $res = $result->fetchRow() ) {
+ $res['article_cnt'] = $gBitSystem->mDb->getOne( "select count(*) from `" . BIT_DB_PREFIX . "articles` where `article_type_id` = ?", array( $res['article_type_id'] ) );
+ $ret[] = $res;
+ }
+
+ return $ret;
+ }
+}