123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- <?php
- /**
- * Universal additional comments class which allows attach comments for any items on some scope
- */
- class ADcomments {
- /**
- * Current scope and item comments data as id=>commentData
- *
- * @var array
- */
- protected $allCommentsData = array();
- /**
- * Current instance scope
- *
- * @var string
- */
- protected $scope = '';
- /**
- * UbillingCache object placeholder
- *
- * @var object
- */
- protected $cache = '';
- /**
- * Comments caching time
- *
- * @var int
- */
- protected $cacheTime = 2592000; //month by default
- /**
- * Current instance item id
- *
- * @var string
- */
- protected $item = '';
- /**
- * Current instance administrator login
- *
- * @var string
- */
- protected $myLogin = '';
- /**
- * Current scope items counters as item=>commentsCount
- *
- * @var array
- */
- protected $scopeItems = array();
- /**
- * Comments data database abstraction layer
- *
- * @var object
- */
- protected $commentsDb = '';
- /**
- * Scope items loaded flag
- *
- * @var bool
- */
- protected $scopeItemsLoaded = false;
- /**
- * Default editing area size
- *
- * @var string
- */
- protected $textAreaSize = '60x10';
- /**
- * Some predefined stuff here
- */
- const TABLE_COMMENTS = 'adcomments';
- const PROUTE_NEW_TEXT = 'newadcommentstext';
- const PROUTE_EDIT_FORM = 'adcommentseditid';
- const PROUTE_EDIT_ID = 'adcommentsmodifyid';
- const PROUTE_EDIT_TEXT = 'adcommentsmodifytext';
- const PROUTE_DELETE = 'adcommentsdeleteid';
- const CACHE_KEY = 'ADCOMMENTS_';
- /**
- * when everything goes wrong
- */
- const EX_EMPTY_SCOPE = 'EMPTY_SCOPE_RECEIVED';
- const EX_EMPTY_ITEM = 'EMPTY_ITEMID_RECEIVED';
- const EX_EMPTY_QUERY_STRING = 'EMPTY_SERVER_QUERY_STRING_RECEIVED';
- /**
- * ADcomments class constructor
- *
- * @param string $scope Object scope for comments tree
- */
- public function __construct($scope) {
- if (!empty($scope)) {
- $this->setScope($scope);
- $this->setMyLogin();
- $this->initCache();
- $this->initDb();
- } else {
- throw new Exception(self::EX_EMPTY_SCOPE);
- }
- }
- /**
- * Current instance comments scope
- *
- * @param string $scope scope of items comments
- *
- * @return void
- */
- protected function setScope($scope) {
- $scope = trim($scope);
- $scope = ubRouting::filters($scope, 'mres');
- $this->scope = $scope;
- }
- /**
- * Sets current administrator login into private prop
- *
- * @return void
- */
- protected function setMyLogin() {
- $this->myLogin = whoami();
- }
- /**
- * Initalizes system cache object for further usage
- *
- * @return void
- */
- protected function initCache() {
- $this->cache = new UbillingCache();
- }
- /**
- * Inits database abstraction layer
- *
- * @return void
- */
- protected function initDb() {
- $this->commentsDb = new NyanORM(self::TABLE_COMMENTS);
- }
- /**
- * Clear scope cache object
- *
- * @return void
- */
- protected function clearScopeCache() {
- $this->cache->delete(self::CACHE_KEY . $this->scope);
- }
- /**
- * Sets current scope item commenting ID
- *
- * @param string $item target item ID
- *
- * @return void
- */
- protected function setItem($item) {
- $item = trim($item);
- $item = ubRouting::filters($item, 'mres');
- $this->item = $item;
- }
- /**
- * Loads selected scope and item comments into private data property
- *
- * @return void
- */
- protected function loadComments() {
- if (!empty($this->scope)) {
- if (!empty($this->item)) {
- $this->commentsDb->where('scope', '=', $this->scope);
- $this->commentsDb->where('item', '=', $this->item);
- $this->commentsDb->orderBy('date', 'ASC');
- $this->allCommentsData = $this->commentsDb->getAll('id');
- } else {
- throw new Exception(self::EX_EMPTY_ITEM);
- }
- } else {
- throw new Exception(self::EX_EMPTY_SCOPE);
- }
- }
- /**
- * Returns new comment creation form
- *
- * @return string
- */
- protected function commentAddForm() {
- $result = '';
- $inputs = wf_TextArea(self::PROUTE_NEW_TEXT, '', '', true, $this->textAreaSize);
- $inputs .= wf_Submit(__('Save'));
- $result .= wf_tag('div', false, '', 'style="float:left;"');
- $result .= wf_Form('', 'POST', $inputs, 'glamour');
- $result .= wf_tag('div', true);
- //princess fast reply form if its enabled?
- if ($this->scope == 'TASKMAN') {
- $adCommFr = new ADcommFR();
- $result .= $adCommFr->renderPrincessFastReplies();
- }
- $result .= wf_CleanDiv();
- return ($result);
- }
- /**
- * Creates some new comment in database
- *
- * @param string $text text of new comment
- *
- * @return void
- */
- protected function createComment($text) {
- $curdate = curdatetime();
- $text = strip_tags($text);
- $text = ubRouting::filters($text, 'mres');
- $this->commentsDb->data('scope', $this->scope);
- $this->commentsDb->data('item', $this->item);
- $this->commentsDb->data('date', $curdate);
- $this->commentsDb->data('admin', $this->myLogin);
- $this->commentsDb->data('text', $text);
- $this->commentsDb->create();
- log_register('ADCOMM CREATE SCOPE `' . $this->scope . '` ITEM [' . $this->item . ']');
- $this->clearScopeCache();
- }
- /**
- * Deletes comment from database
- *
- * @param int $id existing comment database ID
- *
- * @return void
- */
- protected function deleteComment($id) {
- $id = ubRouting::filters($id, 'int');
- $this->commentsDb->where('id', '=', $id);
- $this->commentsDb->delete();
- log_register('ADCOMM DELETE SCOPE `' . $this->scope . '` ITEM [' . $this->item . ']');
- $this->clearScopeCache();
- }
- /**
- * Edits some comment text in database
- *
- * @param int $id existing comment database ID
- * @param string $text new text for comment
- *
- * @return void
- */
- protected function modifyComment($id, $text) {
- $id = ubRouting::filters($id, 'int');
- $text = strip_tags($text);
- $text = ubRouting::filters($text, 'mres');
- $this->commentsDb->data('text', $text);
- $this->commentsDb->where('id', '=', $id);
- $this->commentsDb->save();
- log_register('ADCOMM CHANGE SCOPE `' . $this->scope . '` ITEM [' . $this->item . ']');
- $this->clearScopeCache();
- }
- /**
- * Controls post environment and do something object actions when its required
- *
- * @return void
- */
- protected function commentSaver() {
- //detecting return URL
- if (isset($_SERVER['QUERY_STRING'])) {
- $returnUrl = '?' . $_SERVER['QUERY_STRING'];
- } else {
- $returnUrl = '';
- show_error(__('Strange exeption') . ': ' . self::EX_EMPTY_QUERY_STRING);
- }
- ///new comment creation
- if (ubRouting::checkPost(self::PROUTE_NEW_TEXT)) {
- $this->createComment(ubRouting::post(self::PROUTE_NEW_TEXT));
- if ($returnUrl) {
- ubRouting::nav($returnUrl);
- }
- }
- //comment deletion
- if (ubRouting::checkPost(self::PROUTE_DELETE)) {
- $this->deleteComment(ubRouting::post(self::PROUTE_DELETE));
- if ($returnUrl) {
- ubRouting::nav($returnUrl);
- }
- }
- //comment editing
- if (ubRouting::checkPost(array(self::PROUTE_EDIT_ID, self::PROUTE_EDIT_TEXT))) {
- $this->modifyComment(ubRouting::post(self::PROUTE_EDIT_ID), ubRouting::post(self::PROUTE_EDIT_TEXT));
- if ($returnUrl) {
- ubRouting::nav($returnUrl);
- }
- }
- }
- /**
- * Returns JavaScript comfirmation box for deleting/editing inputs
- *
- * @param string $alertText
- *
- * @return string
- */
- protected function jsAlert($alertText) {
- $result = 'onClick="return confirm(\'' . $alertText . '\');"';
- return ($result);
- }
- /**
- * Returns coment controls for own comments or for the user with root rights
- *
- * @param int $commentid existing additional comment ID
- * @return string
- */
- protected function commentControls($commentid) {
- $result = '';
- if (isset($this->allCommentsData[$commentid])) {
- if (($this->allCommentsData[$commentid]['admin'] == $this->myLogin) or (cfr('ROOT'))) {
- $deleteInputs = wf_HiddenInput(self::PROUTE_DELETE, $commentid);
- $deleteInputs .= wf_tag('input', false, '', 'type="image" src="skins/icon_del.gif" title="' . __('Delete') . '" ' . $this->jsAlert(__('Removing this may lead to irreparable results')));
- $deleteForm = wf_Form('', 'POST', $deleteInputs, '');
- $editInputs = wf_HiddenInput(self::PROUTE_EDIT_FORM, $commentid);
- $editInputs .= wf_tag('input', false, '', 'type="image" src="skins/icon_edit.gif" title="' . __('Edit') . '" ' . $this->jsAlert(__('Are you serious')));
- $editForm = wf_Form('', 'POST', $editInputs, '');
- $result .= wf_tag('div', false, '', 'style="display:inline-block;"') . $deleteForm . wf_tag('div', true);
- $result .= wf_tag('div', false, '', 'style="display:inline-block;"') . $editForm . wf_tag('div', true);
- }
- }
- return ($result);
- }
- /**
- * Returns comment editing form
- *
- * @param int $commentid existing database comment ID
- *
- * @return string
- */
- protected function commentEditForm($commentid) {
- $result = '';
- if (isset($this->allCommentsData[$commentid])) {
- $inputs = wf_HiddenInput(self::PROUTE_EDIT_ID, $commentid);
- $inputs .= wf_TextArea(self::PROUTE_EDIT_TEXT, '', $this->allCommentsData[$commentid]['text'], true, $this->textAreaSize);
- $inputs .= wf_Submit(__('Save'));
- $result = wf_Form('', 'POST', $inputs, 'glamour');
- }
- return ($result);
- }
- /**
- * Returns list of available comments for some item
- *
- * @param string $item
- * @return string
- */
- public function renderComments($item) {
- $result = '';
- $rows = '';
- $this->setItem($item);
- $this->loadComments();
- $this->commentSaver();
- $employeeLogins = ts_GetAllEmployeeLoginsAssocCached();
- if (!empty($this->allCommentsData)) {
- foreach ($this->allCommentsData as $io => $each) {
- $authorRealname = (isset($employeeLogins[$each['admin']])) ? $employeeLogins[$each['admin']] : $each['admin'];
- $authorName = wf_tag('center') . wf_tag('b') . $authorRealname . wf_tag('b', true) . wf_tag('center', true);
- $authorAvatar = wf_tag('center') . @gravatar_ShowAdminAvatar($each['admin'], '64') . wf_tag('center', true);
- $commentController = wf_tag('center') . $this->commentControls($each['id']) . wf_tag('center', true);
- $authorPanel = $authorName . wf_tag('br') . $authorAvatar . wf_tag('br') . $commentController;
- $commentText = nl2br($each['text']);
- if (ubRouting::checkPost(self::PROUTE_EDIT_FORM)) {
- //is editing form required for this comment?
- if (ubRouting::post(self::PROUTE_EDIT_FORM) == $each['id']) {
- //overriding text with editing form
- $commentText = $this->commentEditForm($each['id']);
- }
- }
- $cells = wf_TableCell('', '20%');
- $cells .= wf_TableCell($each['date']);
- $rows .= wf_TableRow($cells, 'row2');
- $cells = wf_TableCell($authorPanel);
- $cells .= wf_TableCell($commentText);
- $rows .= wf_TableRow($cells, 'row3');
- }
- $result .= wf_TableBody($rows, '100%', '0', '');
- }
- $result .= $this->commentAddForm();
- return ($result);
- }
- /**
- * Loads current scope items from database or cache
- *
- * @return array
- */
- protected function getScopeItemsCached() {
- $cachedData = array();
- //getting from cache
- $cachedData = $this->cache->get(self::CACHE_KEY . $this->scope, $this->cacheTime);
- if (empty($cachedData)) {
- //cache must be updated
- $this->commentsDb->selectable(array('id', 'scope', 'item', 'text'));
- $this->commentsDb->where('scope', '=', $this->scope);
- $cachedData = $this->commentsDb->getAll();
- if (empty($cachedData)) {
- $cachedData = array();
- }
- $this->cache->set(self::CACHE_KEY . $this->scope, $cachedData, $this->cacheTime);
- }
- return ($cachedData);
- }
- /**
- * Loads scope items list with counters if its really required
- *
- * @rerturn void
- */
- protected function loadScopeItems() {
- if ($this->scope) {
- $cachedData = $this->getScopeItemsCached();
- if (!empty($cachedData)) {
- foreach ($cachedData as $io => $each) {
- if (isset($this->scopeItems[$each['item']])) {
- $this->scopeItems[$each['item']]++;
- } else {
- $this->scopeItems[$each['item']] = 1;
- }
- }
- }
- $this->scopeItemsLoaded = true;
- } else {
- throw new Exception(self::EX_EMPTY_SCOPE);
- }
- }
- /**
- * Checks have item some comments or not?
- *
- * @param string $item
- *
- * @return bool
- */
- public function haveComments($item) {
- if (!$this->scopeItemsLoaded) {
- $this->loadScopeItems();
- }
- if (isset($this->scopeItems[$item])) {
- $result = true;
- } else {
- $result = false;
- }
- return ($result);
- }
- /**
- * Checks have item some additional comments and return native indicator
- *
- * @param string $item
- *
- * @return int
- */
- public function getCommentsCount($item) {
- if ($this->haveComments($item)) {
- $result = $this->scopeItems[$item];
- } else {
- $result = 0;
- }
- return ($result);
- }
- /**
- * Checks have item some additional comments and return native indicator
- *
- * @param string $item
- * @param int $size
- *
- * @return string
- */
- public function getCommentsIndicator($item, $size = '') {
- if ($this->haveComments($item)) {
- $size = (!$size) ? 16 : $size;
- $counter = $this->getCommentsCount($item);
- $result = wf_img_sized('skins/adcomments.png', __('Additional comments') . ' (' . $counter . ')', $size, $size);
- } else {
- // . .
- // |\_|\
- // | a_a\ I'm Batman.
- // | | "]
- // ____| '-\___
- // /.----.___.-'\
- // // _ \
- // // .-. (~v~) /|
- // |'| /\: .-- / \
- // // |-/ \_/____/\/~|
- // |/ \ | []_|_|_] \ |
- // | \ | \ |___ _\ ]_}
- // | | '-' / '.' |
- // | | / /|: |
- // | | | / |: /\
- // | | / / | / \
- // | | | / / | \
- // \ | |/\/ |/|/\ \
- // \|\ |\| | | / /\/\__\
- // \ \| | / | |__
- // / | |____)
- // |_/
- $result = '';
- }
- return ($result);
- }
- /**
- * Returns all items comments data for a given scope, like:
- * $item => array( [0] => array($comment1),
- * [1] => array($comment2),
- * .......................
- * [N] => array($commentN)
- * )
- *
- * where $comment will be represented as an associative array
- * with following keys: id,scope,item,text
- *
- * @return array
- *
- * @throws Exception
- */
- public function getScopeItemsCommentsAll() {
- if ($this->scope) {
- $itemsComments = array();
- $cachedData = $this->getScopeItemsCached();
- if (!empty($cachedData)) {
- foreach ($cachedData as $io => $each) {
- $itemsComments[$each['item']][] = $each;
- }
- }
- return ($itemsComments);
- } else {
- throw new Exception(self::EX_EMPTY_SCOPE);
- }
- }
- }
|