root/trunk/gregarius/ajax.php

Revision 1718, 19.2 kB (checked in by mbonetti, 14 months ago)

kbnav: edit tags of current item (t), ajax: fix to actually submit the
edited tags, duh.

  • Property svn:eol-style set to native
  • Property svn:eolstyle set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2###############################################################################
3# Gregarius - A PHP based RSS aggregator.
4# Copyright (C) 2003 - 2006 Marco Bonetti
5#
6###############################################################################
7# This program is free software and open source software; you can redistribute
8# it and/or modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the License,
10# or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15# more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
20# http://www.gnu.org/licenses/gpl.html
21#
22###############################################################################
23# E-mail:      mbonetti at gmail dot com
24# Web page:    http://gregarius.net/
25###############################################################################
26
27if (array_key_exists('js',$_GET)) {
28    require_once('core.php');
29    rss_bootstrap(false,'$Revision$',0);
30}
31
32require_once('init.php');
33
34function __exp__setState($id,$state) {
35        if (isLoggedIn()) {
36                rss_query('update '.getTable('item') . " set unread=$state where id=$id");     
37                rss_invalidate_cache();
38        }
39    $rs = rss_query('select unread from '.getTable('item') . " where id=$id");
40    list($unread) = rss_fetch_row($rs);
41    return "$id|$unread";
42}
43
44function __exp__getSideContent($what) {
45        ob_start();
46        switch ($what) {
47                case 'FeedList':
48                        $f = new FeedList(false);
49                        $f -> render();
50                        break;
51
52                case 'CatList':
53                        //rss_require('cls/taglist.php');
54                        //$v = new TagList('channel');
55                        rss_require('cls/categories.php');
56                        $v = new CatList();
57                        $v -> render();
58                        break;
59
60                case 'TagList':
61                        rss_require('cls/taglist.php');
62                        $t = new TagList('item');
63                        $t -> render();
64                        break;
65        }
66        $c = ob_get_contents();
67        ob_end_clean();
68        rss_invalidate_cache();
69        return ($what . "#@#" .$c);
70}
71
72function __exp__getFeedContent($cid) {
73
74       
75        ob_start();
76        rss_require('cls/items.php');
77       
78        $readItems = new ItemList();
79
80        $readItems -> populate(" not(i.unread & ". RSS_MODE_UNREAD_STATE  .") and i.cid= $cid", "", 0, 2, ITEM_SORT_HINT_READ);
81        $readItems -> setTitle(__('Recent items'));
82        $readItems -> setRenderOptions(IL_TITLE_NO_ESCAPE);
83        foreach ($readItems -> feeds[0] -> items as $item) {
84                $item -> render();
85        }
86        $c = ob_get_contents();
87       
88        ob_end_clean();
89        return "$cid|@|$c";
90}
91
92function __exp__rateItem($iid, $rt) {
93        list($rrt) = rss_fetch_row(rss_query("select rating from "
94            .getTable('rating') . " where iid = $iid"));
95
96        rss_query('delete from ' .getTable('rating') . ' where iid = ' . $iid);
97        if ($rt == $rrt) {
98                return ("$iid|0");
99        }
100        rss_query('insert into ' .getTable('rating') . "(iid,rating) values ($iid,$rt)");
101        if (rss_is_sql_error(RSS_SQL_ERROR_NO_ERROR)) {
102                return ("$iid|$rt");
103        }
104}
105
106/**
107 * this exported AJAX method is only here so that the plugin callback
108 * hook is asynchronous
109 */
110function __exp_itemRatedCB($iid,$rt) {
111        rss_plugin_hook("rss.plugins.rating.rated",array($iid,$rt));
112        return null;
113}
114
115
116
117function __exp_addChannel($url, $folderid = 0, $title_=null,$descr_=null,$tags = null) {
118        rss_require('extlib/JSON.php');
119        $json = new SERVICES_JSON();
120        if (!isset($GLOBALS['rssuser'])) {
121                require_once('cls/user.php');
122        }
123        if(rss_user_check_user_level(RSS_USER_LEVEL_PRIVATE)) {
124                $ret = add_channel($url, $folderid, $title_,$descr_,$tags);
125        } else {
126                $ret = array (-1, "Sorry, you are not privileged enough to add feeds");
127        }
128       
129        return $json -> encode($ret);
130}
131
132$sajax_request_type = "POST";
133$sajax_debug_mode = 0;
134$sajax_remote_uri = getPath() . basename(__FILE__);
135
136// Non standard! One usually calls sajax_export() ...
137$sajax_export_list = array("__exp__submitTag","__exp__getSideContent","__exp__getFeedContent", "__exp_addChannel");
138
139// Plugins shall export ajax functions as well
140$sajax_export_list = rss_plugin_hook("rss.plugins.ajax.exports",$sajax_export_list);
141
142
143if (isLoggedIn()) {
144    $sajax_export_list[] = "__exp__setState";
145    $sajax_export_list[] = "__exp__rateItem";
146    $sajax_export_list[] = "__exp_itemRatedCB";
147}
148
149sajax_init();
150
151//////////////////////////////////////////////////////////////////////////////
152//////////////////////////////////////////////////////////////////////////////
153//////////////////////////////////////////////////////////////////////////////
154
155/* spit out the javascript for this bugger */
156if (array_key_exists('js',$_GET)) {
157
158    if (getConfig('rss.output.compression')) {
159            ob_start('ob_gzhandler');
160    } else {
161            ob_start();
162    }
163    header('Content-Type: text/javascript');
164    // The javascript output shall be cached
165    // The Etag was set at the start of this file.
166   
167    $js = sajax_get_javascript();
168    echo $js;
169
170    // and here is s'more javascript for field editing...
171    ?>
172
173/// End Sajax javscript
174/// From here on: Copyright (C) 2003 - 2006 Marco Bonetti, gregarius.net
175/// Released under GPL
176
177function miniloginform() {
178        span = document.getElementById('loginformcontainer');
179        if (span.style.display == 'none') {
180                span.style.display = 'block';
181        } else {
182                span.style.display = 'none';
183        }
184}
185
186function loginHandler() {
187        pw = document.getElementById('password');
188        username = document.getElementById('username');
189        var re = /[0-9a-f]{32}/ ;
190        if (! re.test(pw.value)) {
191                pw.value = hex_md5(pw.value + username.value);
192        }
193        return true;
194}
195
196function setTags(id,tagss) {
197  tags = tagss.split(' ');
198
199  var fld=document.getElementById("t" + id);
200  var html = "";
201  for (i=0;i<tags.length;i++) {
202     html = html + "<a href=\"<?php echo  getPath()
203     . (getConfig('rss.output.usemodrewrite')?'tag/':'tags.php?tag=')
204     ?>" + tags[i] + "\">" + tags[i] + "</a> ";
205  }
206  fld.innerHTML = html;
207
208  var aspan=document.getElementById("ta" + id);
209  aspan.innerHTML = "<a href=\"#\" onclick=\"_et(" +id +"); return false;\"><?php echo  __('edit') ?></a>";
210}
211
212function submit_tag_cb(ret) {
213    data= ret.split(',');
214    //replace(/[^a-zA-Z0-9\ _\.,]/gi,"")
215    id=data[0];
216    tags=data[1];
217    setTags(id,tags);
218}
219
220
221function submit_tag(id,tags) {
222    x___exp__submitTag(id, tags, submit_tag_cb);
223}
224
225function _et(id) {
226   var actionSpan = document.getElementById("ta" + id);
227    var toggle = actionSpan.firstChild;
228    if (toggle.innerHTML == "<?php echo  __('submit') ?>") {
229        var fld = document.getElementById("tfield" + id);
230      toggle.innerHTML="<?php echo  __('...') ?>";
231        submit_tag(id,fld.value);
232    } else if (toggle.innerHTML == "<?php echo __('edit') ?>") {
233       var isIE=document.all?true:false;
234       // the tag container
235       var tc=document.getElementById("t"+id);
236        var tags = tc.innerHTML.replace(/<\/?a[^>]*>(\ $)?/gi,"");
237        //.replace(<?php echo ALLOWED_TAGS_REGEXP ?>gi,"");
238        // submit link
239        toggle.innerHTML="<?php echo  __('submit') ?>";
240        // cancel link
241        cancel = document.createElement("a");
242        cancel.style.margin="0 0 0 0.5em";
243        cancel.innerHTML = "<?php echo  __('cancel') ?>";
244        cancel.setAttribute("href","#");
245        if (isIE) {
246            // the IE sucky way
247            cancel.onclick = function() { setTags(id,tags); return false;}
248       } else {
249          // the proper DOM way
250            cancel.setAttribute("onclick","setTags("+id+",'"+tags+"'); return false;");
251       }
252        actionSpan.appendChild(cancel);
253
254                  <?php rss_plugin_hook("rss.plugins.ajax.extrajs.edittag",null); ?>
255                 
256        tc.innerHTML = "<input class=\"tagedit\" id=\"tfield"
257         +id+"\" type=\"text\" value=\"" + tags + "\" />";
258
259        // set the caret to the end of the field for bloody IE
260        var control = tc.firstChild;
261                  control.onkeyup = function(e) {
262                                if (!e) { e = event; e.which = e.keyCode; }
263                                switch (e.which) {
264                                 case 10: case 13: _et(id); return false; break;
265                                 default: return true;  break;
266                                }
267                  };
268        control.focus();
269        if (control.createTextRange) {
270            var range = control.createTextRange();
271        range.collapse(false);
272            range.select();
273        } else if (control.setSelectionRange) {
274            control.focus();
275            var length = control.value.length;
276            control.setSelectionRange(length, length);
277        }
278    }
279    return false;
280}
281
282
283cs = getCookie('side');
284if (!cs) {
285        cs = '1';
286}
287document.currentSide = cs;
288document.currentSideCache = new Array();
289for (i=0;i<3;i++) {
290        document.currentSideCache[i] = null;
291}
292
293
294function _side(what) {
295        if (document.currentSide == what) {
296                return 0;
297        }
298       
299        document.currentSideCache[document.currentSide] = document.getElementById('channels').innerHTML;
300        if ((content = document.currentSideCache[what]) != null) {     
301                _setSideContent_cb( what + "#@#" + content );
302        } else {
303                x___exp__getSideContent(what, _setSideContent_cb);
304        }
305}
306
307function _setSideContent_cb(ret) {
308        data=ret.split('#@#');
309        kind=data[0];
310        content=data[1];
311        c = document.getElementById('channels').innerHTML;
312        ul = document.getElementById('sidemenu');
313        lis= ul.getElementsByTagName('li');
314        for (j=0;j<lis.length;j++) {
315                var li = lis[j];
316                if (li.id == ('sidemenu'+kind)) {
317                        li.className = "active";
318                } else {
319                        li.className = "";
320                }
321        }
322
323        document.currentSide = kind;
324        document.currentSideCache[kind] = content;
325        document.getElementById('channels').innerHTML = content;
326    setRootCookie("side",kind);
327}
328
329
330
331// feed collapsing
332function _ftgl(cid) {
333        cids = getCookie('collapsedfeeds');
334        if (cids) {
335                cidsArr = cids.split(":");
336        } else {
337                cidsArr = new Array();
338        }
339       
340        var ul = document.getElementById('f'+cid);
341        var img = document.getElementById('cli'+cid);
342        var collapsed  = (img.parentNode.className == 'expand');
343       
344        if (collapsed) {
345                img.src = img.src.replace(/plus/g,'minus');
346                img.parentNode.className = "collapse";
347                img.parentNode.parentNode.className="";
348                for(i=0;i<cidsArr.length;i++) {
349                        if (cidsArr[i] == cid) {
350                                cidsArr[i] = -1;
351                        }
352                }
353                if (ul.style.display == "none") {
354                        ul.style.display = "block";
355                } else {
356                        ul.innerHTML = "...";
357                        x___exp__getFeedContent(cid, get_feed_content_cb);
358                }
359        } else {
360                img.src = img.src.replace(/minus/g,'plus');
361                img.parentNode.className = "expand";
362                img.parentNode.parentNode.className="collapsed";
363                ul.style.display = "none";
364                cidsArr[cidsArr.length]=cid;
365        }
366       
367        cidsArr.sort();
368        cidsCookie = "";
369        for (i=0;i<cidsArr.length;i++) {
370                if (cidsArr[i] > 0) {
371                        cidsCookie = cidsCookie + cidsArr[i];
372                        if (i<cidsArr.length -1) {
373                                cidsCookie += ":";
374                        }
375                }
376        }
377        setRootCookie('collapsedfeeds',cidsCookie);
378}
379
380
381function get_feed_content_cb(data) {
382        d=data.split('|@|');
383        cid=d[0];
384        html=d[1];
385        if (cid) {
386                ul = document.getElementById('f'+cid);
387                if (ul) {
388                        ul.innerHTML = html;
389                        ul.style.display = "block";
390                }
391        }
392}
393
394function setRootCookie(cookieName,cookieValue) {
395  setCookie(cookieName,cookieValue,"<?php echo getPath(); ?>");
396}       
397function setRootSessionCookie(cookieName,cookieValue) {
398  setSessionCookie(cookieName,cookieValue,"<?php echo getPath(); ?>"); 
399}       
400// src: http://www.javascripter.net/faq/settinga.htm
401function setCookie(cookieName,cookieValue,path) {
402    //alert(cookieValue);
403    var today = new Date();
404    var expire = new Date();
405    // 1 year
406    expire.setTime(today.getTime() + 31536000000);
407    document.cookie = cookieName+"="+escape(cookieValue)
408        + "; expires="+expire.toGMTString()
409        + "; path="+path;
410}
411
412function setSessionCookie(cookieName,cookieValue,path) {
413    document.cookie = cookieName+"="+escape(cookieValue)
414        + "; path="+path;   
415}
416
417function getCookie(cookieName) {
418    var theCookie=""+document.cookie;
419    var ind=theCookie.indexOf(cookieName);
420    if (ind==-1 || cookieName=="") return "";
421    var ind1=theCookie.indexOf(';',ind);
422    if (ind1==-1) ind1=theCookie.length;
423    return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
424}
425
426<?php rss_plugin_hook("rss.plugins.ajax.extrajs.public",null); ?>
427
428<?php if (isLoggedIn()) { ?>
429
430<?php rss_plugin_hook("rss.plugins.ajax.extrajs.private",null); ?>
431
432document.states = new Array();
433document.prevState = new Array();
434
435
436function setState(id,state) {
437    x___exp__setState(id,state,setState_cb);
438}
439
440function setItemClass(id,cls) {
441    if ((a=document.getElementById('sa'+id)) && (li=a.parentNode)) {
442        li.className=cls;
443    }
444}
445
446function fade(id,amount) {
447    if ((a=document.getElementById('sa'+id)) && (li=a.parentNode)) {
448        li.style.opacity=amount;
449        li.style.height = amount*li.style.height;
450        if (amount <= 0) {
451            li.parentNode.removeChild(li);
452        }
453    }
454}
455
456function setItemHide(id, redirect){
457    if ((a=document.getElementById('sa'+id)) && (li=a.parentNode)) {
458       ul = li.parentNode;
459       
460       if (false) {
461        // do funky tuff
462        for (i=5;i>=0;i--) {
463            window.setTimeout('fade('+id+','+(2*i)/10+')', 100*(5-i));
464        }
465       } else {
466         trash = ul.removeChild(li);
467       }
468       
469       // remove parent elements (heading, ul) if all the children are gone
470       if (!redirect && (ul.getElementsByTagName('li').length == 0)) {
471        pn = ul.parentNode;
472       
473        var ps = ul.previousSibling;
474        while ( ps = ps.previousSibling ) {
475            if ("H3" == ps.nodeName.toUpperCase()) {
476                trash=ps.parentNode.removeChild(ps);
477                break;
478            }
479        }
480        trash = pn.removeChild(ul);
481       }
482       
483       if (redirect) {
484        if (t = document.getElementById("_markReadButton")) {
485            // Maybe we should fix the array of ids also...
486            self.setTimeout('t.click()', 1000);
487        }else{
488             self.setTimeout('setRedirect()', 1000);
489        }
490       }
491    }
492}
493
494function setRedirect() {
495        document.location = '<?php echo  getPath() ?>';
496}
497
498function setState_cb(ret) {
499    data=ret.replace(/[^0-9\|]/gi,"").split('|');
500    id=data[0];
501    s=data[1];
502    document.states[id]=s;
503    _ces(id);
504}
505
506function _es(id, state, cid) {
507        if (document.prevState[id] != null) {
508           // if we click the edit icon while editing cancel the edit
509           _ces(id);
510           document.prevState[id] = null;
511           return;
512        }
513         
514    if (document.states[id]) {
515        tmpState =document.states[id];
516    } else {
517        tmpState =state;
518    }
519    document.prevState[id] = tmpState;
520        if (div = document.getElementById('sad'+id)) {
521
522
523        onOk = '<?php echo  rss_plugin_hook("rss.plugins.ajax.admindlg.onok",""); ?>'.replace(/_ID_/g,id);
524        onCancel = '<?php echo  rss_plugin_hook("rss.plugins.ajax.admindlg.oncancel",""); ?>'.replace(/_ID_/g,id);
525        extraCode = '<?php echo  rss_plugin_hook("rss.plugins.ajax.admindlg",""); ?>'.replace(/_ID_/g,id);
526       
527  onOk += '_ses('+id+','+cid+'); return false;';
528    if (!onCancel) {
529        onCancel = '_ces('+id+'); return false;';
530    }
531        if (!extraCode) {
532           extraCode = '';
533        }
534        div.innerHTML = ''
535                + '<form class="sf" id="sf"'+id+'" action="#" method="post">'
536                + '<p><input type="checkbox" id="sf' + id + 'u" value="1"'
537                + (tmpState & <?php echo  RSS_MODE_UNREAD_STATE ?> ?' checked="checked"':'')
538                + ' />'
539                + '<label for="sf' + id + 'u"><?php echo  __("Unread (Set this item\'s read/unread state)") ?></label></p>'
540                + '<p><input type="checkbox" id="sf' + id + 's" value="1"'
541                + (tmpState & <?php echo  RSS_MODE_STICKY_STATE ?> ?' checked="checked"':'')
542                + ' />'
543                + '<label for="sf' + id + 's"><?php echo  __("Sticky (Won\'t be deleted when you prune items)") ?></label></p>'
544                + '<p><input type="checkbox" id="sf' + id + 'p" value="1"'
545                + (tmpState & <?php echo  RSS_MODE_PRIVATE_STATE ?> ?' checked="checked"':'')
546                + ' />'
547                + '<label for="sf' + id + 'p"><?php echo  __("Private (Only administrators can see private items)") ?></label></p>'
548                + '<p><input type="checkbox" id="sf' + id + 'f" value="1"'
549                + (tmpState & <?php echo  RSS_MODE_FLAG_STATE ?> ?' checked="checked"':'')
550                + ' />'
551    + '<label for="sf' + id + 'f"><?php echo  __("Flag (Flags an item for later reading)") ?></label></p>'
552                + extraCode
553                + '<p class="sbm">'
554                + '<a id="ess'+id+'ok" href="#" onclick="'+onOk+'"><?php echo  __("OK") ?></a>'
555                + '<a href="#" onclick="'+onCancel+'"><?php echo  __("Cancel") ?></a></p>'
556                + '</form>';
557
558    div.className = 'ief';
559    div.style.display = "block";
560   }
561}
562
563function _ces(id) {
564        if (div = document.getElementById('sad'+id)) {
565                div.className = '';
566                div.innerHTML = '';
567                div.style.display='none';
568        }
569       
570        if (sa = document.getElementById('sa' + id)) {
571        sa.focus();
572    }
573
574}
575
576function _ses(id,cid) {
577    s = 0;
578    if ((sfu = document.getElementById('sf'+id+'u')) && sfu.checked) {
579      s += <?php echo  RSS_MODE_UNREAD_STATE ?>;
580    }
581    if ((sfs = document.getElementById('sf'+id+'s')) && sfs.checked) {
582      s += <?php echo  RSS_MODE_STICKY_STATE ?>;
583    }
584    if ((sfp = document.getElementById('sf'+id+'p')) && sfp.checked) {
585      s += <?php echo  RSS_MODE_PRIVATE_STATE ?>;
586    }
587    if ((sff = document.getElementById('sf'+id+'f')) && sff.checked) {
588      s += <?php echo  RSS_MODE_FLAG_STATE ?>;
589    }
590   
591   
592
593    if ((p=document.prevState[id]) != s) {
594        if ((s & <?php echo  RSS_MODE_UNREAD_STATE ?>) != (p & <?php echo  RSS_MODE_UNREAD_STATE ?>)) {
595            if (s & <?php echo  RSS_MODE_UNREAD_STATE ?>) {
596                setItemClass(id,'item unread');
597                c=unreadCnt(1,cid);
598            } else {
599                c = unreadCnt(-1,cid);
600                                if ((sel = document.getElementById('<?php echo  SHOW_WHAT ?>')) &&
601                                    sel.options[sel.selectedIndex].value == <?php echo  SHOW_UNREAD_ONLY ?>) {
602                        setItemHide(id, (c==0));
603                                } else{
604                                        setItemClass(id, 'item even');                               
605                                }
606            }
607        }
608        if (btn=document.getElementById('ess'+id+'ok')) {
609            btn.innerHTML = '...';
610            btn.disabled = true;
611        }
612        document.prevState[id] = null;
613        setState(id,s);
614    } else {
615      // state didn't change!
616      _ces(id);
617    }
618}
619
620function unreadCnt(d,channel) {
621        c = null;
622        channels = document.getElementsByTagName("strong");
623        for(i=0;i<channels.length;i++){
624                if((channels[i].id == 'cid'+channel) || (channels[i].id == 'ucnt') || (channels[i].id == 'fucnt')){
625                        if (e = channels[i].innerHTML.replace(/[^0-9]+/g,"")) {
626                                e = d+eval(e);
627                                channels[i].innerHTML = channels[i].innerHTML.replace(/[0-9]+/g,e);
628                                if(channels[i].id == 'ucnt'){ c = e; }
629                        }
630                }
631        }
632        return c;
633}
634
635function _rt(id,rt) {
636         x___exp__rateItem(id,rt,rateItem_cb);
637}
638
639function rateItem_cb(ret) {
640        data=ret.replace(/[^0-9\|]/gi,"").split('|');
641        id = data[0];
642        rt = data[1];
643        if (id && rt) {
644               
645                ul = document.getElementById("rr" + id);
646                lis = ul.getElementsByTagName('li');
647                for (i=0;i<lis.length;i++) {
648                        var li = lis[i];
649                        if ((i+1) == rt) {
650                                li.className = "current";
651                        } else {
652             li.className = "";
653                        }
654                }
655                x___exp_itemRatedCB(id,rt,itemRatedCB_cb);
656        }
657}
658function itemRatedCB_cb(data) {}
659
660<?php }
661
662flush();
663exit();
664   
665//////////////////////////////////////////////////////////////////////////////
666//////////////////////////////////////////////////////////////////////////////
667
668} elseif(array_key_exists('rs',$_REQUEST)) {
669    // this one handles the xmlhttprequest call from the above javascript
670    sajax_handle_client_request();
671    exit();
672}
673
674//////////////////////////////////////////////////////////////////////////////
675//////////////////////////////////////////////////////////////////////////////
676?>
Note: See TracBrowser for help on using the browser.