summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--actions/deletenotice.php2
-rw-r--r--actions/opensearch.php2
-rw-r--r--classes/Avatar.php2
-rw-r--r--classes/User.php8
-rw-r--r--classes/User_group.php2
-rw-r--r--classes/User_role.php3
-rw-r--r--lib/action.php34
-rw-r--r--lib/common.php1
-rw-r--r--lib/htmloutputter.php4
-rw-r--r--lib/noticelist.php2
-rw-r--r--lib/noticesection.php2
-rw-r--r--lib/right.php3
-rw-r--r--lib/theme.php164
-rw-r--r--scripts/userrole.php85
14 files changed, 253 insertions, 61 deletions
diff --git a/actions/deletenotice.php b/actions/deletenotice.php
index 4a48a9c34..ba8e86d0f 100644
--- a/actions/deletenotice.php
+++ b/actions/deletenotice.php
@@ -67,7 +67,7 @@ class DeletenoticeAction extends Action
common_user_error(_('Not logged in.'));
exit;
} else if ($this->notice->profile_id != $this->user_profile->id &&
- !$this->user->hasRight(Right::deleteOthersNotice)) {
+ !$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
common_user_error(_('Can\'t delete this notice.'));
exit;
}
diff --git a/actions/opensearch.php b/actions/opensearch.php
index b2186f0e9..8ebb5fc82 100644
--- a/actions/opensearch.php
+++ b/actions/opensearch.php
@@ -75,7 +75,7 @@ class OpensearchAction extends Action
$this->element('Url', array('type' => 'text/html', 'method' => 'get',
'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---')))));
$this->element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico'));
- $this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), theme_path('logo.png'));
+ $this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), Theme::path('logo.png'));
$this->element('AdultContent', null, 'false');
$this->element('Language', null, common_language());
$this->element('OutputEncoding', null, 'UTF-8');
diff --git a/classes/Avatar.php b/classes/Avatar.php
index 64f105179..cc7a6b647 100644
--- a/classes/Avatar.php
+++ b/classes/Avatar.php
@@ -102,6 +102,6 @@ class Avatar extends Memcached_DataObject
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
- return theme_path('default-avatar-'.$sizenames[$size].'.png');
+ return Theme::path('default-avatar-'.$sizenames[$size].'.png');
}
}
diff --git a/classes/User.php b/classes/User.php
index b0d372be8..9b90ce61b 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -705,10 +705,12 @@ class User extends Memcached_DataObject
if (Event::handle('UserRightsCheck', array($this, $right, &$result))) {
switch ($right)
{
- case Right::deleteOthersNotice:
- $result = $this->hasRole('moderator');
+ case Right::DELETEOTHERSNOTICE:
+ $result = $this->hasRole(User_role::MODERATOR);
break;
- default:
+ case Right::CONFIGURESITE:
+ $result = $this->hasRole(User_role::ADMINISTRATOR);
+ default:
$result = false;
break;
}
diff --git a/classes/User_group.php b/classes/User_group.php
index 310ecff1e..b92638f7a 100644
--- a/classes/User_group.php
+++ b/classes/User_group.php
@@ -34,7 +34,7 @@ class User_group extends Memcached_DataObject
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
- return theme_path('default-avatar-'.$sizenames[$size].'.png');
+ return Theme::path('default-avatar-'.$sizenames[$size].'.png');
}
function homeUrl()
diff --git a/classes/User_role.php b/classes/User_role.php
index 85ecfb422..fc3806897 100644
--- a/classes/User_role.php
+++ b/classes/User_role.php
@@ -45,4 +45,7 @@ class User_role extends Memcached_DataObject
{
return Memcached_DataObject::pkeyGet('User_role', $kv);
}
+
+ const MODERATOR = 'moderator';
+ const ADMINISTRATOR = 'administrator';
}
diff --git a/lib/action.php b/lib/action.php
index 776549854..34b17063a 100644
--- a/lib/action.php
+++ b/lib/action.php
@@ -168,7 +168,7 @@ class Action extends HTMLOutputter // lawsuit
{
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/favicon.ico')) {
$this->element('link', array('rel' => 'shortcut icon',
- 'href' => theme_path('favicon.ico')));
+ 'href' => Theme::path('favicon.ico')));
} else {
$this->element('link', array('rel' => 'shortcut icon',
'href' => common_path('favicon.ico')));
@@ -177,7 +177,7 @@ class Action extends HTMLOutputter // lawsuit
if (common_config('site', 'mobile')) {
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/apple-touch-icon.png')) {
$this->element('link', array('rel' => 'apple-touch-icon',
- 'href' => theme_path('apple-touch-icon.png')));
+ 'href' => Theme::path('apple-touch-icon.png')));
} else {
$this->element('link', array('rel' => 'apple-touch-icon',
'href' => common_path('apple-touch-icon.png')));
@@ -210,16 +210,16 @@ class Action extends HTMLOutputter // lawsuit
if (Event::handle('StartShowUAStyles', array($this))) {
$this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
- 'href="'.theme_path('css/ie.css', 'base').'?version='.STATUSNET_VERSION.'" /><![endif]');
+ 'href="'.Theme::path('css/ie.css', 'base').'?version='.STATUSNET_VERSION.'" /><![endif]');
foreach (array(6,7) as $ver) {
- if (file_exists(theme_file('css/ie'.$ver.'.css', 'base'))) {
+ if (file_exists(Theme::file('css/ie'.$ver.'.css', 'base'))) {
// Yes, IE people should be put in jail.
$this->comment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '.
- 'href="'.theme_path('css/ie'.$ver.'.css', 'base').'?version='.STATUSNET_VERSION.'" /><![endif]');
+ 'href="'.Theme::path('css/ie'.$ver.'.css', 'base').'?version='.STATUSNET_VERSION.'" /><![endif]');
}
}
$this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
- 'href="'.theme_path('css/ie.css', null).'?version='.STATUSNET_VERSION.'" /><![endif]');
+ 'href="'.Theme::path('css/ie.css', null).'?version='.STATUSNET_VERSION.'" /><![endif]');
Event::handle('EndShowUAStyles', array($this));
}
@@ -391,9 +391,9 @@ class Action extends HTMLOutputter // lawsuit
if (Event::handle('StartAddressData', array($this))) {
$this->elementStart('a', array('class' => 'url home bookmark',
'href' => common_local_url('public')));
- if (common_config('site', 'logo') || file_exists(theme_file('logo.png'))) {
+ if (common_config('site', 'logo') || file_exists(Theme::file('logo.png'))) {
$this->element('img', array('class' => 'logo photo',
- 'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : theme_path('logo.png'),
+ 'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png'),
'alt' => common_config('site', 'name')));
}
$this->element('span', array('class' => 'fn org'), common_config('site', 'name'));
@@ -1101,4 +1101,22 @@ class Action extends HTMLOutputter // lawsuit
{
return Design::siteDesign();
}
+
+ /**
+ * Check the session token.
+ *
+ * Checks that the current form has the correct session token,
+ * and throw an exception if it does not.
+ *
+ * @return void
+ */
+
+ function checkSessionToken()
+ {
+ // CSRF protection
+ $token = $this->trimmed('token');
+ if (empty($token) || $token != common_session_token()) {
+ $this->clientError(_('There was a problem with your session token.'));
+ }
+ }
}
diff --git a/lib/common.php b/lib/common.php
index 68bdbf229..6aac46807 100644
--- a/lib/common.php
+++ b/lib/common.php
@@ -227,7 +227,6 @@ require_once 'markdown.php';
require_once INSTALLDIR.'/lib/util.php';
require_once INSTALLDIR.'/lib/action.php';
-require_once INSTALLDIR.'/lib/theme.php';
require_once INSTALLDIR.'/lib/mail.php';
require_once INSTALLDIR.'/lib/subs.php';
require_once INSTALLDIR.'/lib/Shorturl_api.php';
diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php
index ce83295fb..c2ec83c28 100644
--- a/lib/htmloutputter.php
+++ b/lib/htmloutputter.php
@@ -375,8 +375,8 @@ class HTMLOutputter extends XMLOutputter
$url = parse_url($src);
if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment))
{
- if(file_exists(theme_file($src,$theme))){
- $src = theme_path($src, $theme) . '?version=' . STATUSNET_VERSION;
+ if(file_exists(Theme::file($src,$theme))){
+ $src = Theme::path($src, $theme) . '?version=' . STATUSNET_VERSION;
}else{
$src = common_path($src);
}
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 385da37e9..027db2b3e 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -513,7 +513,7 @@ class NoticeListItem extends Widget
$user = common_current_user();
if (!empty($user) &&
- ($this->notice->profile_id == $user->id || $user->hasRight(Right::deleteOthersNotice))) {
+ ($this->notice->profile_id == $user->id || $user->hasRight(Right::DELETEOTHERSNOTICE))) {
$deleteurl = common_local_url('deletenotice',
array('notice' => $this->notice->id));
diff --git a/lib/noticesection.php b/lib/noticesection.php
index b223932ef..24465f8ba 100644
--- a/lib/noticesection.php
+++ b/lib/noticesection.php
@@ -114,7 +114,7 @@ class NoticeSection extends Section
$att_class = 'attachments';
}
- $clip = theme_path('images/icons/clip.png', 'base');
+ $clip = Theme::path('images/icons/clip.png', 'base');
$this->out->elementStart('a', array('class' => $att_class, 'style' => "font-style: italic;", 'href' => $href, 'title' => "# of attachments: $count"));
$this->out->raw(" ($count&nbsp");
$this->out->element('img', array('style' => 'display: inline', 'align' => 'top', 'width' => 20, 'height' => 20, 'src' => $clip, 'alt' => 'alt'));
diff --git a/lib/right.php b/lib/right.php
index 4e0096d46..4fc981af0 100644
--- a/lib/right.php
+++ b/lib/right.php
@@ -45,6 +45,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
class Right
{
- const deleteOthersNotice = 'deleteothersnotice';
+ const DELETEOTHERSNOTICE = 'deleteothersnotice';
+ const CONFIGURESITE = 'configuresite';
}
diff --git a/lib/theme.php b/lib/theme.php
index 08e3e8538..c658058ff 100644
--- a/lib/theme.php
+++ b/lib/theme.php
@@ -23,7 +23,7 @@
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Sarven Capadisli <csarven@status.net>
- * @copyright 2008 StatusNet, Inc.
+ * @copyright 2008-2009 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/
*/
@@ -33,62 +33,146 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
}
/**
- * Gets the full path of a file in a theme dir based on its relative name
+ * Class for querying and manipulating a theme
*
- * @param string $relative relative path within the theme directory
- * @param string $theme name of the theme; defaults to current theme
+ * Themes are directories with some expected sub-directories and files
+ * in them. They're found in either local/theme (for locally-installed themes)
+ * or theme/ subdir of installation dir.
*
- * @return string File path to the theme file
+ * This used to be a couple of functions, but for various reasons it's nice
+ * to have a class instead.
+ *
+ * @category Output
+ * @package StatusNet
+ * @author Evan Prodromou <evan@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/
*/
-function theme_file($relative, $theme=null)
+class Theme
{
- if (empty($theme)) {
- $theme = common_config('site', 'theme');
- }
- $dir = common_config('theme', 'dir');
- if (empty($dir)) {
- $dir = INSTALLDIR.'/theme';
- }
- return $dir.'/'.$theme.'/'.$relative;
-}
+ var $dir = null;
+ var $path = null;
-/**
- * Gets the full URL of a file in a theme dir based on its relative name
- *
- * @param string $relative relative path within the theme directory
- * @param string $theme name of the theme; defaults to current theme
- *
- * @return string URL of the file
- */
+ /**
+ * Constructor
+ *
+ * Determines the proper directory and path for this theme.
+ *
+ * @param string $name Name of the theme; defaults to config value
+ */
-function theme_path($relative, $theme=null)
-{
- if (empty($theme)) {
- $theme = common_config('site', 'theme');
- }
+ function __construct($name=null)
+ {
+ if (empty($name)) {
+ $name = common_config('site', 'theme');
+ }
+
+ // Check to see if it's in the local dir
+
+ $localroot = INSTALLDIR.'/local/theme';
+
+ $fulldir = $localroot.'/'.$name;
+
+ if (file_exists($fulldir) && is_dir($fulldir)) {
+ $this->dir = $fulldir;
+ $this->path = common_path('local/theme/'.$name.'/');
+ return;
+ }
+
+ // Check to see if it's in the distribution dir
- $path = common_config('theme', 'path');
+ $instroot = common_config('theme', 'dir');
- if (empty($path)) {
- $path = common_config('site', 'path') . '/theme/';
+ if (empty($instroot)) {
+ $instroot = INSTALLDIR.'/theme';
+ }
+
+ $fulldir = $instroot.'/'.$name;
+
+ if (file_exists($fulldir) && is_dir($fulldir)) {
+
+ $this->dir = $fulldir;
+
+ $path = common_config('theme', 'path');
+
+ if (empty($path)) {
+ $path = common_config('site', 'path') . '/theme/';
+ }
+
+ if ($path[strlen($path)-1] != '/') {
+ $path .= '/';
+ }
+
+ if ($path[0] != '/') {
+ $path = '/'.$path;
+ }
+
+ $server = common_config('theme', 'server');
+
+ if (empty($server)) {
+ $server = common_config('site', 'server');
+ }
+
+ // XXX: protocol
+
+ $this->path = 'http://'.$server.$path.$name;
+ }
}
- if ($path[strlen($path)-1] != '/') {
- $path .= '/';
+ /**
+ * Gets the full local filename of a file in this theme.
+ *
+ * @param string $relative relative name, like 'logo.png'
+ *
+ * @return string full pathname, like /var/www/mublog/theme/default/logo.png
+ */
+
+ function getFile($relative)
+ {
+ return $this->dir.'/'.$relative;
}
- if ($path[0] != '/') {
- $path = '/'.$path;
+ /**
+ * Gets the full HTTP url of a file in this theme
+ *
+ * @param string $relative relative name, like 'logo.png'
+ *
+ * @return string full URL, like 'http://example.com/theme/default/logo.png'
+ */
+
+ function getPath($relative)
+ {
+ return $this->path.'/'.$relative;
}
- $server = common_config('theme', 'server');
+ /**
+ * Gets the full path of a file in a theme dir based on its relative name
+ *
+ * @param string $relative relative path within the theme directory
+ * @param string $name name of the theme; defaults to current theme
+ *
+ * @return string File path to the theme file
+ */
- if (empty($server)) {
- $server = common_config('site', 'server');
+ static function file($relative, $name=null)
+ {
+ $theme = new Theme($name);
+ return $theme->getFile($relative);
}
- // XXX: protocol
+ /**
+ * Gets the full URL of a file in a theme dir based on its relative name
+ *
+ * @param string $relative relative path within the theme directory
+ * @param string $name name of the theme; defaults to current theme
+ *
+ * @return string URL of the file
+ */
- return 'http://'.$server.$path.$theme.'/'.$relative;
+ static function path($relative, $name=null)
+ {
+ $theme = new Theme($name);
+ return $theme->getPath($relative);
+ }
}
diff --git a/scripts/userrole.php b/scripts/userrole.php
new file mode 100644
index 000000000..7b6a9b3fd
--- /dev/null
+++ b/scripts/userrole.php
@@ -0,0 +1,85 @@
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - a distributed open-source microblogging tool
+ * Copyright (C) 2008, 2009, StatusNet, Inc.
+ *
+ * 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/>.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+$shortoptions = 'i:n:r:d';
+$longoptions = array('id=', 'nickname=', 'role=', 'delete');
+
+$helptext = <<<END_OF_USERROLE_HELP
+userrole.php [options]
+modifies a role for the given user
+
+ -d --delete delete the role
+ -i --id ID of the user
+ -n --nickname nickname of the user
+ -r --role role to add (or delete)
+
+END_OF_USERROLE_HELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+
+if (have_option('i', 'id')) {
+ $id = get_option_value('i', 'id');
+ $user = User::staticGet('id', $id);
+ if (empty($user)) {
+ print "Can't find user with ID $id\n";
+ exit(1);
+ }
+} else if (have_option('n', 'nickname')) {
+ $nickname = get_option_value('n', 'nickname');
+ $user = User::staticGet('nickname', $nickname);
+ if (empty($user)) {
+ print "Can't find user with nickname '$nickname'\n";
+ exit(1);
+ }
+} else {
+ print "You must provide either an ID or a nickname.\n";
+ exit(1);
+}
+
+$role = get_option_value('r', 'role');
+
+if (empty($role)) {
+ print "You must provide a role.\n";
+ exit(1);
+}
+
+if (have_option('d', 'delete')) {
+ print "Revoking role '$role' from user '$user->nickname' ($user->id)...";
+ try {
+ $user->revokeRole($role);
+ print "OK\n";
+ } catch (Exception $e) {
+ print "FAIL\n";
+ print $e->getMessage();
+ print "\n";
+ }
+} else {
+ print "Granting role '$role' to user '$user->nickname' ($user->id)...";
+ try {
+ $user->grantRole($role);
+ print "OK\n";
+ } catch (Exception $e) {
+ print "FAIL\n";
+ print $e->getMessage();
+ print "\n";
+ }
+}