We are no longer offering accounts on this server. Consider https://gitlab.freedesktop.org/ as a place to host projects.

DisqusPlugin.php 8.21 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Plugin to add Disqus commenting to notice pages
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Plugin
 * @package   StatusNet
 * @author    Zach Copley <zach@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    exit(1);
}

/**
 *
 * This plugin adds Disqus commenting to your notices. Enabling this
 * plugin will make each notice page display the Disqus widget, and
 * notice lists will display the number of commments each notice has.
 *
 * To use this plugin, you need to first register your site with Disqus
 * and get a Discus 'shortname' for it.
 *
 *    http://disqus.com
 *
 * To enable the plugin, put the following in you config.php:
 *
 * addPlugin(
48 49 50 51
 *     'Disqus', array(
 *         'shortname' => 'YOURSHORTNAME',
 *         'divStyle'  => 'width:675px; padding-top:10px; position:relative; float:left;'
 *     )
52 53
 * );
 *
54 55 56 57 58 59 60 61 62 63 64 65 66
 * If you only want to allow commenting on a specific user's notices or
 * a specific set of user's notices, use the "nicknames" array, e.g.:
 *
 * addPlugin(
 *     'Disqus', array(
 *         'shortname' => 'YOURSHORTNAME',
 *         'divStyle'  => 'width:675px; padding-top:10px; position:relative; float:left;',
 *         'nicknames' => array('spock', 'kirk', 'bones')
 *     )
 * );
 *
 *
 * NOTE: the 'divStyle' in an optional parameter that passes in some
67
 * inline CSS when creating the Disqus widget. It's a shortcut to make
68
 * the widget look OK with the default StatusNet theme. If you leave
69
 * it out you'll have to edit your theme CSS files to make the widget
70 71 72 73
 * look good.  You can also control the way the widget looks by
 * adding style rules to your theme.
 *
 * See: http://help.disqus.com/entries/100878-css-customization
74
 *
75
 *
76 77 78 79 80 81 82 83 84 85
 * @category Plugin
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 *
 * @see      Event
 */
class DisqusPlugin extends Plugin
{
86 87 88 89 90 91 92 93 94 95
    public $shortname; // Required 'shortname' for actually triggering Disqus
    public $divStyle;  // Optional CSS chunk for the main <div>
    public $nicknames; // Optional array of nicks to restrict commenting to (default on for all users)

    /**
     * Add a Disqus commenting section to the end of an individual
     * notice page's content block
     *
     * @param Action $action The current action
     */
96 97 98 99
    function onEndShowContentBlock($action)
    {
        if (get_class($action) == 'ShownoticeAction') {

100
            $profile = Profile::staticGet('id', $action->notice->profile_id);
101

102 103 104 105 106 107 108 109
            if ($this->hasCommenting($profile)) {

                $attrs = array();
                $attrs['id'] = 'disqus_thread';

                if ($this->divStyle) {
                    $attrs['style'] = $this->divStyle;
                }
110

111
                $action->element('div', $attrs, null);
112

113 114 115 116 117 118 119
                $script = <<<ENDOFSCRIPT
    var disqus_identifier = %d;
      (function() {
       var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
       dsq.src = 'http://%s.disqus.com/embed.js';
       (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
      })();
120 121
ENDOFSCRIPT;

122
                $action->inlineScript(sprintf($script, $action->notice->id, $this->shortname));
123

124
                $attrs = array();
125

126
                $attrs['id'] = 'disqus_thread_footer';
127

128 129 130
                if ($this->divStyle) {
                    $attrs['style'] = $this->divStyle;
                }
131

132 133
                $action->elementStart('div', $attrs);
                $action->elementStart('noscript');
134

135 136 137
                $noScriptMsg = sprintf(_m("Please enable JavaScript to view the [comments powered by Disqus](http://disqus.com/?ref_noscript=%s)."), $this->shortname);
                $output = common_markup_to_html($noScriptMsg);
                $action->raw($output);
138

139
                $action->elementEnd('noscript');
140

141 142 143 144 145 146
                $action->elementStart('a', array('href' => 'http://disqus.com', 'class' => 'dsq-brlink'));
                $action->raw(_m('Comments powered by '));
                $action->element('span', array('class' => 'logo-disqus'), 'Disqus');
                $action->elementEnd('a');
                $action->elementEnd('div');
            }
147 148 149
        }
    }

150 151 152 153 154 155
    /**
     * Add Disqus comment count script to the end of the scripts section
     *
     * @param Action $action the current action
     *
     */
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    function onEndShowScripts($action)
    {
        // fugly
        $script = <<<ENDOFSCRIPT
var disqus_shortname = '%s';
(function () {
  var s = document.createElement('script'); s.async = true;
  s.src = 'http://disqus.com/forums/%s/count.js';
  (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
ENDOFSCRIPT;
        $action->inlineScript(sprintf($script, $this->shortname, $this->shortname));

    }

171 172 173 174 175 176 177 178
    /**
     * Override the default Notice display to add Disqus comments link
     * (the link displays the total number of comments for each notice)
     *
     * @param NoticeListItem $noticeListItem
     *
     * @return boolean override
     */
179 180
    function onStartShowNoticeItem($noticeListItem)
    {
181
        // Don't enable commenting for remote notices
182 183 184 185
        if (empty($noticeListItem->notice->is_local)) {
            return true;
        }

186
        $profile = Profile::staticGet('id', $noticeListItem->notice->profile_id);
187

188
        if ($this->hasCommenting($profile)) {
189

190
            // @todo Refactor individual notice display to have it's own event hooks
191

192 193
            $noticeListItem->showNotice();
            $noticeListItem->showNoticeInfo();
194

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
            $noticeUrl = $noticeListItem->notice->bestUrl();
            $noticeUrl .= '#disqus_thread';

            $noticeListItem->out->element(
                'a', array('href' => $noticeUrl, 'class' => 'disqus_count'), 'Comments'
            );

            $noticeListItem->showNoticeOptions();
            Event::handle('EndShowNoticeItem', array($noticeListItem));

            return false;
        } else {
            return true;
        }
    }

    /**
     * Helper to check whether commenting should be enabled
     * for a given notice
     *
     * Assumes commenting should be enabled, unless the
     * nicknames array is populated
     *
     * @param Profile $profile the profile to check
     *
     * @return boolean true if yes
     */
    private function hasCommenting($profile)
    {
        if (!empty($this->nicknames)) {
            foreach ($this->nicknames as $nickname) {
                if ($profile->nickname == $nickname) {
                    return true;
                }
            }
            return false;
        }

        return true;
234 235
    }

236 237 238 239 240 241 242
    /**
     * Plugin details
     *
     * @param &$versions Array of current plugins
     *
     * @return boolean true
     */
243 244 245 246 247 248 249 250 251 252 253 254
    function onPluginVersion(&$versions)
    {
        $versions[] = array('name' => 'Disqus',
                            'version' => STATUSNET_VERSION,
                            'author' => 'Zach Copley',
                            'homepage' => 'http://status.net/wiki/Plugin:Disqus',
                            'rawdescription' =>
                            _m('Use <a href="http://disqus.com/">Disqus</a>'.
                               ' to add commenting to notice pages.'));
        return true;
    }
}