/** * @param Comments $stream * @param int $output 0: Normal, 1: Raw, 2: Inline, 3: Load, 4: Save * @param UserTable $user * @param UserTable $viewer * @param cbPluginHandler $plugin * @return null|string */ static public function showNew( $stream, $output, $user, $viewer, $plugin ) { global $_PLUGINS; if ( ! CBActivity::canCreate( $user, $viewer, $stream ) ) { return null; } $cbModerator = CBActivity::isModerator( (int) $viewer->get( 'id' ) ); $messageLimit = ( $cbModerator ? 0 : (int) $stream->get( 'message_limit', 400 ) ); $rowId = $stream->id() . '_new'; $newBody = null; $newFooter = null; $_PLUGINS->trigger( 'activity_onDisplayCommentCreate', array( &$newBody, &$newFooter, $stream, $output ) ); $return = '<div id="' . $rowId . '" class="streamItem streamItemInline commentContainer commentContainerNew' . ( $stream->get( 'type' ) == 'comment' ? ' hidden' : null ) . '">' . '<div class="streamItemInner streamMedia media clearfix">' . '<form action="' . $stream->endpoint( 'new' ) . '" method="post" enctype="multipart/form-data" name="' . $rowId . 'Form" id="' . $rowId . 'Form" class="cb_form streamItemForm form">' . '<div class="streamMediaLeft commentContainerLogo media-left">' . CBuser::getInstance( (int) $viewer->get( 'user_id' ), false )->getField( 'avatar', null, 'html', 'none', 'list', 0, true ) . '</div>' . '<div class="streamMediaBody streamItemNew commentContainerContent media-body text-small">' . '<textarea id="' . $stream->id() . '_message_new" name="message" rows="1" class="streamInput streamInputAutosize streamInputMessage form-control" placeholder="' . htmlspecialchars( ( $stream->get( 'type' ) == 'comment' ? CBTxt::T( 'Write a reply...' ) : CBTxt::T( 'Write a comment...' ) ) ) . '"' . ( $messageLimit ? ' data-cbactivity-input-limit="' . (int) $messageLimit . '" maxlength="' . (int) $messageLimit . '"' : null ) . '></textarea>' . $newBody . '<div class="streamItemDisplay commentContainerFooter hidden">' . '<div class="commentContainerFooterRow clearfix">' . '<div class="commentContainerFooterRowLeft pull-left">' . $newFooter . '</div>' . '<div class="commentContainerFooterRowRight pull-right text-right">' . '<button type="submit" class="commentButton commentButtonNewSave streamItemNewSave btn btn-primary btn-xs disabled" disabled="disabled">' . CBTxt::T( 'Post' ) . '</button>' . ' <button type="button" class="commentButton commentButtonNewCancel streamItemNewCancel btn btn-default btn-xs">' . CBTxt::T( 'Cancel' ) . '</button>' . '</div>' . '</div>' . '</div>' . '</div>' . '</form>' . '</div>' . '</div>'; return $return; }
/** * @param Activity $stream * @param int $output 0: Normal, 1: Raw, 2: Inline, 3: Load, 4: Save * @param UserTable $user * @param UserTable $viewer * @param cbPluginHandler $plugin * @return null|string */ static public function showNew( $stream, $output, $user, $viewer, $plugin ) { global $_PLUGINS; if ( ! CBActivity::canCreate( $user, $viewer, $stream ) ) { return null; } $cbModerator = CBActivity::isModerator( (int) $viewer->get( 'id' ) ); $messageLimit = ( $cbModerator ? 0 : (int) $stream->get( 'message_limit', 400 ) ); $showActions = (int) $stream->get( 'actions', 1 ); $actionLimit = ( $cbModerator ? 0 : (int) $stream->get( 'actions_message_limit', 100 ) ); $showLocations = (int) $stream->get( 'locations', 1 ); $locationLimit = ( $cbModerator ? 0 : (int) $stream->get( 'locations_address_limit', 200 ) ); $showLinks = (int) $stream->get( 'links', 1 ); $linkLimit = ( $cbModerator ? 0 : (int) $stream->get( 'links_link_limit', 5 ) ); $showTags = (int) $stream->get( 'tags', 1 ); $actionTooltip = cbTooltip( null, CBTxt::T( 'What are you doing or feeling?' ), null, 'auto', null, null, null, 'data-hascbtooltip="true" data-cbtooltip-position-my="bottom center" data-cbtooltip-position-at="top center" data-cbtooltip-classes="qtip-simple"' ); $locationTooltip = cbTooltip( null, CBTxt::T( 'Share your location.' ), null, 'auto', null, null, null, 'data-hascbtooltip="true" data-cbtooltip-position-my="bottom center" data-cbtooltip-position-at="top center" data-cbtooltip-classes="qtip-simple"' ); $tagTooltip = cbTooltip( null, CBTxt::T( 'Are you with anyone?' ), null, 'auto', null, null, null, 'data-hascbtooltip="true" data-cbtooltip-position-my="bottom center" data-cbtooltip-position-at="top center" data-cbtooltip-classes="qtip-simple"' ); $linkTooltip = cbTooltip( null, CBTxt::T( 'Have a link to share?' ), null, 'auto', null, null, null, 'data-hascbtooltip="true" data-cbtooltip-position-my="bottom center" data-cbtooltip-position-at="top center" data-cbtooltip-classes="qtip-simple"' ); $actionOptions = ( $showActions ? CBActivity::loadActionOptions() : array() ); $locationOptions = ( $showLocations ? CBActivity::loadLocationOptions() : array() ); $rowId = $stream->id() . '_new'; $newBody = null; $newFooter = null; $_PLUGINS->trigger( 'activity_onDisplayActivityCreate', array( &$newBody, &$newFooter, $stream, $output ) ); $return = '<div id="' . $rowId . '" class="streamItem streamPanel activityContainer activityContainerNew panel panel-default">' . '<div class="streamItemInner">' . '<form action="' . $stream->endpoint( 'new' ) . '" method="post" enctype="multipart/form-data" name="' . $rowId . 'Form" id="' . $rowId . 'Form" class="cb_form streamItemForm form">' . '<div class="streamItemNew">' . '<textarea id="' . $stream->id() . '_message_new" name="message" rows="1" class="streamInput streamInputAutosize streamInputMessage form-control no-border" placeholder="' . htmlspecialchars( CBTxt::T( "What's on your mind?" ) ) . '" data-cbactivity-input-size="3"' . ( $messageLimit ? ' data-cbactivity-input-limit="' . (int) $messageLimit . '" maxlength="' . (int) $messageLimit . '"' : null ) . '></textarea>'; if ( $showLinks ) { if ( ( ! $linkLimit ) || ( $linkLimit > 1 ) ) { $return .= '<div class="streamItemInputGroup streamInputLinkContainer cbRepeat border-default clearfix hidden" data-cbrepeat-sortable="false"' . ( $linkLimit ? ' data-cbrepeat-max="' . (int) $linkLimit . '"' : null ) . '>' . '<div class="streamItemInputGroupRow cbRepeatRow border-default">' . '<span class="streamItemInputGroupLabel form-control">' . '<button type="button" class="cbRepeatRowAdd btn btn-xs btn-success"><span class="fa fa-plus "></span></button>' . '<button type="button" class="cbRepeatRowRemove btn btn-xs btn-danger"><span class="fa fa-minus"></span></button>' . '</span>' . '<div class="streamItemInputGroupInput border-default">' . '<input type="text" id="' . $stream->id() . '_links__0__url_new" name="links[0][url]" class="streamInput streamInputLinkURL form-control no-border" placeholder="' . htmlspecialchars( CBTxt::T( "What link would you like to share?" ) ) . '" disabled="disabled" />' . '</div>' . '</div>' . '</div>'; } else { $return .= '<div class="streamItemInputGroup streamInputLinkContainer border-default clearfix hidden">' . '<input type="text" id="' . $stream->id() . '_links__0__url_new" name="links[0][url]" class="streamInput streamInputLinkURL form-control no-border" placeholder="' . htmlspecialchars( CBTxt::T( "What link would you like to share?" ) ) . '" disabled="disabled" />' . '</div>'; } } if ( $actionOptions ) { $emoteOptions = CBActivity::loadEmoteOptions(); $return .= '<div class="streamItemInputGroup streamInputActionContainer border-default clearfix hidden">' . '<span class="streamItemInputGroupLabel streamInputSelectToggleLabel form-control"></span>' . '<div class="streamItemInputGroupInput border-default">' . '<input type="text" id="' . $stream->id() . '_actions_message_new" name="actions[message]" class="streamInput streamInputActionMessage streamInputSelectTogglePlaceholder form-control no-border"' . ( $actionLimit ? ' maxlength="' . (int) $actionLimit . '"' : null ) . ' disabled="disabled" />' . ( $emoteOptions ? str_replace( 'actions__emote', $stream->id() . '_actions_emote_new', moscomprofilerHTML::selectList( $emoteOptions, 'actions[emote]', 'class="streamInputSelect streamInputEmote" data-cbselect-width="auto" data-cbselect-height="100%" data-cbselect-dropdown-css-class="streamEmoteOptions" disabled="disabled"', 'value', 'text', null, 0, false, false, false ) ) : null ) . '</div>' . '</div>'; } if ( $locationOptions ) { $return .= '<div class="streamItemInputGroup streamInputLocationContainer border-default clearfix hidden">' . '<span class="streamItemInputGroupLabel streamInputSelectToggleLabel form-control"></span>' . '<div class="streamItemInputGroupInput border-default">' . '<input type="text" id="' . $stream->id() . '_location_place_new" name="location[place]" class="streamInput streamInputLocationPlace form-control no-border" placeholder="' . CBTxt::T( 'Where are you?' ) . '"' . ( $locationLimit ? ' maxlength="' . (int) $locationLimit . '"' : null ) . ' disabled="disabled" />' . '<input type="text" id="' . $stream->id() . '_location_address_new" name="location[address]" class="streamInput streamInputLocationAddress form-control no-border" placeholder="' . CBTxt::T( 'Have the address to share?' ) . '"' . ( $locationLimit ? ' maxlength="' . (int) $locationLimit . '"' : null ) . ' disabled="disabled" />' . '<div class="streamFindLocation fa fa-map-marker fa-lg" data-cbactivity-location-target=".streamInputLocationAddress"></div>' . '</div>' . '</div>'; } if ( $showTags ) { $tagOptions = CBActivity::loadTagOptions( null, (int) $viewer->get( 'id' ) ); $return .= '<div class="streamItemInputGroup streamInputTagContainer border-default clearfix hidden">' . str_replace( 'tags__', $stream->id() . '_tags_new', moscomprofilerHTML::selectList( $tagOptions, 'tags[]', 'multiple="multiple" class="streamInputSelect streamInputTags form-control no-border" data-cbselect-placeholder="' . htmlspecialchars( CBTxt::T( 'Who are you with?' ) ) . '" data-cbselect-tags="true" data-cbselect-width="100%" data-cbselect-height="100%" data-cbselect-dropdown-css-class="streamTagsOptions" disabled="disabled"', 'value', 'text', null, 0, true, false, false ) ) . '</div>'; } $return .= $newBody . '</div>' . '<div class="streamPanelFooter streamItemDisplay activityContainerFooter panel-footer hidden">' . '<div class="activityContainerFooterRow clearfix">' . '<div class="activityContainerFooterRowLeft pull-left">' . ( $actionOptions ? str_replace( 'actions__id', $stream->id() . '_actions_id_new', moscomprofilerHTML::selectList( $actionOptions, 'actions[id]', 'class="streamInputSelect streamInputSelectToggle streamInputAction btn btn-xs btn-default" data-cbactivity-toggle-target=".streamInputActionContainer" data-cbactivity-toggle-active-classes="btn-primary" data-cbactivity-toggle-inactive-classes="btn-default" data-cbactivity-toggle-icon="fa fa-smile-o" data-cbselect-dropdown-css-class="streamSelectOptions"' . $actionTooltip, 'value', 'text', null, 0, false, false, false ) ) : null ) . ( $locationOptions ? ( $actionOptions ? ' ' : null ) . str_replace( 'location__id', $stream->id() . '_location_id_new', moscomprofilerHTML::selectList( $locationOptions, 'location[id]', 'class="streamInputSelect streamInputSelectToggle streamInputLocation btn btn-xs btn-default" data-cbactivity-toggle-target=".streamInputLocationContainer" data-cbactivity-toggle-active-classes="btn-primary" data-cbactivity-toggle-inactive-classes="btn-default" data-cbactivity-toggle-icon="fa fa-map-marker" data-cbselect-dropdown-css-class="streamSelectOptions"' . $locationTooltip, 'value', 'text', null, 0, false, false, false ) ) : null ) . ( $showTags ? ( $actionOptions || $locationOptions ? ' ' : null ) . '<button type="button" id="' . $stream->id() . '_tags_new" class="streamToggle streamInputTag btn btn-default btn-xs" data-cbactivity-toggle-target=".streamInputTagContainer" data-cbactivity-toggle-active-classes="btn-primary" data-cbactivity-toggle-inactive-classes="btn-default"' . $tagTooltip . '><span class="fa fa-user"></span></button>' : null ) . ( $showLinks ? ( $actionOptions || $locationOptions || $showTags ? ' ' : null ) . '<button type="button" id="' . $stream->id() . '_links_new" class="streamToggle streamInputLink btn btn-default btn-xs" data-cbactivity-toggle-target=".streamInputLinkContainer" data-cbactivity-toggle-active-classes="btn-primary" data-cbactivity-toggle-inactive-classes="btn-default"' . $linkTooltip . '><span class="fa fa-link"></span></button>' : null ) . $newFooter . '</div>' . '<div class="activityContainerFooterRowRight pull-right text-right">' . '<button type="submit" class="activityButton activityButtonNewSave streamItemNewSave btn btn-primary btn-xs disabled" disabled="disabled">' . CBTxt::T( 'Post' ) . '</button>' . ' <button type="button" class="activityButton activityButtonNewCancel streamItemNewCancel btn btn-default btn-xs">' . CBTxt::T( 'Cancel' ) . '</button>' . '</div>' . '</div>' . '</div>' . '</form>' . '</div>' . '</div>'; return $return; }
/** * Saves activity * * @param int $id * @param Activity $stream * @param UserTable $user * @param UserTable $viewer */ private function saveActivity( $id, $stream, $user, $viewer ) { global $_CB_framework, $_PLUGINS; $cbModerator = CBActivity::isModerator( (int) $viewer->get( 'id' ) ); CBActivity::getTemplate( 'activity', false, false ); $row = new ActivityTable(); $row->load( (int) $id ); $canAccess = false; if ( ! $row->get( 'id' ) ) { if ( CBActivity::canCreate( $user, $viewer, $stream ) ) { $canAccess = true; } } elseif ( ( ( $row->get( 'type' ) == 'status' ) || ( $row->get( 'subtype' ) == 'status' ) ) && ( $cbModerator || ( $viewer->get( 'id' ) == $row->get( 'user_id' ) ) ) ) { $canAccess = true; } if ( ! $canAccess ) { header( 'HTTP/1.0 404 Not Found' ); exit(); } $messageLimit = ( $cbModerator ? 0 : (int) $stream->get( 'message_limit', 400 ) ); $showActions = (int) $stream->get( 'actions', 1 ); $actionLimit = ( $cbModerator ? 0 : (int) $stream->get( 'actions_message_limit', 100 ) ); $showLocations = (int) $stream->get( 'locations', 1 ); $locationLimit = ( $cbModerator ? 0 : (int) $stream->get( 'locations_address_limit', 200 ) ); $showLinks = (int) $stream->get( 'links', 1 ); $linkLimit = ( $cbModerator ? 0 : (int) $stream->get( 'links_link_limit', 5 ) ); $showTags = (int) $stream->get( 'tags', 1 ); $message = trim( $this->input( 'message', $row->get( 'message', null, GetterInterface::HTML ), GetterInterface::HTML ) ); // Remove duplicate spaces: $message = preg_replace( '/ {2,}/i', ' ', $message ); // Remove duplicate tabs: $message = preg_replace( '/\t{2,}/i', "\t", $message ); // Remove duplicate linebreaks: $message = preg_replace( '/(\r\n|\r|\n){2,}/i', '$1', $message ); $row->set( 'user_id', $row->get( 'user_id', $viewer->get( 'id' ) ) ); if ( $stream->get( 'type' ) && ( $stream->get( 'type' ) != 'status' ) ) { $row->set( 'type', $row->get( 'type', $stream->get( 'type' ) ) ); $row->set( 'subtype', $row->get( 'subtype', 'status' ) ); $parentDefault = null; } else { $row->set( 'type', $row->get( 'type', 'status' ) ); $parentDefault = ( $viewer->get( 'id' ) != $user->get( 'user_id' ) ? $user->get( 'user_id' ) : null ); } $row->set( 'item', $row->get( 'item', $stream->get( 'item' ) ) ); $row->set( 'parent', $row->get( 'parent', $stream->get( 'parent', $parentDefault ) ) ); if ( $messageLimit && ( cbutf8_strlen( $message ) > $messageLimit ) ) { $message = cbutf8_substr( $message, 0, $messageLimit ); } $row->set( 'message', $message ); if ( $showActions ) { $action = $this->getInput()->subTree( 'actions' ); $actionId = (int) $action->get( 'id', 0, GetterInterface::INT ); $actionMessage = ( $actionId ? trim( $action->get( 'message', '', GetterInterface::STRING ) ) : '' ); // Remove linebreaks: $actionMessage = str_replace( array( "\n", "\r\n" ), ' ', $actionMessage ); // Remove duplicate spaces: $actionMessage = preg_replace( '/ {2,}/i', ' ', $actionMessage ); // Remove duplicate tabs: $actionMessage = preg_replace( '/\t{2,}/i', "\t", $actionMessage ); if ( $actionLimit && ( cbutf8_strlen( $actionMessage ) > $actionLimit ) ) { $actionMessage = cbutf8_substr( $actionMessage, 0, $actionLimit ); } $actionId = ( $actionMessage ? $actionId : 0 ); $newAction = array( 'id' => $actionId, 'message' => ( $actionId ? $actionMessage : '' ), 'emote' => ( $actionId ? (int) $action->get( 'emote', 0, GetterInterface::INT ) : 0 ) ); $row->params()->set( 'action', $newAction ); } if ( $showLocations ) { $location = $this->getInput()->subTree( 'location' ); $locationId = (int) $location->get( 'id', 0, GetterInterface::INT ); $locationPlace = ( $locationId ? trim( $location->get( 'place', '', GetterInterface::STRING ) ) : '' ); $locationAddress = ( $locationId ? trim( $location->get( 'address', '', GetterInterface::STRING ) ) : '' ); if ( $locationLimit && ( cbutf8_strlen( $locationPlace ) > $locationLimit ) ) { $locationPlace = cbutf8_substr( $locationPlace, 0, $locationLimit ); } if ( $locationLimit && ( cbutf8_strlen( $locationAddress ) > $locationLimit ) ) { $locationAddress = cbutf8_substr( $locationAddress, 0, $locationLimit ); } $locationId = ( $locationPlace ? $locationId : 0 ); $newLocation = array( 'id' => $locationId, 'place' => ( $locationId ? $locationPlace : '' ), 'address' => ( $locationId ? $locationAddress : '' ) ); $row->params()->set( 'location', $newLocation ); } if ( $showLinks ) { $links = $this->getInput()->subTree( 'links' ); $newLinks = array(); /** @var ParamsInterface[] $links */ foreach ( $links as $i => $link ) { if ( $linkLimit && ( ( $i + 1 ) > $linkLimit ) ) { break; } $linkUrl = trim( $link->get( 'url', '', GetterInterface::STRING ) ); if ( $linkUrl ) { $attachment = $stream->parser()->attachment( $linkUrl ); if ( ! $attachment ) { continue; } $linkType = $attachment->get( 'type', '', GetterInterface::STRING ); switch ( $linkType ) { case 'video': $linkMedia = $attachment->subTree( 'media' )->subTree( 'video' )->subTree( 0 ); break; case 'audio': $linkMedia = $attachment->subTree( 'media' )->subTree( 'audio' )->subTree( 0 ); break; case 'image': case 'url': default: $linkMedia = $attachment->subTree( 'media' )->subTree( 'image' )->subTree( 0 ); break; } $newLinks[] = array( 'url' => $linkUrl, 'text' => null, 'title' => trim( $link->get( 'title', $attachment->subTree( 'title' )->get( 0, '', GetterInterface::STRING ), GetterInterface::STRING ) ), 'description' => trim( $link->get( 'description', $attachment->subTree( 'description' )->get( 0, '', GetterInterface::STRING ), GetterInterface::STRING ) ), 'media' => array( 'url' => $linkMedia->get( 'url', '', GetterInterface::STRING ), 'mimetype' => $linkMedia->get( 'mimetype', '', GetterInterface::STRING ), 'extension' => $linkMedia->get( 'extension', '', GetterInterface::STRING ), 'custom' => '' ), 'type' => $linkType, 'thumbnail' => $link->get( 'thumbnail', 1, GetterInterface::INT ), 'internal' => 0, ); } } $row->params()->set( 'links', $newLinks ); } if ( $row->get( 'id' ) ) { $row->params()->set( 'modified', $_CB_framework->getUTCDate() ); } $row->set( 'params', $row->params()->asJson() ); if ( $row->getError() || ( ! $row->check() ) ) { header( 'HTTP/1.0 500 Internal Server Error' ); exit(); } if ( $row->getError() || ( ! $row->store() ) ) { header( 'HTTP/1.0 500 Internal Server Error' ); exit(); } if ( $showTags ) { $tagsStream = $row->tags( $stream->source() ); if ( $tagsStream ) { $tags = $this->input( 'tags', array(), GetterInterface::RAW ); foreach ( $tagsStream->data() as $tag ) { /** @var TagTable $tag */ if ( ! in_array( $tag->get( 'user' ), $tags ) ) { $tag->delete(); $tagsStream->resetData(); } else { $key = array_search( $tag->get( 'user' ), $tags ); if ( $key !== false ) { unset( $tags[$key] ); } } } foreach ( $tags as $tagUser ) { if ( is_numeric( $tagUser ) ) { $tagUser = (int) $tagUser; } else { $tagUser = Get::clean( $tagUser, GetterInterface::STRING ); } $tag = new TagTable(); $tag->set( 'user_id', (int) $tagsStream->user()->get( 'id' ) ); $tag->set( 'type', $tagsStream->get( 'type', null, GetterInterface::STRING ) ); $tag->set( 'subtype', $tagsStream->get( 'subtype', null, GetterInterface::STRING ) ); $tag->set( 'item', $tagsStream->get( 'item', null, GetterInterface::STRING ) ); $tag->set( 'parent', $tagsStream->get( 'parent', null, GetterInterface::STRING ) ); $tag->set( 'user', $tagUser ); $tag->store(); $tagsStream->resetData(); } } } $rows = array( &$row ); if ( $stream->get( 'comments', 1 ) ) { CBActivity::preFetchComments( $rows, 'activity' ); } if ( $stream->get( 'tags', 1 ) ) { CBActivity::preFetchTags( $rows, 'activity' ); } CBActivity::preFetchUsers( $rows ); $_PLUGINS->trigger( 'activity_onPushActivity', array( $stream, $row ) ); echo HTML_cbactivityActivity::showActivity( $rows, $stream, 4, $user, $viewer, $this ); header( 'HTTP/1.0 200 OK' ); exit(); }