* @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';
*/
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
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.
*
*
* @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);
- if ($this->boolean('ajax')) {
+ $this->action = $this->trimmed('action');
+
+ 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;
}
// 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', StatusNet::isHTTPS()));
+ $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" '.
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', StatusNet::isHTTPS()).'"); }');
- $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', StatusNet::isHTTPS()).'"); }');
- $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));
$messages = array_merge($messages, $this->getScriptMessages());
- Event::handle('EndScriptMessages', array($this, &$messages));
+ Event::handle('EndScriptMessages', array($this, &$messages));
}
if (!empty($messages)) {
// 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);
/**
* 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');
*
* @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);
}
/**