$like_content, ) ); if ($smcFunc['db_num_rows']($request) == 1) list ($id_topic) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); if (empty($id_topic)) fatal_lang_error(isset($_GET['view']) ? 'cannot_view_likes' : 'cannot_like_content', false); // So we know what topic it's in and more importantly we know the user can see it. // If we're not viewing, we need some info set up. if (!isset($_GET['view'])) { $context['flush_cache'] = 'likes_topic_' . $id_topic . '_' . $context['user']['id']; $context['redirect_from_like'] = 'topic=' . $id_topic . '.msg' . $like_content . '#msg' . $like_content; add_integration_function('integrate_issue_like', 'msg_issue_like', '', false); } } else { // Modders: This will give you whatever the user offers up in terms of liking, e.g. $like_type=msg, $like_content=1 // When you hook this, check $like_type first. If it is not something your mod worries about, return false. // Otherwise, determine (however you need to) that the user can see the relevant liked content (and it exists). // If the user cannot see it, return false. If the user can see it and can like it, you MUST return your $like_type back. // See also issueLike() for further notes. $can_like = call_integration_hook('integrate_valid_likes', array($like_type, $like_content)); $found = false; if (!empty($can_like)) { $can_like = (array) $can_like; foreach ($can_like as $result) { if ($result !== false) { $like_type = $result; $found = true; break; } } } if (!$found) fatal_lang_error(isset($_GET['view']) ? 'cannot_view_likes' : 'cannot_like_content', false); } // So at this point, whatever type of like the user supplied and the item of content in question, // we know it exists, now we need to figure out what we're doing with that. if (isset($_GET['view'])) viewLikes($like_type, $like_content); else { // Only registered users may actually like content. is_not_guest(); checkSession('get'); issueLike($like_type, $like_content); } } /** * @param string $like_type The type of content being liked * @param integer $like_content The ID of the content being liked */ function issueLike($like_type, $like_content) { global $context, $smcFunc; // Do we already like this? $request = $smcFunc['db_query']('', ' SELECT content_id, content_type, id_member FROM {db_prefix}user_likes WHERE content_id = {int:like_content} AND content_type = {string:like_type} AND id_member = {int:id_member}', array( 'like_content' => $like_content, 'like_type' => $like_type, 'id_member' => $context['user']['id'], ) ); $already_liked = $smcFunc['db_num_rows']($request) != 0; $smcFunc['db_free_result']($request); if ($already_liked) { $smcFunc['db_query']('', ' DELETE FROM {db_prefix}user_likes WHERE content_id = {int:like_content} AND content_type = {string:like_type} AND id_member = {int:id_member}', array( 'like_content' => $like_content, 'like_type' => $like_type, 'id_member' => $context['user']['id'], ) ); } else { // Insert the like. $smcFunc['db_insert']('insert', '{db_prefix}user_likes', array('content_id' => 'int', 'content_type' => 'string-6', 'id_member' => 'int', 'like_time' => 'int'), array($like_content, $like_type, $context['user']['id'], time()), array('content_id', 'content_type', 'id_member') ); // Add a background task to process sending alerts. $smcFunc['db_insert']('insert', '{db_prefix}background_tasks', array('task_file' => 'string', 'task_class' => 'string', 'task_data' => 'string', 'claimed_time' => 'int'), array('$sourcedir/tasks/Likes-Notify.php', 'Likes_Notify_Background', serialize(array( 'content_id' => $like_content, 'content_type' => $like_type, 'sender_id' => $context['user']['id'], 'sender_name' => $context['user']['name'], 'time' => time(), )), 0), array('id_task') ); } // Now, how many people like this content now? We *could* just +1 / -1 the relevant container but that has proven to become unstable. $request = $smcFunc['db_query']('', ' SELECT COUNT(id_member) FROM {db_prefix}user_likes WHERE content_id = {int:like_content} AND content_type = {string:like_type}', array( 'like_content' => $like_content, 'like_type' => $like_type, ) ); list ($num_likes) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Sometimes there might be other things that need updating after we do this like. call_integration_hook('integrate_issue_like', array($like_type, $like_content, $num_likes)); // Now some clean up. This is provided here for any like handlers that want to do any cache flushing. // This way a like handler doesn't need to explicitly declare anything in integrate_issue_like, but do so // in integrate_valid_likes where it absolutely has to exist. if (!empty($context['flush_cache'])) cache_put_data($context['flush_cache'], null); if (!empty($context['redirect_from_like'])) redirectexit($context['redirect_from_like']); else redirectexit(); // Because we have to go *somewhere*. } /** * Callback attached to integrate_issue_like. * Partly it indicates how it's supposed to work and partly it deals with updating the count of likes * attached to this message now. * @param string $like_type The type of content being liked - should always be 'msg' * @param int $like_content The ID of the post being liked * @param int $num_likes The number of likes this message has received */ function msg_issue_like($like_type, $like_content, $num_likes) { global $smcFunc; if ($like_type !== 'msg') return; $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET likes = {int:num_likes} WHERE id_msg = {int:id_msg}', array( 'id_msg' => $like_content, 'num_likes' => $num_likes, ) ); // Note that we could just as easily have cleared the cache here, or set up the redirection address // but if your liked content doesn't need to do anything other than have the record in smf_user_likes, // there's no point in creating another function unnecessarily. } /** * This is for viewing the people who liked a thing. * Accessed from index.php?action=likes;view and should generally load in a popup. * We use a template for this in case themers want to style it. * @param string $like_type The type of content being liked * @param integer $like_content The ID of the content being liked */ function viewLikes($like_type, $like_content) { global $smcFunc, $txt, $context, $memberContext; // Firstly, load what we need. We already know we can see this, so that's something. $context['likers'] = array(); $request = $smcFunc['db_query']('', ' SELECT id_member, like_time FROM {db_prefix}user_likes WHERE content_id = {int:like_content} AND content_type = {string:like_type} ORDER BY like_time DESC', array( 'like_content' => $like_content, 'like_type' => $like_type, ) ); while ($row = $smcFunc['db_fetch_assoc']($request)) $context['likers'][$row['id_member']] = array('timestamp' => $row['like_time']); // Now to get member data, including avatars and so on. $members = array_keys($context['likers']); $loaded = loadMemberData($members); if (count($loaded) != count($members)) { $members = array_diff($members, $loaded); foreach ($members as $not_loaded) unset ($context['likers'][$not_loaded]); } foreach ($context['likers'] as $liker => $dummy) { $loaded = loadMemberContext($liker); if (!$loaded) { unset ($context['likers'][$liker]); continue; } $context['likers'][$liker]['profile'] = &$memberContext[$liker]; $context['likers'][$liker]['time'] = !empty($dummy['timestamp']) ? timeformat($dummy['timestamp']) : ''; } $count = count($context['likers']); $title_base = isset($txt['likes_' . $count]) ? 'likes_' . $count : 'likes_n'; $context['page_title'] = strip_tags(sprintf($txt[$title_base], '', comma_format($count))); // Lastly, setting up for display loadTemplate('Likes'); loadLanguage('Help'); // for the close window button $context['template_layers'] = array(); $context['sub_template'] = 'popup'; } /** * What's this? I dunno, what are you talking about? Never seen this before, nope. No sir. */ function BookOfUnknown() { global $context, $scripturl; echo ' The Book of Unknown, ', @$_GET['verse'] == '2:18' ? '2:18' : '4:16', '
'; if (!isset($_GET['verse']) || ($_GET['verse'] != '2:18' && $_GET['verse'] != '22:1-2')) $_GET['verse'] = '4:16'; if ($_GET['verse'] == '2:18') echo ' Woe, it was that his name wasn\'t known, that he came in mystery, and was recognized by none. And it became to be in those days something.  Something not yet unknown to mankind.  And thus what was to be known the secret project began into its existence.  Henceforth the opposition was only weary and fearful, for now their match was at arms against them.'; elseif ($_GET['verse'] == '4:16') echo ' And it came to pass that the unbelievers dwindled in number and saw rise of many proselytizers, and the opposition found fear in the face of the x and the j while those who stood with the something grew stronger and came together.  Still, this was only the beginning, and what lay in the future was unknown to all, even those on the right side.'; elseif ($_GET['verse'] == '22:1-2') echo '

Now behold, that which was once the secret project was unknown no longer.  Alas, it needed more than only one, but yet even thought otherwise.  It became that the opposition rumored and lied, but still to no avail.  Their match, though not perfect, had them outdone.

Let it continue.  The end.

'; echo '
'; if ($_GET['verse'] == '2:18') echo ' from The Book of Unknown, 2:18'; elseif ($_GET['verse'] == '4:16') echo ' from The Book of Unknown, 4:16'; elseif ($_GET['verse'] == '22:1-2') echo ' from The Book of Unknown, 22:1-2'; echo '
'; obExit(false); } ?>