/** * Get standardized post data given an SQL query (which can specify WHERE conditions, for example.) * * @param ETSQLQuery $sql The SQL query to use as a basis. * @return array An array of posts and their details. */ public function getWithSQL($sql) { // likeActivityId: いいね済みの場合、ActivityId が存在する // likeCnt: いいねボタンのカウント数(※ポイント数ではないので注意) $sql->select("p.*")->select("m.memberId", "memberId")->select("m.username", "username")->select("m.account", "account")->select("m.email", "email")->select("m.avatarFormat", "avatarFormat")->select("m.preferences", "preferences")->select("em.memberId", "editMemberId")->select("em.username", "editMemberName")->select("dm.memberId", "deleteMemberId")->select("dm.username", "deleteMemberName")->select("m.lastActionTime", "lastActionTime")->select("m.lastActionDetail", "lastActionDetail")->select("GROUP_CONCAT(g.groupId)", "groups")->select("GROUP_CONCAT(g.name)", "groupNames")->select("count(b.activityId)", "likeCnt")->from("post p")->from("member m", "m.memberId=p.memberId", "left")->from("member em", "em.memberId=p.editMemberId", "left")->from("member dm", "dm.memberId=p.deleteMemberId", "left")->from("member_group mg", "m.memberId=mg.memberId", "left")->from("group g", "g.groupId=mg.groupId", "left")->from("activity b", "b.memberId=p.memberId AND b.type='like' AND b.fromMemberId is not null AND b.postId=p.postId AND b.conversationId=p.conversationId", "left")->groupBy("p.postId")->orderBy("p.time ASC"); $fromMemberId = ET::$session->userId; if ($fromMemberId) { // ログイン済みの場合 いいね済みを取得 $sql->select("a.activityId", "likeActivityId")->from("activity a", "a.memberId=p.memberId AND a.type='like' AND a.fromMemberId=:fromMemberId AND a.postId=p.postId AND a.conversationId=p.conversationId", "left")->bind(":fromMemberId", $fromMemberId); } $this->trigger("getPostsBefore", array($sql)); $result = $sql->exec(); // Loop through the results and compile them into an array of posts. $posts = array(); while ($post = $result->nextRow()) { // 2016/02 SWCユーザ名を設定するように変更対応 $post["username"] = SwcUtils::getUserName($post["memberId"]); $post["editMemberName"] = SwcUtils::getUserName($post["editMemberId"]); $post["deleteMemberName"] = SwcUtils::getUserName($post["deleteMemberId"]); ET::memberModel()->expand($post); $posts[] = $post; } $this->trigger("getPostsAfter", array(&$posts)); return $posts; }
echo "<strong class='title'><a href='" . URL($conversationURL . ((ET::$session->user and $conversation["unread"]) ? "/unread" : "")) . "'>"; if (SWC_MAIN_THUMB_DISPLAY && $menuImgUrl) { // メニュー画像サムネイル出力 echo "<img src='" . $menuImgUrl . "' width='28' height='20' alt='' title=''>"; } echo highlight(sanitizeHTML($conversation["title"]), ET::$session->get("highlight")) . "</a></strong> "; // If we're highlighting search terms (i.e. if we did a fulltext search), then output a "show matching posts" link. if (ET::$session->get("highlight")) { echo "<span class='controls'><a href='" . URL($conversationURL . "/?search=" . urlencode($data["fulltextString"])) . "' class='showMatchingPosts'>" . T("Show matching posts") . "</a></span>"; } // If this conversation is stickied, output an excerpt from its first post. if ($conversation["sticky"]) { echo "<div class='excerpt'>" . ET::formatter()->init($conversation["firstPost"])->inline(true)->firstLine()->clip(200)->format()->get() . "</div>"; } ?> </div> <div class='col-channel'><?php $channel = $data["channelInfo"][$conversation["channelId"]]; echo "<a href='" . URL(searchURL("", $channel["slug"])) . "' class='channel channel-{$conversation["channelId"]}' data-channel='{$channel["slug"]}'>{$channel["title"]}</a>"; ?> </div> <div class='col-lastPost'><?php echo "<span class='action'>" . avatar(array("memberId" => $conversation["lastPostMemberId"], "username" => $conversation["lastPostMember"], "avatarFormat" => $conversation["lastPostMemberAvatarFormat"], "email" => $conversation["lastPostMemberEmail"]), "thumb"), " ", sprintf(T("%s posted %s"), "<span class='lastPostMember name'>" . memberLink($conversation["lastPostMemberId"], $conversation["lastPostMember"]) . "</span>", "<a href='" . URL($conversationURL . "/unread") . "' class='lastPostTime'>" . SwcUtils::getStrfTime($conversation["lastPostTime"]) . "</a>"), "</span>"; ?> </div> <div class='col-replies'><?php echo "<span><a href='" . URL($conversationURL . "/unread") . "'>" . $conversation["replies"] . "</a></span>"; ?> </div> </li>
public function action_upload() { // require_once 'qqFileUploader.php'; // $uploader = new qqFileUploader(); // $uploader->inputName = 'qqfile'; // 管理画面で設定されたファイル拡張子(画像のみ) // Set the allowed file types based on config. $allowedFileTypes = C("plugin.Attachments.allowedFileTypes"); // 管理画面で設定されたMAXサイズ(デフォルト: 25MB) // Set the max file size based on config. $maxSize = C("plugin.Attachments.maxFileSize"); $model = $this->getAttachmentModel(); $id = ""; try { // アップロード処理 $attachmentId = ""; $uploader = ET::uploader(); $filepath = $uploader->getUploadedFile(self::$file_key, $allowedFileTypes); if (file_exists($filepath)) { // ファイルサイズチェック $size = filesize($filepath); if ($size > $maxSize) { // TODO: サイズ超過 エラー時 } // 元ファイル名 $name = $_FILES[self::$file_key]["name"]; $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if ($ext != "gif") { // gif 以外はjpg で保存 $ext = "jpg"; } // ファイル名 $baseName = pathinfo($name, PATHINFO_BASENAME); // $baseName = pathinfo($filepath, PATHINFO_FILENAME) .$ext; $attachmentId = SwcUtils::createUniqKey(13); // ランダム文字列 $secret = generateRandomString(13, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); // 保存先ファイルパス $destPath = $model->path() . $attachmentId . $secret . "." . $ext; // MAX値超過する場合 リサイズする $outputFile = $uploader->saveAsImage($filepath, $destPath, SWC_IMG_MAX_W, SWC_IMG_MAX_H); // 画像データ $imgFile = file_get_contents($outputFile); // エンティティ設定 $entity = array("attachmentId" => $attachmentId, "filename" => $baseName, "secret" => $secret, "content" => $imgFile); $paramPostId = R("postId"); if (preg_match('/^p[0-9]+$/', $paramPostId)) { // postID がある場合 "p"から始まる // "p"を除去して登録 $entity["postId"] = substr($paramPostId, 1); } else { if (preg_match('/^c[0-9]+$/', $paramPostId)) { // 会話ID を設定 "c"から始まる // 新規の場合、"c0"が設定されている // アップロード時は"c" を付けたまま一時登録する $entity["conversationId"] = $paramPostId; } } // sessId取得 $sessId = ET::$session->getSessId(); $entity["sessId"] = $sessId; $model->create($entity, false); } } catch (Exception $e) { // TODO: return; } $result = array(); if ($attachmentId) { // OK の場合 $result["success"] = 1; $result["uploadName"] = $baseName; $result["attachmentId"] = $attachmentId; } else { // NG $result["success"] = 0; } header("Content-Type: text/plain"); echo json_encode($result); }
} /** * Shows a collection of posts as list items. * * @package esoTalk */ $prevPost = null; foreach ($data["posts"] as $k => $post) { // Format the post for the template. $formattedPost = $this->formatPostForTemplate($post, $data["conversation"]); // If the post before this one is by the same member as this one, hide the avatar. if ($prevPost and empty($prevPost["deleteMemberId"]) and $prevPost["memberId"] == $post["memberId"]) { $formattedPost["hideAvatar"] = true; } //$thisPostTime = relativeTime($post["time"]); $thisPostTime = SwcUtils::getStrfTime($post["time"]); // 年月日日時として表示 $mainFlg = $post["mainPostFlg"]; ?> <li data-index='<?php echo date("Y", $post["time"]) . date("m", $post["time"]); ?> '> <?php if ($mainFlg) { $this->renderView("conversation/tagsPath", array("tags" => $this->data["tags"])); } // If the post before this one has a different relative time string to this one, output a 'time marker'. if (!isset($prevPost["time"]) or relativeTime($prevPost["time"]) != $thisPostTime) { ?> <div class='timeMarker'<?php
/** * Show the sign up sheet and handle input from its form. * * @return void */ public function action_join() { // If we're already logged in, get out of here. if (ET::$session->user) { $this->redirect(URL("")); } // SWC新規登録へ $this->redirect(SwcUtils::getSwcUrl("entry")); // // If registration is closed, show a message. // if (!C("esoTalk.registration.open")) { // $this->renderMessage(T("Registration Closed"), T("message.registrationClosed")); // return; // } // // // Set the title and make sure this page isn't indexed. // $this->title = T("Sign Up"); // $this->addToHead("<meta name='robots' content='noindex, noarchive'/>"); // // // Construct a form. // $form = ETFactory::make("form"); // $form->action = URL("user/join"); // // // Add the username field to the form structure. // $form->addSection("username", T("Username")); // $form->addField("username", "username", function($form) // { // return $form->input("username"); // }, // function($form, $key, &$data) // { // $data["username"] = $form->getValue($key); // }); // // // Add the email field to the form structure. // $form->addSection("email", T("Email")); // $form->addField("email", "email", function($form) // { // return $form->input("email")."<br><small>".T("Used to verify your account and subscribe to conversations")."</small>"; // }, // function($form, $key, &$data) // { // $data["email"] = $form->getValue($key); // }); // // // Add the password field to the form structure. // $form->addSection("password", T("Password")); // $form->addField("password", "password", function($form) // { // return $form->input("password", "password")."<br><small>".sprintf(T("Choose a secure password of at least %s characters"), C("esoTalk.minPasswordLength"))."</small>"; // }, // function($form, $key, &$data) // { // $data["password"] = $form->getValue($key); // }); // // // Add the confirm password field to the form structure. // $form->addSection("confirm", T("Confirm password")); // $form->addField("confirm", "confirm", function($form) // { // return $form->input("confirm", "password"); // }, // function($form, $key, &$data) // { // // Make sure the passwords match. // if ($form->getValue("password") != $form->getValue($key)) // $form->error($key, T("message.passwordsDontMatch")); // }); // // $this->trigger("initJoin", array($form)); // // // If the cancel button was pressed, return to where the user was before. // if ($form->isPostBack("cancel")) $this->redirect(URL(R("return"))); // // // If the form has been submitted, validate it and add the member into the database. // if ($form->validPostBack("submit")) { // // $data = array(); // if ($form->validPostBack()) $form->runFieldCallbacks($data); // // if (!$form->errorCount()) { // // $data["account"] = ACCOUNT_MEMBER; // // if (!C("esoTalk.registration.requireConfirmation")) $data["confirmed"] = true; // else $data["resetPassword"] = md5(uniqid(rand())); // // // Create the member. // $model = ET::memberModel(); // $memberId = $model->create($data); // // // If there were validation errors, pass them to the form. // if ($model->errorCount()) $form->errors($model->errors()); // // else { // // // If we require the user to confirm their email, send them an email and show a message. // if (C("esoTalk.registration.requireConfirmation") == "email") { // $this->sendConfirmationEmail($data["email"], $data["username"], $memberId.$data["resetPassword"]); // $this->renderMessage(T("Success!"), T("message.confirmEmail")); // } // // // If we require the user account to be approved by an administrator, show a message. // elseif (C("esoTalk.registration.requireConfirmation") == "approval") { // $admin = ET::memberModel()->getById(C("esoTalk.rootAdmin")); // ET::activityModel()->create("unapproved", $admin, null, array("username" => $data["username"])); // $this->renderMessage(T("Success!"), T("message.waitForApproval")); // } // // else { // ET::$session->login($form->getValue("username"), $form->getValue("password")); // $this->redirect(URL("")); // } // // return; // // } // // } // // } // // $this->data("form", $form); // $this->render("user/join"); }
/** * 投稿単位(post)の出力用編集メソッド * Format post data into an array which can be used to display the post template view (conversation/post). * * @param array $post The post data. * @param array $conversation The details of the conversation which the post is in. * @return array A formatted array which can be used in the post template view. */ protected function formatPostForTemplate($post, $conversation) { $canEdit = ET::postModel()->canEditPost($post, $conversation); $avatar = avatar($post); // Construct the post array for use in the post view (conversation/post). // title: SWCユーザ名を表示するように設定対応 // purl: 追加。SNSボタンリンク用に投稿単位の絶対urlを設定 // likeCnt: 追加。いいねボタンのカウント数設定 // mainPostFlg: 追加。テーマのメイン投稿(最初の投稿)フラグ $formatted = array("id" => "p" . $post["postId"], "conversationId" => $post["conversationId"], "title" => memberLink($post["memberId"], $post["username"]), "avatar" => (!$post["deleteMemberId"] and $avatar) ? "<a href='" . URL(memberURL($post["memberId"], $post["username"])) . "'>{$avatar}</a>" : false, "class" => $post["deleteMemberId"] ? array("deleted") : array(), "info" => array(), "controls" => array(), "body" => !$post["deleteMemberId"] ? $this->displayPost($post["content"]) : false, "footer" => array(), "purl" => URL(postURL($post["postId"]), TRUE), "likeCnt" => $post["likeCnt"], "mainPostFlg" => $post["mainPostFlg"], "data" => array("id" => $post["postId"], "memberid" => $post["memberId"])); // いいね済みフラグ $formatted["liked"] = $post["likeActivityId"] ? 1 : ""; // $date = smartTime($post["time"], true); $date = SwcUtils::getStrfTime($post["time"], T("date.short")); // Add the date/time to the post info as a permalink. $formatted["info"][] = "<a href='" . URL(postURL($post["postId"])) . "' class='time' title='" . strftime(T("date.full"), $post["time"]) . "'>" . (!empty($conversation["searching"]) ? T("Show in context") : $date) . "</a>"; // If the post isn't deleted, add a lot of stuff! if (!$post["deleteMemberId"]) { // Add the user's online status / last action next to their name. // if (empty($post["preferences"]["hideOnline"])) { // $lastAction = ET::memberModel()->getLastActionInfo($post["lastActionTime"], $post["lastActionDetail"]); // if ($lastAction[0]) $lastAction[0] = " (".sanitizeHTML($lastAction[0]).")"; // if ($lastAction) array_unshift($formatted["info"], "<".(!empty($lastAction[1]) ? "a href='{$lastAction[1]}'" : "span")." class='online' title='".T("Online")."{$lastAction[0]}'><i class='icon-circle'></i></".(!empty($lastAction[1]) ? "a" : "span").">"); // } // Show the user's group type. // $formatted["info"][] = "<span class='group'>".memberGroup($post["account"], $post["groups"])."</span>"; $formatted["class"][] = "group-" . $post["account"]; foreach ($post["groups"] as $k => $v) { if ($k) { $formatted["class"][] = "group-" . $k; } } // If the post has been edited, show the time and by whom next to the controls. if ($post["editMemberId"]) { $formatted["controls"][] = "<span class='editedBy'>" . sprintf(T("Edited %s by %s"), "<span title='" . strftime(T("date.full"), $post["editTime"]) . "'>" . relativeTime($post["editTime"], true) . "</span>", name($post["editMemberName"])) . "</span>"; } // If the user can reply, add a quote control. if ($conversation["canReply"]) { $formatted["controls"][] = "<a href='" . URL(conversationURL($conversation["conversationId"], $conversation["title"]) . "/?quote=" . $post["postId"] . "#reply") . "' title='" . T("Quote") . "' class='control-quote'><i class='icon-quote-left'></i></a>"; } // If the user can edit the post, add edit/delete controls. if ($canEdit) { $formatted["controls"][] = "<a href='" . URL("conversation/editPost/" . $post["postId"]) . "' title='" . T("Edit") . "' class='control-edit'><i class='icon-edit'></i></a>"; $formatted["controls"][] = "<a href='" . URL("conversation/deletePost/" . $post["postId"] . "?token=" . ET::$session->token) . "' title='" . T("Delete") . "' class='control-delete'><i class='icon-remove'></i></a>"; } } else { // Add the "deleted by" information. if ($post["deleteMemberId"]) { $formatted["controls"][] = "<span>" . sprintf(T("Deleted %s by %s"), "<span title='" . strftime(T("date.full"), $post["deleteTime"]) . "'>" . relativeTime($post["deleteTime"], true) . "</span>", name($post["deleteMemberName"])) . "</span>"; } // If the user can edit the post, add a restore control. if ($canEdit) { $formatted["controls"][] = "<a href='" . URL("conversation/restorePost/" . $post["postId"] . "?token=" . ET::$session->token) . "' title='" . T("Restore") . "' class='control-restore'><i class='icon-reply'></i></a>"; } } $this->trigger("formatPostForTemplate", array(&$formatted, $post, $conversation)); return $formatted; }
/** * Get a single conversation's details. * * This function returns an array of fields which is that "standard" for conversation data structure * within this model. * * @param array $wheres An array of WHERE conditions. Regardless of how many conversations match, only * the first will be returned. * @return array The conversation details array. */ public function get($wheres = array()) { $sql = ET::SQL()->select("s.*")->select("c.*")->select("sm.username", "startMember")->select("sm.avatarFormat", "startMemberAvatarFormat")->select("ch.title", "channelTitle")->select("ch.description", "channelDescription")->select("ch.slug", "channelSlug")->select("ch.lft", "channelLft")->select("ch.rgt", "channelRgt")->select("GROUP_CONCAT(pv.groupId)", "channelPermissionView")->select("GROUP_CONCAT(IF(pvg.name IS NOT NULL, pvg.name, ''))", "channelPermissionViewNames")->from("conversation c")->from("channel ch", "c.channelId=ch.channelId", "left")->from("channel_group pv", "c.channelId=pv.channelId AND pv.view=1", "left")->from("group pvg", "pv.groupId=pvg.groupId", "left")->from("member_conversation s", "s.conversationId=c.conversationId AND type='member' AND s.id=:userId", "left")->bind(":userId", ET::$session->userId)->from("member sm", "sm.memberId=c.startMemberId", "left")->where($wheres)->groupBy("c.channelId")->limit(1); // Fetch the labels field as well. $this->addLabels($sql); // Make sure the user is allowed to view this conversation. $this->addAllowedPredicate($sql); // Fetch the user's reply and moderate permissions for this conversation. if (!ET::$session->isAdmin()) { $sql->select("BIT_OR(p.reply)", "canReply")->select("BIT_OR(p.moderate)", "canModerate")->select("BIT_OR(p.moderate)", "canDeleteConversation")->from("channel_group p", "c.channelId=p.channelId AND p.groupId IN (:groupIds)", "left")->bind(":groupIds", ET::$session->getGroupIds()); } else { $sql->select("1", "canReply")->select("1", "canModerate")->select("1", "canDeleteConversation"); } // Execute the query. $result = $sql->exec(); if (!$result->numRows()) { return false; } // Get all the details from the result into an array. $conversation = $result->firstRow(); // 2016/02 SWCユーザ名設定 $conversation["startMember"] = SwcUtils::getUserName($conversation["startMemberId"]); // Expand the labels field into a simple array of active labels. $conversation["labels"] = $this->expandLabels($conversation["labels"]); // Convert the separate groups who have permission to view this channel ID/name fields into one. $conversation["channelPermissionView"] = $this->formatGroupsAllowed($conversation["channelPermissionView"], $conversation["channelPermissionViewNames"]); // If the conversation is locked and the user can't moderate, then they can't reply. if ($conversation["locked"] and !$conversation["canModerate"]) { $conversation["canReply"] = false; } // If the current user owns this conversation, and it's a draft, or they're the only poster, // then allow them to delete it. We can only know that they're the only poster if there is only // one post in the conversation, or if there are two and the last one is theirs. In an ideal world, // we would check all of the post authors, but it's probably not worth the performance hit here. if ($conversation["startMemberId"] == ET::$session->userId and ($conversation["countPosts"] <= 1 or $conversation["countPosts"] == 2 and $conversation["lastPostMemberId"] == ET::$session->userId)) { $conversation["canDeleteConversation"] = true; } return $conversation; }
/** * Common initialization for all controllers, called on every page load. This will add basic user links to * the "user" menu, and add core JS files and language definitions. * * If this is overridden, parent::init() should be called to maintain consistency between controllers. * * @return void */ public function init() { // Check for updates to the esoTalk software, but only if we're the root admin and we haven't checked in // a while. // 1/28 掲示板バージョンUPチェック処理 削除 // if (ET::$session->userId == C("esoTalk.rootAdmin") and C("esoTalk.admin.lastUpdateCheckTime") + C("esoTalk.updateCheckInterval") < time()) // ET::upgradeModel()->checkForUpdates(); if ($this->responseType === RESPONSE_TYPE_DEFAULT) { // If the user IS NOT logged in, add the 'login' and 'sign up' links to the bar. if (!ET::$session->user) { // 1/28 リンク先変更 SWC新規登録ページへ $this->addToMenu("user", "join", "<a href='" . URL(SwcUtils::getSwcUrl("entry") . "?return=" . urlencode($this->selfURL)) . "' class='link-join'>" . T("Sign Up") . "</a>"); // 1/28 リンク先変更 SWCログインページへ $this->addToMenu("user", "login", "<a href='/login/index.php' class='link-login'>" . T("Log In") . "</a>"); } else { $this->addToMenu("user", "user", "<a href='" . URL("member/me") . "'>" . avatar(ET::$session->user, "thumb") . name(ET::$session->user["username"]) . "</a>"); $this->addToMenu("user", "settings", "<a href='" . URL("settings") . "' class='link-settings'>" . T("Settings") . "</a>"); if (ET::$session->isAdmin()) { $this->addToMenu("user", "administration", "<a href='" . URL("admin") . "' class='link-administration'>" . T("Administration") . "</a>"); } // リンク先変更 ログアウト $this->addToMenu("user", "logout", "<a href='" . URL("user/logout?token=" . ET::$session->token) . "' class='link-logout'>" . T("Log Out") . "</a>"); } // Get the number of members currently online and add it as a statistic. if (C("esoTalk.members.visibleToGuests") or ET::$session->user) { $online = ET::SQL()->select("COUNT(*)")->from("member")->where("UNIX_TIMESTAMP()-:seconds<lastActionTime")->bind(":seconds", C("esoTalk.userOnlineExpire"))->exec()->result(); $stat = Ts("statistic.online", "statistic.online.plural", number_format($online)); $stat = "<a href='" . URL("members/online") . "' class='link-membersOnline'>{$stat}</a>"; // 2016/1 削除 オンラインリンク // $this->addToMenu("statistics", "statistic-online", $stat); } // 2016/1 削除 copyright // $this->addToMenu("meta", "copyright", "<a href='http://esotalk.org/' target='_blank'>".T("Powered by")." esoTalk</a>"); // Set up some default JavaScript files and language definitions. $this->addJSFile("core/js/lib/jquery.js", true); $this->addJSFile("core/js/lib/jquery.misc.js", true); $this->addJSFile("core/js/lib/jquery.history.js", true); $this->addJSFile("core/js/lib/jquery.scrollTo.js", true); $this->addJSFile("core/js/global.js", true); $this->addJSLanguage("message.ajaxRequestPending", "message.ajaxDisconnected", "Loading...", "Notifications"); $this->addJSVar("notificationCheckInterval", C("esoTalk.notificationCheckInterval")); // If config/custom.css contains something, add it to be included in the page. if (file_exists($file = PATH_CONFIG . "/custom.css") and filesize($file) > 0) { $this->addCSSFile("config/custom.css", true); } } $this->trigger("init"); }
<?php if (!$data["searchString"]) { ?> <!-- Reply area --> <div id='conversationReply'> <?php echo $data["replyForm"]->open(); ?> <?php // If we can't reply, we should show some kind of error message. if (!$conversation["canReply"]) { // If the user simply isn't logged in, show a reply box placeholder saying that they need to log in or sign up. if (!ET::$session->user) { $post = array("id" => "reply", "class" => "logInToReply", "title" => "", "body" => sprintf(T("message.logInToReply"), SwcUtils::getSwcUrl('login'), SwcUtils::getSwcUrl('login')), "avatar" => avatar()); $this->renderView("conversation/post", array("post" => $post)); } elseif (ET::$session->isSuspended()) { echo "<p class='help'>" . T("message.suspended") . "</p>"; } elseif ($conversation["locked"]) { echo "<p class='help'>" . T("message.locked") . "</p>"; } } else { $this->renderView("conversation/reply", array("form" => $data["replyForm"], "conversation" => $conversation, "controls" => $data["replyControls"])); } ?> <?php echo $data["replyForm"]->close(); ?> </div>
/** * アバター画像(SWCのプロフィール画像表示する) * * Return a HTML element to display a member's avatar. * * @param array $member An array of the member's details. (memberId and avatarFormat are required in this implementation.) * @param string $className CSS class names to apply to the avatar. * * @package esoTalk */ function avatar($member = array(), $className = "") { // SWCからユーザプロフィール画像取得urlをsrcに設定する // Construct the avatar path from the provided information. // TODO: SWCユーザに存在するユーザIDかチェック要 if (!empty($member["memberId"])) { $url = SwcUtils::getUserImgUrl($member['memberId']); return "<img src='{$url}' alt='' class='avatar {$className}'/>"; } // Default to an avatar with the first letter of the member's name. $l = strtoupper($member["username"][0]); if (SwcUtils::isMB($member["username"][0])) { $l = mb_strtoupper($member["username"][0]); } return "<span class='avatar {$className}'>" . (!empty($member["username"]) ? $l : " ") . "</span>"; }
/** * 2016/02 変更修正 * * SWCユーザ情報取得 * * SWC側のAPIでユーザ情報取得する。 * 掲示板のユーザ情報(et_member)にマージして返却する * * $withSwcUserInfo= false の場合: * SWCユーザ情報を取得せずに返却する * * Get member data for the specified post ID. * * @param int $memberId The ID of the member. * @param type $withSwcUserInfo * @return array An array of the member's details. */ public function getById($memberId, $withSwcUserInfo = true) { if ($withSwcUserInfo) { // SWCユーザ情報取得 $userInfo = SwcUtils::getUserDetail($memberId); // ユーザ情報マージ処理 return $this->refreshUserData($userInfo); } else { // 2016/02 memberId= SWCのユーザID となる return reset($this->get(array("m.memberId" => $memberId))); } }
/** * Get a full list of conversation details for a list of conversation IDs. * * @param array $conversationIDs The list of conversation IDs to fetch details for. * @param bool $checkForPermission Whether or not to add a check onto the query to make sure the * user has permission to view all of the conversations. */ public function getResults($conversationIDs, $checkForPermission = false) { // Construct a query to get details for all of the specified conversations. $sql = ET::SQL()->select("s.*")->select("c.*")->select("sm.memberId", "startMemberId")->select("sm.username", "startMember")->select("sm.avatarFormat", "startMemberAvatarFormat")->select("lpm.memberId", "lastPostMemberId")->select("lpm.username", "lastPostMember")->select("lpm.email", "lastPostMemberEmail")->select("lpm.avatarFormat", "lastPostMemberAvatarFormat")->select("IF((IF(c.lastPostTime IS NOT NULL,c.lastPostTime,c.startTime)>:markedAsRead AND (s.lastRead IS NULL OR s.lastRead<c.countPosts)),(c.countPosts - IF(s.lastRead IS NULL,0,s.lastRead)),0)", "unread")->select("p.content", "firstPost")->from("conversation c")->from("member_conversation s", "s.conversationId=c.conversationId AND s.type='member' AND s.id=:memberId", "left")->from("member sm", "c.startMemberId=sm.memberId", "left")->from("member lpm", "c.lastPostMemberId=lpm.memberId", "left")->from("channel ch", "c.channelId=ch.channelId", "left")->from("post p", "c.sticky AND c.conversationId=p.conversationId AND c.startTime=p.time", "left")->bind(":markedAsRead", ET::$session->preference("markedAllConversationsAsRead"))->bind(":memberId", ET::$session->userId); // If we need to, filter out all conversations that the user isn't allowed to see. if ($checkForPermission) { ET::conversationModel()->addAllowedPredicate($sql); } // Add a labels column to the query. ET::conversationModel()->addLabels($sql); // Limit the results to the specified conversation IDs $sql->where("c.conversationId IN (:conversationIds)")->orderBy("FIELD(c.conversationId,:conversationIdsOrder)"); $sql->bind(":conversationIds", $conversationIDs, PDO::PARAM_INT); $sql->bind(":conversationIdsOrder", $conversationIDs, PDO::PARAM_INT); $this->trigger("beforeGetResults", array(&$sql)); // Execute the query and put the details of the conversations into an array. $result = $sql->exec(); $results = array(); $model = ET::conversationModel(); while ($row = $result->nextRow()) { // XXX: 2016/02 SWCユーザ名設定 $row["startMember"] = SwcUtils::getUserName($row["startMemberId"]); $row["lastPostMember"] = SwcUtils::getUserName($row["lastPostMemberId"]); // Expand the comma-separated label flags into a workable array of active labels. $row["labels"] = $model->expandLabels($row["labels"]); $row["replies"] = max(0, $row["countPosts"] - 1); $results[] = $row; } $this->trigger("afterGetResults", array(&$results)); return $results; }
/** * 一覧データにメイン画像サムネイル表示情報を追加する * @param type $results */ private function addMainThumb($results) { if (!SWC_MAIN_THUMB_DISPLAY) { $results; } $atModel = ET::getInstance("attachmentModel"); foreach ($results as &$r) { // XXX: 一覧メイン画像サムネイル表示処理 // ※下書きには別アイコンが出るので表示しない if (!$r["draft"] && intval($r["countPosts"]) > 0) { // 下書きでない、投稿カウントありの場合 // メイン画像ID取得 $attachmentId = $atModel->getMainAttachmentId($r["conversationId"]); $menuImgUrl = ""; if ($attachmentId) { // 添付画像あり $menuImgUrl = URL("attachment/menu/" . $attachmentId); } else { // デフォルトイメージ画像url $menuImgUrl = SwcUtils::getNoImageFileUrl(); } $r["menuImgUrl"] = $menuImgUrl; } } unset($r); return $results; }
/** * Session 初期処理 * リクエスト単位に、SWC側でSession構築される * 基本、掲示板側では新たなSession は生成しない * Class constructor: starts the session and initializes class properties (ip, token, user, etc.) * * @return void */ public function __construct() { // Session初期処理 $sesName = session_name(); // SWCログインフラグ $isLogin = false; // SWCユーザ情報 $userInfo = ""; // SWCユーザ情報リスト初期化 $this->usersList = array(); // --------------------------------- // SWCログインチェック // ※SWC側でSession が生成される // --------------------------------- $rtn = SwcUtils::isSwcLogin(); // SWCログイン済の場合 if ($rtn instanceof self::$swc_rel_classname && $rtn->isLogin) { // 戻り値が戻り値クラスインスタンスかつ、ログイン中の場合 $isLogin = true; // ユーザ情報取得設定 $this->userInfo = $rtn->userDetail; // SWCのセッション情報から[user][session_id] を取得する if (key_exists("user", $_SESSION) && key_exists("session_id", $_SESSION["user"])) { $this->userInfo["sessid"] = $_SESSION["user"]["session_id"]; } // セッション設定 $_SESSION["userId"] = $this->userInfo['user_id']; } $sesName = session_name(); if ($isLogin || $sesName == SwcUtils::SWC_SESS_NAME) { // ログイン済、またはSWCセッションが開始済の場合 // セッションはそのまま利用する if (empty($_SESSION["token"])) { $_SESSION["token"] = substr(md5(uniqid(rand())), 0, 13); $_SESSION["userAgent"] = md5($_SERVER["HTTP_USER_AGENT"]); } } else { // セッションがない場合(基本あり得ない) // ETセッション開始 $etSesName = C("esoTalk.cookie.name") . "_session"; if ($sesName != $etSesName) { session_name(C("esoTalk.cookie.name") . "_session"); session_start(); if (empty($_SESSION["token"])) { $this->regenerateToken(); } } } // Complicate session highjacking - check the current user agent against the one that initiated the session. if (md5($_SERVER["HTTP_USER_AGENT"]) != $_SESSION["userAgent"]) { session_destroy(); } // Set the class properties to reference session variables. $this->token =& $_SESSION["token"]; $this->ip = $_SERVER["REMOTE_ADDR"]; $this->userId =& $_SESSION["userId"]; // If there's a user logged in, get their user data. // --------------------------------- // 最新のSWCユーザ情報をセッションに設定する // --------------------------------- if ($this->userId and C("esoTalk.installed")) { $this->refreshUserData($this->userInfo); } }