]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/action.php
Let's not limit qvitter stuff to 'json' requests
[quix0rs-gnu-social.git] / lib / action.php
index 18ffb5e9206b1da4d2ee4dcab424d54f66c4e0bd..26afd7bfbe0667c085aad99144084f9957a27cf3 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once INSTALLDIR.'/lib/noticeform.php';
 require_once INSTALLDIR.'/lib/htmloutputter.php';
@@ -55,7 +53,23 @@ require_once INSTALLDIR.'/lib/htmloutputter.php';
  */
 class Action extends HTMLOutputter // lawsuit
 {
-    var $args;
+    // This should be protected/private in the future
+    public $args = array();
+
+    // Action properties, set per-class
+    protected $action = false;
+    protected $ajax   = false;
+    protected $menus  = true;
+    protected $needLogin = false;
+    protected $needPost = false;
+
+    // The currently scoped profile (normally Profile::current; from $this->auth_user for API)
+    protected $scoped = null;
+
+    // Related to front-end user representation
+    protected $format = null;
+    protected $error  = null;
+    protected $msg    = null;
 
     /**
      * Constructor
@@ -73,6 +87,44 @@ class Action extends HTMLOutputter // lawsuit
         parent::__construct($output, $indent);
     }
 
+    function getError()
+    {
+        return $this->error;
+    }
+
+    function getInfo()
+    {
+        return $this->msg;
+    }
+
+    static public function run(array $args=array(), $output='php://output', $indent=null) {
+        $class = get_called_class();
+        $action = new $class($output, $indent);
+        $action->execute($args);
+        return $action;
+    }
+
+    public function execute(array $args=array()) {
+        // checkMirror stuff
+        if (common_config('db', 'mirror') && $this->isReadOnly($args)) {
+            if (is_array(common_config('db', 'mirror'))) {
+                // "load balancing", ha ha
+                $arr = common_config('db', 'mirror');
+                $k = array_rand($arr);
+                $mirror = $arr[$k];
+            } else {
+                $mirror = common_config('db', 'mirror');
+            }
+
+            // everyone else uses the mirror
+            common_config_set('db', 'database', $mirror);
+        }
+
+        if ($this->prepare($args)) {
+            $this->handle($args);
+        }
+    }
+
     /**
      * For initializing members of the class.
      *
@@ -80,14 +132,27 @@ class Action extends HTMLOutputter // lawsuit
      *
      * @return boolean true
      */
-    function prepare($argarray)
+    protected function prepare(array $args=array())
     {
-        $this->args =& common_copy_args($argarray);
+        if ($this->needPost && !$this->isPost()) {
+            $this->clientError(_('This method requires a POST.'), 405);
+        }
+
+        $this->args = common_copy_args($args);
+
+        $this->action = $this->trimmed('action');
 
-        if ($this->boolean('ajax')) {
+        if ($this->ajax || $this->boolean('ajax')) {
+            // check with StatusNet::isAjax()
             StatusNet::setAjax(true);
         }
 
+        if ($this->needLogin) {
+            $this->checkLogin(); // if not logged in, this redirs/excepts
+        }
+
+        $this->scoped = Profile::current();
+
         return true;
     }
 
@@ -222,14 +287,12 @@ class Action extends HTMLOutputter // lawsuit
 
             // Use old name for StatusNet for compatibility on events
 
-            if (Event::handle('StartShowStatusNetStyles', array($this)) &&
-                Event::handle('StartShowLaconicaStyles', array($this))) {
+            if (Event::handle('StartShowStylesheets', array($this))) {
                 $this->primaryCssLink(null, 'screen, projection, tv, print');
-                Event::handle('EndShowStatusNetStyles', array($this));
-                Event::handle('EndShowLaconicaStyles', array($this));
+                Event::handle('EndShowStylesheets', array($this));
             }
 
-            $this->cssLink(common_path('js/css/smoothness/jquery-ui.css'));
+            $this->cssLink('js/extlib/jquery-ui/css/smoothness/jquery-ui.css');
 
             if (Event::handle('StartShowUAStyles', array($this))) {
                 $this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
@@ -298,21 +361,19 @@ class Action extends HTMLOutputter // lawsuit
         if (Event::handle('StartShowScripts', array($this))) {
             if (Event::handle('StartShowJQueryScripts', array($this))) {
                 if (common_config('site', 'minify')) {
-                    $this->script('jquery.min.js');
-                    $this->script('jquery.form.min.js');
-                    $this->script('jquery-ui.min.js');
-                    $this->script('jquery.cookie.min.js');
-                    $this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.min.js').'"); }');
-                    $this->script('jquery.joverlay.min.js');
-                    $this->script('jquery.infieldlabel.min.js');
+                    $this->script('extlib/jquery.min.js');
+                    $this->script('extlib/jquery.form.min.js');
+                    $this->script('extlib/jquery-ui/jquery-ui.min.js');
+                    $this->script('extlib/jquery.cookie.min.js');
+                    $this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/extlib/json2.min.js', StatusNet::isHTTPS()).'"); }');
+                    $this->script('extlib/jquery.infieldlabel.min.js');
                 } else {
-                    $this->script('jquery.js');
-                    $this->script('jquery.form.js');
-                    $this->script('jquery-ui.min.js');
-                    $this->script('jquery.cookie.js');
-                    $this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.js').'"); }');
-                    $this->script('jquery.joverlay.js');
-                    $this->script('jquery.infieldlabel.js');
+                    $this->script('extlib/jquery.js');
+                    $this->script('extlib/jquery.form.js');
+                    $this->script('extlib/jquery-ui/jquery-ui.js');
+                    $this->script('extlib/jquery.cookie.js');
+                    $this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/extlib/json2.js', StatusNet::isHTTPS()).'"); }');
+                    $this->script('extlib/jquery.infieldlabel.js');
                 }
 
                 Event::handle('EndShowJQueryScripts', array($this));
@@ -328,10 +389,8 @@ class Action extends HTMLOutputter // lawsuit
                 }
                 // This route isn't available in single-user mode.
                 // Not sure why, but it causes errors here.
-                if (!common_config('singleuser', 'enabled')) {
-                    $this->inlineScript('var _peopletagAC = "' .
-                                        common_local_url('peopletagautocomplete') . '";');
-                }
+                $this->inlineScript('var _peopletagAC = "' .
+                                    common_local_url('peopletagautocomplete') . '";');
                 $this->showScriptMessages();
                 // Anti-framing code to avoid clickjacking attacks in older browsers.
                 // This will show a blank page if the page is being framed, which is
@@ -372,7 +431,7 @@ class Action extends HTMLOutputter // lawsuit
 
             $messages = array_merge($messages, $this->getScriptMessages());
 
-           Event::handle('EndScriptMessages', array($this, &$messages));
+            Event::handle('EndScriptMessages', array($this, &$messages));
         }
 
         if (!empty($messages)) {
@@ -547,7 +606,7 @@ class Action extends HTMLOutputter // lawsuit
                     // if logo is an uploaded file, try to fall back to HTTPS file URL
                     $httpUrl = common_config('site', 'logo');
                     if (!empty($httpUrl)) {
-                        $f = File::staticGet('url', $httpUrl);
+                        $f = File::getKV('url', $httpUrl);
                         if (!empty($f) && !empty($f->filename)) {
                             // this will handle the HTTPS case
                             $logoUrl = File::url($f->filename);
@@ -1002,17 +1061,17 @@ class Action extends HTMLOutputter // lawsuit
             // TRANS: Text between [] is a link description, text between () is the link itself.
             // TRANS: Make sure there is no whitespace between "]" and "(".
             // TRANS: "%%site.broughtby%%" is the value of the variable site.broughtby
-            $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%).');
+            $instr = _('**%%site.name%%** is a social network, courtesy of [%%site.broughtby%%](%%site.broughtbyurl%%).');
         } else {
             // TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is not set.
-            $instr = _('**%%site.name%%** is a microblogging service.');
+            $instr = _('**%%site.name%%** is a social network.');
         }
         $instr .= ' ';
         // TRANS: Second sentence of the StatusNet site license. Mentions the StatusNet source code license.
         // TRANS: Make sure there is no whitespace between "]" and "(".
         // TRANS: Text between [] is a link description, text between () is the link itself.
         // TRANS: %s is the version of StatusNet that is being used.
-        $instr .= sprintf(_('It runs the [StatusNet](http://status.net/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), STATUSNET_VERSION);
+        $instr .= sprintf(_('It runs on [GNU social](http://www.gnu.org/software/social/), version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), STATUSNET_VERSION);
         $output = common_markup_to_html($instr);
         $this->raw($output);
         // do it
@@ -1164,11 +1223,9 @@ class Action extends HTMLOutputter // lawsuit
     /**
      * Handler method
      *
-     * @param array $argarray is ignored since it's now passed in in prepare()
-     *
      * @return boolean is read only action?
      */
-    function handle($argarray=null)
+    protected function handle()
     {
         header('Vary: Accept-Encoding,Cookie');
 
@@ -1302,26 +1359,121 @@ class Action extends HTMLOutputter // lawsuit
      *
      * @return nothing
      */
-    function serverError($msg, $code=500)
+    function serverError($msg, $code=500, $format=null)
     {
-        $action = $this->trimmed('action');
-        common_debug("Server error '$code' on '$action': $msg", __FILE__);
-        throw new ServerException($msg, $code);
+        if ($format === null) {
+            $format = $this->format;
+        }
+
+        common_debug("Server error '{$code}' on '{$this->action}': {$msg}", __FILE__);
+
+        if (!array_key_exists($code, ServerErrorAction::$status)) {
+            $code = 500;
+        }
+
+        $status_string = ServerErrorAction::$status[$code];
+
+        switch ($format) {
+        case 'xml':
+            header("HTTP/1.1 {$code} {$status_string}");
+            $this->initDocument('xml');
+            $this->elementStart('hash');
+            $this->element('error', null, $msg);
+            $this->element('request', null, $_SERVER['REQUEST_URI']);
+            $this->elementEnd('hash');
+            $this->endDocument('xml');
+            break;
+        case 'json':
+            if (!isset($this->callback)) {
+                header("HTTP/1.1 {$code} {$status_string}");
+            }
+            $this->initDocument('json');
+            $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
+            print(json_encode($error_array));
+            $this->endDocument('json');
+            break;
+        default:
+            throw new ServerException($msg, $code);
+        }
+
+        exit((int)$code);
     }
 
     /**
      * Client error
      *
-     * @param string  $msg  error message to display
-     * @param integer $code http error code, 400 by default
+     * @param string  $msg    error message to display
+     * @param integer $code   http error code, 400 by default
+     * @param string  $format error format (json, xml, text) for ApiAction
      *
      * @return nothing
+     * @throws ClientException always
      */
-    function clientError($msg, $code=400)
+    function clientError($msg, $code=400, $format=null)
     {
-        $action = $this->trimmed('action');
-        common_debug("User error '$code' on '$action': $msg", __FILE__);
-        throw new ClientException($msg, $code);
+        // $format is currently only relevant for an ApiAction anyway
+        if ($format === null) {
+            $format = $this->format;
+        }
+
+        common_debug("User error '{$code}' on '{$this->action}': {$msg}", __FILE__);
+
+        if (!array_key_exists($code, ClientErrorAction::$status)) {
+            $code = 400;
+        }
+        
+        $status_string = ClientErrorAction::$status[$code];
+
+        switch ($format) {
+        case 'xml':
+            header("HTTP/1.1 {$code} {$status_string}");
+            $this->initDocument('xml');
+            $this->elementStart('hash');
+            $this->element('error', null, $msg);
+            $this->element('request', null, $_SERVER['REQUEST_URI']);
+            $this->elementEnd('hash');
+            $this->endDocument('xml');
+            break;
+        case 'json':
+            if (!isset($this->callback)) {
+                header("HTTP/1.1 {$code} {$status_string}");
+            }
+            $this->initDocument('json');
+            $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
+            $this->text(json_encode($error_array));
+            $this->endDocument('json');
+            break;
+        case 'text':
+            header("HTTP/1.1 {$code} {$status_string}");
+            header('Content-Type: text/plain; charset=utf-8');
+            echo $msg;
+            break;
+        default:
+            throw new ClientException($msg, $code);
+        }
+        exit((int)$code);
+    }
+
+    /**
+     * If not logged in, take appropriate action (redir or exception)
+     *
+     * @param boolean $redir Redirect to login if not logged in
+     *
+     * @return boolean true if logged in (never returns if not)
+     */
+    public function checkLogin($redir=true)
+    {
+        if (common_logged_in()) {
+            return true;
+        }
+
+        if ($redir==true) {
+            common_set_returnto($_SERVER['REQUEST_URI']);
+            common_redirect(common_local_url('login'));
+        }
+
+        // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
+        $this->clientError(_('Not logged in.'), 403);
     }
 
     /**