.DS_Store
nbproject
*.mo
-
+*log*
+htaccess-sample
+installer.txt
+extlib/DB.php
--- /dev/null
+[submodule "statistics_plugin"]
+ path = statistics_plugin
+ url = https://dev.pztrn.name/statistics_plugin.git
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
if (!$ptag) {
$user = User::getKV('id', $id);
- if ($user) {
+
+ if ($user instanceof User) {
$this->clientError(
// TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
// TRANS: %s is a username.
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*/
class ApiAccountVerifyCredentialsAction extends ApiAuthAction
{
+ /**
+ * Handle the request
+ *
+ * Check whether the credentials are valid and output the result
+ *
+ * @return void
+ */
protected function handle()
{
- parent::handle();
+ parent::handle($args);
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return boolean success flag
*
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->user = $this->getTargetUser($this->arg('id'));
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is_read-only=false
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
$this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->scoped), $cursor, $count);
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
{
var $list = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* Grab the file from the 'media' param, then store, and shorten
*
* @todo Upload throttle!
- *
- * @param array $args $_REQUEST data (unused)
- *
* @return void
*/
protected function handle()
{
- parent::handle();
+ parent::handle($args);
// Workaround for PHP returning empty $_POST and $_FILES when POST
// length > post_max_size in php.ini
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean false
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean success
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
common_debug("In apisearchatom handle()");
*
* @return boolean true if nothing goes wrong
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showResults();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
}
*
* @return boolean false if user doesn't exist
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showTrends();
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
/**
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
/**
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$cur = common_current_user();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
return false;
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
common_redirect($url, 302);
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
function defaultReturnTo()
{
$user = common_current_user();
- if ($user) {
+
+ if ($user instanceof User) {
return common_local_url('subscribers',
array('nickname' => $user->nickname));
} else {
{
var $page = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
$this->group = $group;
}
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new GroupBlockListItem($profile, $this->group, $this->action);
}
/**
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (!common_logged_in()) {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
* @fixme merge common setup code with other group actions
* @fixme allow group admins to delete their own groups
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
*
* @return boolean read-only flag (false)
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
/**
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
{
var $page = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
}
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
// @todo XXX: Documentation missing.
class FoafAction extends ManagedAction
{
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
// @todo XXX: Documentation missing.
class FoafGroupAction extends Action
{
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
var $lon = null;
var $location = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$token = $this->trimmed('token');
* @return nothing
*
*/
- function handle($args)
+ function handle(array $args=array())
{
header('Content-Type: application/json; charset=utf-8');
$location_object = array();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
if (!common_logged_in()) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
/** group we're viewing. */
protected $group = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
{
var $page = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
{
var $page = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
// @todo FIXME: documentation missing.
class GroupQueueList extends GroupMemberList
{
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new GroupQueueListItem($profile, $this->group, $this->action);
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
var $page = null;
var $profile = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
if (!common_logged_in()) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
return;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (!common_config('invite', 'enabled')) {
$bestname = $profile->getBestName();
$sitename = common_config('site', 'name');
$personal = $this->trimmed('personal');
+ $language = $this->trimmed('language');
$addresses = explode("\n", $this->trimmed('addresses'));
foreach ($addresses as $email) {
} catch (NoSuchUserException $e) {
// If email was not known, let's send an invite!
$this->sent[] = $email;
- $this->sendInvitation($email, $user, $personal);
+ $this->sendInvitation($email, $user, $personal, $language);
}
}
}
}
- function sendInvitation($email, $user, $personal)
+ function sendInvitation($email, $user, $personal, $language)
{
$profile = $user->getProfile();
$bestname = $profile->getBestName();
$title = (empty($personal)) ? 'invite' : 'invitepersonal';
// @todo FIXME: i18n issue.
- $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths());
+ $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths(), $language);
$body = $inviteTemplate->toHTML(array('inviter' => $bestname,
'inviterurl' => $profile->profileurl,
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
+ /**
+ * Class handler.
+ *
+ * @return nothing
+ */
protected function doPreparation()
{
if (!common_logged_in()) {
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
if (!common_logged_in()) {
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
*
* @return nothing
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
print $user->nickname . ': ' . $notice->content;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
{
protected $q = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->terms = $terms;
}
- function newListItem($notice)
+ function newListItem(Notice $notice)
{
return new SearchNoticeListItem($notice, $this->out, $this->terms);
}
return null;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return nothing
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
}
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean false if user doesn't exist
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$type = $this->trimmed('type');
$this->endXML();
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
var $returnto;
var $lt;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
var $page = null;
var $tag = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
- //common_log(LOG_DEBUG, 'Autocomplete data: ' . json_encode($this->tags));
+ //common_debug('Autocomplete data: ' . json_encode($this->tags));
if ($this->tags) {
print(json_encode($this->tags));
exit(0);
var $peopletag = null;
var $tagger = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
}
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
$this->peopletag = $peopletag;
}
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new PeopletagMemberListItem($profile, $this->peopletag, $this->action);
}
var $tagger = null;
var $tags = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
- # Post from the tag dropdown; redirect to a GET
+ // Post from the tag dropdown; redirect to a GET
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- common_redirect(common_local_url('peopletagsbyuser', $this->getSelfUrlArgs()), 303);
- }
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ common_redirect(common_local_url('peopletagsbyuser', $this->getSelfUrlArgs()), 303);
+ }
$this->showPage();
}
var $page = null;
var $tagged = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
var $peopletag = null;
var $tagger = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
}
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
$this->peopletag = $peopletag;
}
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new PeopletagSubscriberListItem($profile, $this->peopletag, $this->action);
}
var $page = null;
var $profile = null;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
$key = 'disable-' . $this->plugin;
Config::save('plugins', $key, $this->overrideValue());
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
$this->msg = null;
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
common_redirect($this->peopletag->homeUrl(), 303);
}
// nop
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*/
class PublictagcloudAction extends Action
{
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
$this->elementEnd('div');
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
// This should probably be cached rather than recalculated
$tags = new Notice_tag();
- #Need to clear the selection and then only re-add the field
- #we are grouping by, otherwise it's not a valid 'group by'
- #even though MySQL seems to let it slide...
+ /*
+ * Need to clear the selection and then only re-add the field
+ * we are grouping by, otherwise it's not a valid 'group by'
+ * even though MySQL seems to let it slide...
+ */
$tags->selectAdd();
$tags->selectAdd('tag');
+ $tags->selectAdd('notice_id');
+ $tags->selectAdd('scope');
- #Add the aggregated columns...
+ // Add the aggregated columns...
$tags->selectAdd('max(notice_id) as last_notice_id');
$calc = common_sql_weight('created', common_config('tag', 'dropoff'));
$cutoff = sprintf("notice_tag.created > '%s'",
common_sql_date(time() - common_config('tag', 'cutoff')));
$tags->selectAdd($calc . ' as weight');
+ $tags->joinAdd(array('notice_id', 'notice:id'));
$tags->whereAdd($cutoff);
$tags->groupBy('tag');
$tags->orderBy('weight DESC');
$tw = array();
$sum = 0;
while ($tags->fetch()) {
- $tw[$tags->tag] = $tags->weight;
- $sum += $tags->weight;
+ // Check scope:
+ if ($tags->isCurrentProfileInScope()) {
+ $tw[$tags->tag] = $tags->weight;
+ $sum += $tags->weight;
+ }
}
ksort($tw);
var $msg = null;
var $success = null;
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (common_logged_in()) {
* @return boolean read-only flag (false)
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return nothing
*/
- function handle($args)
+ function handle(array $args=array())
{
common_redirect(common_local_url($this->arg('nextAction'), $this->arg('args')));
}
common_redirect($this->file->getUrl(false), 301);
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
if (!$ptag) {
$user = User::getKV('id', $this->tagged->id);
- if ($user) {
+ if ($user instanceof User) {
$this->clientError(
// TRANS: Client error displayed when an unknown error occurs while delisting a user.
// TRANS: %s is a username.
$this->elementEnd('div');
}
- public function isReadOnly($args)
+ public function isReadOnly(array $args=array())
{
return true;
}
return $c;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return nothing
*/
- function handle($args)
+ function handle(array $args=array())
{
header('Content-Type: application/rsd+xml');
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
class SelfTagProfileList extends ProfileList
{
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new SelfTagProfileListItem($profile, $this->action);
}
*
* @return success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
{
var $profile = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
/**
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
// @todo FIXME: documentation needed.
class SupAction extends Action
{
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
return $updates;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
return $c;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*/
class UnblockAction extends ProfileFormAction
{
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*/
class UnsubscribeAction extends Action
{
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (!common_logged_in()) {
* Prepare to run
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
parent::initRss();
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
public static function deleteFromProfile(Profile $target, $original=true) {
try {
$avatars = self::getProfileAvatars($target);
+
foreach ($avatars as $avatar) {
+ assert($avatar instanceof Avatar);
+
if ($avatar->original && !$original) {
continue;
}
+
$avatar->delete();
}
} catch (NoAvatarException $e) {
}
$size = "{$width}x{$height}";
+
if (!isset(self::$_avatars[$target->id])) {
self::$_avatars[$target->id] = array();
} elseif (isset(self::$_avatars[$target->id][$size])){
}
$avatar = null;
+
if (Event::handle('StartProfileGetAvatar', array($target, $width, &$avatar))) {
$avatar = self::pkeyGet(
array(
'height' => $height,
)
);
+
Event::handle('EndProfileGetAvatar', array($target, $width, &$avatar));
}
}
if ($path[0] != '/') {
- $path = '/'.$path;
+ $path = '/' . $path;
}
$server = common_config('avatar', 'server');
try {
return self::byProfile($target, $width, $height)->displayUrl();
} catch (Exception $e) {
+ common_debug(sprintf('target=>id=%s,width=%s,height=%s,message=%s',
+ $target->id,
+ $width,
+ $height,
+ $e->getMessage()
+ ));
return self::defaultImage($width);
}
}
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');
}
static function newSize(Profile $target, $width) {
return null;
}
- static function saveNew($user, $address, $addressType, $extra=null)
+ static function saveNew(User $user, $address, $addressType, $extra=null)
{
$ca = new Confirm_address();
}
}
+ // Debug log (convert crop to int to have TRUE being displayed as 1 and FALSE as 0)
+ /* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: width=' . $width . ',height=' . $height . ',crop=' . intval($crop));
+
return $image->getFileThumbnail($width, $height, $crop);
}
return $out_url;
}
- static function saveNew($data, $file_id, $url) {
+ static function saveNew(array $data, $file_id, $url) {
$file_redir = new File_redirection;
$file_redir->urlhash = File::hashurl($url);
$file_redir->url = $url;
return $this->file;
}
-}
\ No newline at end of file
+}
* @param int $file_id
*/
public static function saveNew($data, $file_id) {
+ // @TODO Must be an object (see below code)
+ assert(is_object($data));
+
if (!empty($data->thumbnail_url)) {
// Non-photo types such as video will usually
// show us a thumbnail, though it's not required.
} else {
$msg = sprintf("DB query (%0.3fs): %s", $delta, $clean);
}
- common_log(LOG_DEBUG, $msg);
+ common_debug($msg);
}
if ($fail) {
* Record the given set of hash tags in the db for this notice.
* Given tag strings will be normalized and checked for dupes.
*/
- function saveKnownTags($hashtags)
+ function saveKnownTags(array $hashtags)
{
//turn each into their canonical tag
//this is needed to remove dupes before saving e.g. #hash.tag = #hashtag
* @return Notice
* @throws ClientException
*/
- static function saveNew($profile_id, $content, $source, array $options=null) {
+ static function saveNew($profile_id, $content, $source, array $options=array()) {
$defaults = array('uri' => null,
'url' => null,
'conversation' => null, // URI of conversation
'object_type' => null,
'verb' => null);
- if (!empty($options) && is_array($options)) {
+ /*
+ * Above type-hint is already array, so simply count it, this saves
+ * "some" CPU cycles.
+ */
+ if (count($options) > 0) {
$options = array_merge($defaults, $options);
- extract($options);
- } else {
- extract($defaults);
}
+ extract($options);
+
if (!isset($is_local)) {
$is_local = Notice::LOCAL_PUBLIC;
}
throw new ClientException(_('You cannot repeat your own notice.'));
}
- if ($repeat->scope != Notice::SITE_SCOPE &&
- $repeat->scope != Notice::PUBLIC_SCOPE) {
+ if ($repeat->isPrivateScope()) {
// TRANS: Client error displayed when trying to repeat a non-public notice.
throw new ClientException(_('Cannot repeat a private notice.'), 403);
}
*
* @return void
*/
- function saveKnownUrls($urls)
+ function saveKnownUrls(array $urls)
{
if (common_config('attachments', 'process_links')) {
// @fixme validation?
return $this->_replies[$this->getID()];
}
- function _setReplies($replies)
+ function _setReplies(array $replies)
{
$this->_replies[$this->getID()] = $replies;
}
}
$groups = User_group::multiGet('id', $ids);
- $this->_groups[$this->id] = $groups->fetchAll();
+ $this->_setGroups($groups->fetchAll());
return $this->_groups[$this->id];
}
- function _setGroups($groups)
+ function _setGroups(array $groups)
{
$this->_groups[$this->id] = $groups;
}
*/
public function getTags()
{
+ // Check default scope (non-private notices)
+ $inScope = (!$this->isPrivateScope());
+
+ // Get current profile
+ $profile = Profile::current();
+
+ // Is the general scope check okay and the user in logged in?
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ',profile[]=' . gettype($profile));
+ if (($inScope === TRUE) && ($profile instanceof Profile)) {
+ /*
+ * Check scope, else a privacy leaks happens this way:
+ *
+ * 1) Bob and Alice follow each other and write private notices
+ * (this->scope=2) to each other.
+ * 2) Bob uses tags in his private notice to alice (which she can
+ * read from him).
+ * 3) Alice adds that notice (with tags) to her favorites
+ * ("faving") it.
+ * 4) The tags from Bob's private notice becomes visible in Alice's
+ * profile.
+ *
+ * This has the simple background that the scope is not being
+ * re-checked. This has to be done here at this point because given
+ * above scenario is a privacy leak as the tags may be *really*
+ * private (nobody else shall see them) such as initmate words or
+ * very political words.
+ */
+ $inScope = $this->inScope($profile);
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ' - After inScope() has been called.');
+ }
+
$tags = array();
$keypart = sprintf('notice:tags:%d', $this->id);
} else {
$tag = new Notice_tag();
$tag->notice_id = $this->id;
- if ($tag->find()) {
+
+ // Check scope for privacy-leak protection (see some lines above why)
+ if (($inScope === TRUE) && ($tag->find())) {
while ($tag->fetch()) {
$tags[] = $tag->tag;
}
*
* @return boolean whether the profile is in the notice's scope
*/
- function inScope($profile)
+ function inScope(Profile $profile=null)
{
if (is_null($profile)) {
$keypart = sprintf('notice:in-scope-for:%d:null', $this->id);
return ($result == 1) ? true : false;
}
- protected function _inScope($profile)
+ protected function _inScope(Profile $profile=null)
{
$scope = is_null($this->scope) ? self::defaultScope() : $this->getScope();
return !$this->isHiddenSpam($profile);
}
- function isHiddenSpam($profile) {
+ function isHiddenSpam(Profile $profile=null) {
// Hide posts by silenced users from everyone but moderators.
return $scope;
}
- static function fillProfiles($notices)
+ static function fillProfiles(array $notices)
{
$map = self::getProfiles($notices);
foreach ($notices as $entry=>$notice) {
return array_values($map);
}
- static function getProfiles(&$notices)
+ static function getProfiles(array &$notices)
{
$ids = array();
foreach ($notices as $notice) {
return Profile::pivotGet('id', $ids);
}
- static function fillGroups(&$notices)
+ static function fillGroups(array &$notices)
{
$ids = self::_idsOf($notices);
$gis = Group_inbox::listGet('notice_id', $ids);
return array_keys($ids);
}
- static function fillAttachments(&$notices)
+ static function fillAttachments(array &$notices)
{
$ids = self::_idsOf($notices);
$f2pMap = File_to_post::listGet('post_id', $ids);
}
}
- static function fillReplies(&$notices)
+ static function fillReplies(array &$notices)
{
$ids = self::_idsOf($notices);
$replyMap = Reply::listGet('notice_id', $ids);
return $url;
}
+
+ /**
+ * Checks whether the current profile is allowed (in scope) to see this tag.
+ *
+ * @return $inScope Whether the current profile is allowed to see this tag
+ */
+ function isCurrentProfileInScope () {
+ // Check scope, default is allowed
+ $inScope = TRUE;
+
+ // 1) Get notice object and set id
+ $notice = new Notice();
+ $notice->id = $this->notice_id;
+
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->notice_id=' . $this->notice_id . ' - Calling find() ... fetch() ...');
+
+ // Fetch notice
+ if ((!$notice->find()) || (!$notice->fetch())) {
+ // No longer valid, so better don't allow to see it
+ return FALSE;
+ }
+
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',notice->id=' . $notice->id . ',notice->scope=' . $notice->scope);
+
+ // Is it private scope?
+ if ($notice->isPrivateScope()) {
+ // 2) Get current profile
+ $profile = Profile::current();
+
+ // Is the profile not set?
+ if (!$profile instanceof Profile) {
+ // Public viewer shall not see a tag from a private dent (privacy leak)
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] Not logged in (public view).');
+ $inScope = FALSE;
+ } elseif (!$notice->inScope($profile)) {
+ // Current profile is not in scope (not allowed to see) of notice
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] profile->id=' . $profile->id . ' is not allowed to see this tag.');
+ $inScope = FALSE;
+ }
+ }
+
+ // Return result
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->weight=' . $this->weight . ',inScope=' . intval($inScope) . ' - EXIT!');
+ return $inScope;
+ }
}
{
if (!isset($this->_profile[$this->profile_id])) {
$profile = Profile::getKV('id', $this->profile_id);
+
if (!$profile instanceof Profile) {
- throw new GroupNoProfileException($this);
+
+ $profile = new Profile();
+ $profile->nickname = $this->nickname;
+ $profile->fullname = $this->fullname;
+ $profile->profileurl = $this->mainpage;
+ $profile->homepage = $this->homepage;
+ $profile->bio = $this->description;
+ $profile->location = $this->location;
+ $profile->created = common_sql_now();
+ $this->profile_id = $profile->insert();
+
+ //throw new GroupNoProfileException($this);
}
+
$this->_profile[$this->profile_id] = $profile;
}
return $this->_profile[$this->profile_id];
* @license GNU Affero General Public License http://www.gnu.org/licenses/
*/
+// Comment in if you have xdebug installed and need a detailed backtrace:
+//xdebug_start_trace();
+
$_startTime = microtime(true);
$_perfCounters = array();
} else {
try {
call_user_func("$action_class::run", $args);
- } catch (ClientException $cex) {
- $cac = new ClientErrorAction($cex->getMessage(), $cex->getCode());
+ } catch (ClientException $e) {
+ $cac = new ClientErrorAction($e->getMessage(), $e->getCode());
$cac->showPage();
- } catch (ServerException $sex) { // snort snort guffaw
- $sac = new ServerErrorAction($sex->getMessage(), $sex->getCode(), $sex);
+ } catch (ServerException $e) { // snort snort guffaw
+ $sac = new ServerErrorAction($e->getMessage(), $e->getCode(), $e);
$sac->showPage();
- } catch (Exception $ex) {
- $sac = new ServerErrorAction($ex->getMessage(), 500, $ex);
+ } catch (Exception $e) {
+ $sac = new ServerErrorAction($e->getMessage(), 500, $e);
$sac->showPage();
}
}
--- /dev/null
+<?php
+
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009-2010, 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/>.
+ *
+ * @category Installation
+ * @package Installation
+ *
+ * @author Adrian Lang <mail@adrianlang.de>
+ * @author Brenda Wallace <shiny@cpan.org>
+ * @author Brett Taylor <brett@webfroot.co.nz>
+ * @author Brion Vibber <brion@pobox.com>
+ * @author CiaranG <ciaran@ciarang.com>
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @author Eric Helgeson <helfire@Erics-MBP.local>
+ * @author Evan Prodromou <evan@status.net>
+ * @author Mikael Nordfeldth <mmn@hethane.se>
+ * @author Robin Millette <millette@controlyourself.ca>
+ * @author Sarven Capadisli <csarven@status.net>
+ * @author Tom Adams <tom@holizz.com>
+ * @author Zach Copley <zach@status.net>
+ * @copyright 2009-2010 StatusNet, Inc http://status.net
+ * @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
+ * @license GNU Affero General Public License http://www.gnu.org/licenses/
+ * @version 1.0.x
+ * @link http://status.net
+ */
+
+abstract class Installer
+{
+ /** Web site info */
+ public $sitename, $server, $path, $fancy, $siteProfile, $ssl;
+ /** DB info */
+ public $host, $database, $dbtype, $username, $password, $db;
+ /** Administrator info */
+ public $adminNick, $adminPass, $adminEmail, $adminUpdates;
+ /** Should we skip writing the configuration file? */
+ public $skipConfig = false;
+
+ public static $dbModules = array(
+ 'mysql' => array(
+ 'name' => 'MySQL',
+ 'check_module' => 'mysqli',
+ 'scheme' => 'mysqli', // DSN prefix for PEAR::DB
+ ),
+ 'pgsql' => array(
+ 'name' => 'PostgreSQL',
+ 'check_module' => 'pgsql',
+ 'scheme' => 'pgsql', // DSN prefix for PEAR::DB
+ ),
+ );
+
+ /**
+ * Attempt to include a PHP file and report if it worked, while
+ * suppressing the annoying warning messages on failure.
+ */
+ private function haveIncludeFile($filename) {
+ $old = error_reporting(error_reporting() & ~E_WARNING);
+ $ok = include_once($filename);
+ error_reporting($old);
+ return $ok;
+ }
+
+ /**
+ * Check if all is ready for installation
+ *
+ * @return void
+ */
+ function checkPrereqs()
+ {
+ $pass = true;
+
+ $config = INSTALLDIR.'/config.php';
+ if (file_exists($config)) {
+ if (!is_writable($config) || filesize($config) > 0) {
+ if (filesize($config) == 0) {
+ $this->warning('Config file "config.php" already exists and is empty, but is not writable.');
+ } else {
+ $this->warning('Config file "config.php" already exists.');
+ }
+ $pass = false;
+ }
+ }
+
+ if (version_compare(PHP_VERSION, '5.3.2', '<')) {
+ $this->warning('Require PHP version 5.3.2 or greater.');
+ $pass = false;
+ }
+
+ $reqs = array('gd', 'curl', 'json',
+ 'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
+
+ foreach ($reqs as $req) {
+ if (!$this->checkExtension($req)) {
+ $this->warning(sprintf('Cannot load required extension: <code>%s</code>', $req));
+ $pass = false;
+ }
+ }
+
+ // Make sure we have at least one database module available
+ $missingExtensions = array();
+ foreach (self::$dbModules as $type => $info) {
+ if (!$this->checkExtension($info['check_module'])) {
+ $missingExtensions[] = $info['check_module'];
+ }
+ }
+
+ if (count($missingExtensions) == count(self::$dbModules)) {
+ $req = implode(', ', $missingExtensions);
+ $this->warning(sprintf('Cannot find a database extension. You need at least one of %s.', $req));
+ $pass = false;
+ }
+
+ // @fixme this check seems to be insufficient with Windows ACLs
+ if (!is_writable(INSTALLDIR)) {
+ $this->warning(sprintf('Cannot write config file to: <code>%s</code></p>', INSTALLDIR),
+ sprintf('On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR));
+ $pass = false;
+ }
+
+ // Check the subdirs used for file uploads
+ $fileSubdirs = array('avatar', 'background', 'file');
+ foreach ($fileSubdirs as $fileSubdir) {
+ $fileFullPath = INSTALLDIR."/$fileSubdir/";
+ if (!is_writable($fileFullPath)) {
+ $this->warning(sprintf('Cannot write to %s directory: <code>%s</code>', $fileSubdir, $fileFullPath),
+ sprintf('On your server, try this command: <code>chmod a+w %s</code>', $fileFullPath));
+ $pass = false;
+ }
+ }
+
+ return $pass;
+ }
+
+ /**
+ * Checks if a php extension is both installed and loaded
+ *
+ * @param string $name of extension to check
+ *
+ * @return boolean whether extension is installed and loaded
+ */
+ function checkExtension($name)
+ {
+ if (extension_loaded($name)) {
+ return true;
+ } elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
+ // dl will throw a fatal error if it's disabled or we're in safe mode.
+ // More fun, it may not even exist under some SAPIs in 5.3.0 or later...
+ $soname = $name . '.' . PHP_SHLIB_SUFFIX;
+ if (PHP_SHLIB_SUFFIX == 'dll') {
+ $soname = "php_" . $soname;
+ }
+ return @dl($soname);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Basic validation on the database paramters
+ * Side effects: error output if not valid
+ *
+ * @return boolean success
+ */
+ function validateDb()
+ {
+ $fail = false;
+
+ if (empty($this->host)) {
+ $this->updateStatus("No hostname specified.", true);
+ $fail = true;
+ }
+
+ if (empty($this->database)) {
+ $this->updateStatus("No database specified.", true);
+ $fail = true;
+ }
+
+ if (empty($this->username)) {
+ $this->updateStatus("No username specified.", true);
+ $fail = true;
+ }
+
+ if (empty($this->sitename)) {
+ $this->updateStatus("No sitename specified.", true);
+ $fail = true;
+ }
+
+ return !$fail;
+ }
+
+ /**
+ * Basic validation on the administrator user paramters
+ * Side effects: error output if not valid
+ *
+ * @return boolean success
+ */
+ function validateAdmin()
+ {
+ $fail = false;
+
+ if (empty($this->adminNick)) {
+ $this->updateStatus("No initial user nickname specified.", true);
+ $fail = true;
+ }
+ if ($this->adminNick && !preg_match('/^[0-9a-z]{1,64}$/', $this->adminNick)) {
+ $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
+ '" is invalid; should be plain letters and numbers no longer than 64 characters.', true);
+ $fail = true;
+ }
+ // @fixme hardcoded list; should use Nickname::isValid()
+ // if/when it's safe to have loaded the infrastructure here
+ $blacklist = array('main', 'panel', 'twitter', 'settings', 'rsd.xml', 'favorited', 'featured', 'favoritedrss', 'featuredrss', 'rss', 'getfile', 'api', 'groups', 'group', 'peopletag', 'tag', 'user', 'message', 'conversation', 'bookmarklet', 'notice', 'attachment', 'search', 'index.php', 'doc', 'opensearch', 'robots.txt', 'xd_receiver.html', 'facebook');
+ if (in_array($this->adminNick, $blacklist)) {
+ $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
+ '" is reserved.', true);
+ $fail = true;
+ }
+
+ if (empty($this->adminPass)) {
+ $this->updateStatus("No initial user password specified.", true);
+ $fail = true;
+ }
+
+ return !$fail;
+ }
+
+ /**
+ * Make sure a site profile was selected
+ *
+ * @return type boolean success
+ */
+ function validateSiteProfile()
+ {
+ if (empty($this->siteProfile)) {
+ $this->updateStatus("No site profile selected.", true);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Set up the database with the appropriate function for the selected type...
+ * Saves database info into $this->db.
+ *
+ * @fixme escape things in the connection string in case we have a funny pass etc
+ * @return mixed array of database connection params on success, false on failure
+ */
+ function setupDatabase()
+ {
+ if ($this->db) {
+ throw new Exception("Bad order of operations: DB already set up.");
+ }
+ $this->updateStatus("Starting installation...");
+
+ if (empty($this->password)) {
+ $auth = '';
+ } else {
+ $auth = ":$this->password";
+ }
+ $scheme = self::$dbModules[$this->dbtype]['scheme'];
+ $dsn = "{$scheme}://{$this->username}{$auth}@{$this->host}/{$this->database}";
+
+ $this->updateStatus("Checking database...");
+ $conn = $this->connectDatabase($dsn);
+
+ // ensure database encoding is UTF8
+ if ($this->dbtype == 'mysql') {
+ // @fixme utf8m4 support for mysql 5.5?
+ // Force the comms charset to utf8 for sanity
+ // This doesn't currently work. :P
+ //$conn->executes('set names utf8');
+ } else if ($this->dbtype == 'pgsql') {
+ $record = $conn->getRow('SHOW server_encoding');
+ if ($record->server_encoding != 'UTF8') {
+ $this->updateStatus("GNU social requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
+ return false;
+ }
+ }
+
+ $res = $this->updateStatus("Creating database tables...");
+ if (!$this->createCoreTables($conn)) {
+ $this->updateStatus("Error creating tables.", true);
+ return false;
+ }
+
+ foreach (array('sms_carrier' => 'SMS carrier',
+ 'notice_source' => 'notice source',
+ 'foreign_services' => 'foreign service')
+ as $scr => $name) {
+ $this->updateStatus(sprintf("Adding %s data to database...", $name));
+ $res = $this->runDbScript($scr.'.sql', $conn);
+ if ($res === false) {
+ $this->updateStatus(sprintf("Can't run %s script.", $name), true);
+ return false;
+ }
+ }
+
+ $db = array('type' => $this->dbtype, 'database' => $dsn);
+ return $db;
+ }
+
+ /**
+ * Open a connection to the database.
+ *
+ * @param <type> $dsn
+ * @return <type>
+ */
+ function connectDatabase($dsn)
+ {
+ global $_DB;
+ return $_DB->connect($dsn);
+ }
+
+ /**
+ * Create core tables on the given database connection.
+ *
+ * @param DB_common $conn
+ */
+ function createCoreTables(DB_common $conn)
+ {
+ $schema = Schema::get($conn);
+ $tableDefs = $this->getCoreSchema();
+ foreach ($tableDefs as $name => $def) {
+ if (defined('DEBUG_INSTALLER')) {
+ echo " $name ";
+ }
+ $schema->ensureTable($name, $def);
+ }
+ return true;
+ }
+
+ /**
+ * Fetch the core table schema definitions.
+ *
+ * @return array of table names => table def arrays
+ */
+ function getCoreSchema()
+ {
+ $schema = array();
+ include INSTALLDIR . '/db/core.php';
+ return $schema;
+ }
+
+ /**
+ * Return a parseable PHP literal for the given value.
+ * This will include quotes for strings, etc.
+ *
+ * @param mixed $val
+ * @return string
+ */
+ function phpVal($val)
+ {
+ return var_export($val, true);
+ }
+
+ /**
+ * Return an array of parseable PHP literal for the given values.
+ * These will include quotes for strings, etc.
+ *
+ * @param mixed $val
+ * @return array
+ */
+ function phpVals($map)
+ {
+ return array_map(array($this, 'phpVal'), $map);
+ }
+
+ /**
+ * Write a stock configuration file.
+ *
+ * @return boolean success
+ *
+ * @fixme escape variables in output in case we have funny chars, apostrophes etc
+ */
+ function writeConf()
+ {
+ $vals = $this->phpVals(array(
+ 'sitename' => $this->sitename,
+ 'server' => $this->server,
+ 'path' => $this->path,
+ 'ssl' => in_array($this->ssl, array('never', 'sometimes', 'always'))
+ ? $this->ssl
+ : 'never',
+ 'db_database' => $this->db['database'],
+ 'db_type' => $this->db['type']
+ ));
+
+ // assemble configuration file in a string
+ $cfg = "<?php\n".
+ "if (!defined('GNUSOCIAL')) { exit(1); }\n\n".
+
+ // site name
+ "\$config['site']['name'] = {$vals['sitename']};\n\n".
+
+ // site location
+ "\$config['site']['server'] = {$vals['server']};\n".
+ "\$config['site']['path'] = {$vals['path']}; \n\n".
+ "\$config['site']['ssl'] = {$vals['ssl']}; \n\n".
+
+ // checks if fancy URLs are enabled
+ ($this->fancy ? "\$config['site']['fancy'] = true;\n\n":'').
+
+ // database
+ "\$config['db']['database'] = {$vals['db_database']};\n\n".
+ ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
+ "\$config['db']['type'] = {$vals['db_type']};\n\n";
+
+ // Normalize line endings for Windows servers
+ $cfg = str_replace("\n", PHP_EOL, $cfg);
+
+ // write configuration file out to install directory
+ $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);
+
+ return $res;
+ }
+
+ /**
+ * Write the site profile. We do this after creating the initial user
+ * in case the site profile is set to single user. This gets around the
+ * 'chicken-and-egg' problem of the system requiring a valid user for
+ * single user mode, before the intial user is actually created. Yeah,
+ * we should probably do this in smarter way.
+ *
+ * @return int res number of bytes written
+ */
+ function writeSiteProfile()
+ {
+ $vals = $this->phpVals(array(
+ 'site_profile' => $this->siteProfile,
+ 'nickname' => $this->adminNick
+ ));
+
+ $cfg =
+ // site profile
+ "\$config['site']['profile'] = {$vals['site_profile']};\n";
+
+ if ($this->siteProfile == "singleuser") {
+ $cfg .= "\$config['singleuser']['nickname'] = {$vals['nickname']};\n\n";
+ } else {
+ $cfg .= "\n";
+ }
+
+ // Normalize line endings for Windows servers
+ $cfg = str_replace("\n", PHP_EOL, $cfg);
+
+ // write configuration file out to install directory
+ $res = file_put_contents(INSTALLDIR.'/config.php', $cfg, FILE_APPEND);
+
+ return $res;
+ }
+
+ /**
+ * Install schema into the database
+ *
+ * @param string $filename location of database schema file
+ * @param DB_common $conn connection to database
+ *
+ * @return boolean - indicating success or failure
+ */
+ function runDbScript($filename, DB_common $conn)
+ {
+ $sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename));
+ $stmts = explode(';', $sql);
+ foreach ($stmts as $stmt) {
+ $stmt = trim($stmt);
+ if (!mb_strlen($stmt)) {
+ continue;
+ }
+ try {
+ $res = $conn->simpleQuery($stmt);
+ } catch (Exception $e) {
+ $error = $e->getMessage();
+ $this->updateStatus("ERROR ($error) for SQL '$stmt'");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Create the initial admin user account.
+ * Side effect: may load portions of GNU social framework.
+ * Side effect: outputs program info
+ */
+ function registerInitialUser()
+ {
+ require_once INSTALLDIR . '/lib/common.php';
+
+ $data = array('nickname' => $this->adminNick,
+ 'password' => $this->adminPass,
+ 'fullname' => $this->adminNick);
+ if ($this->adminEmail) {
+ $data['email'] = $this->adminEmail;
+ }
+ $user = User::register($data);
+
+ if (empty($user)) {
+ return false;
+ }
+
+ // give initial user carte blanche
+
+ $user->grantRole('owner');
+ $user->grantRole('moderator');
+ $user->grantRole('administrator');
+
+ // Attempt to do a remote subscribe to update@status.net
+ // Will fail if instance is on a private network.
+
+ if ($this->adminUpdates && class_exists('Ostatus_profile')) {
+ try {
+ $oprofile = Ostatus_profile::ensureProfileURL('http://update.status.net/');
+ Subscription::start($user->getProfile(), $oprofile->localProfile());
+ $this->updateStatus("Set up subscription to <a href='http://update.status.net/'>update@status.net</a>.");
+ } catch (Exception $e) {
+ $this->updateStatus("Could not set up subscription to <a href='http://update.status.net/'>update@status.net</a>.", true);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * The beef of the installer!
+ * Create database, config file, and admin user.
+ *
+ * Prerequisites: validation of input data.
+ *
+ * @return boolean success
+ */
+ function doInstall()
+ {
+ global $config;
+
+ $this->updateStatus("Initializing...");
+ ini_set('display_errors', 1);
+ error_reporting(E_ALL);
+ if (!defined('GNUSOCIAL')) {
+ define('GNUSOCIAL', true);
+ }
+ if (!defined('STATUSNET')) {
+ define('STATUSNET', true);
+ }
+
+ require_once INSTALLDIR . '/lib/framework.php';
+ StatusNet::initDefaults($this->server, $this->path);
+
+ if ($this->siteProfile == "singleuser") {
+ // Until we use ['site']['profile']==='singleuser' everywhere
+ $config['singleuser']['enabled'] = true;
+ }
+
+ try {
+ $this->db = $this->setupDatabase();
+ if (!$this->db) {
+ // database connection failed, do not move on to create config file.
+ return false;
+ }
+ } catch (Exception $e) {
+ // Lower-level DB error!
+ $this->updateStatus("Database error: " . $e->getMessage(), true);
+ return false;
+ }
+
+ // Make sure we can write to the file twice
+ $oldUmask = umask(000);
+
+ if (!$this->skipConfig) {
+ $this->updateStatus("Writing config file...");
+ $res = $this->writeConf();
+
+ if (!$res) {
+ $this->updateStatus("Can't write config file.", true);
+ return false;
+ }
+ }
+
+ if (!empty($this->adminNick)) {
+ // Okay, cross fingers and try to register an initial user
+ if ($this->registerInitialUser()) {
+ $this->updateStatus(
+ "An initial user with the administrator role has been created."
+ );
+ } else {
+ $this->updateStatus(
+ "Could not create initial user account.",
+ true
+ );
+ return false;
+ }
+ }
+
+ if (!$this->skipConfig) {
+ $this->updateStatus("Setting site profile...");
+ $res = $this->writeSiteProfile();
+
+ if (!$res) {
+ $this->updateStatus("Can't write to config file.", true);
+ return false;
+ }
+ }
+
+ // Restore original umask
+ umask($oldUmask);
+ // Set permissions back to something decent
+ chmod(INSTALLDIR.'/config.php', 0644);
+
+ $scheme = $this->ssl === 'always' ? 'https' : 'http';
+ $link = "{$scheme}://{$this->server}/{$this->path}";
+
+ $this->updateStatus("GNU social has been installed at $link");
+ $this->updateStatus(
+ '<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the mailing list and <a href="http://gnu.io/resources/">good documentation</a>.'
+ );
+
+ return true;
+ }
+
+ /**
+ * Output a pre-install-time warning message
+ * @param string $message HTML ok, but should be plaintext-able
+ * @param string $submessage HTML ok, but should be plaintext-able
+ */
+ abstract function warning($message, $submessage='');
+
+ /**
+ * Output an install-time progress message
+ * @param string $message HTML ok, but should be plaintext-able
+ * @param boolean $error true if this should be marked as an error condition
+ */
+ abstract function updateStatus($status, $error=false);
+
+}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
public $selfLink; // <link rel='self' type='application/atom+xml'>
public $editLink; // <link rel='edit' type='application/atom+xml'>
public $generator; // ActivityObject representing the generating application
+
/**
* Turns a regular old Atom <entry> into a magical activity
*
// Is the recipient a remote group?
$oprofile = Ostatus_profile::ensureProfileURI($recipient);
- if ($oprofile) {
+ if ($oprofile instanceof Ostatus_profile) {
if (!$oprofile->isGroup()) {
// may be canonicalized or something
$replies[] = $oprofile->uri;
if ($id) {
$group = User_group::getKV('id', $id);
- if ($group) {
+ if ($group instanceof User_group) {
// Deliver to all members of this local group if allowed.
- $profile = $sender->localProfile();
- if ($profile->isMember($group)) {
+ $profile = Profile::getKV('id', $recipient);
+
+ if (($profile instanceof Profile) && ($profile->isMember($group))) {
$groups[] = $group->id;
} else {
common_log(LOG_INFO, "Skipping reply to local group {$group->nickname} as sender {$profile->id} is not a member");
return false;
}
- static function getFeedAuthor($feedEl)
+ static function getFeedAuthor(DOMElement $feedEl)
{
// Try old and deprecated activity:subject
return null;
}
- static function compareTypes($type, $objects)
+ static function compareTypes($type, array $objects)
{
$type = self::resolveUri($type);
- foreach ((array)$objects as $object) {
+ foreach ($objects as $object) {
if ($type === self::resolveUri($object)) {
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->checkSessionToken();
{
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
*
* @return boolean false
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
function showListStart()
{
- $this->out->elementStart('ol', array('class' => 'attachments'));
+ $this->out->elementStart('div', array('class' => 'attachments'));
}
function showListEnd()
{
- $this->out->elementEnd('ol');
+ $this->out->elementEnd('div');
}
/**
$scripts[] = $script;
}
foreach ($scripts as $script) {
- common_log(LOG_DEBUG, $script->textContent);
+ common_debug($script->textContent);
$script->parentNode->removeChild($script);
}
function getTags()
{
$notice_tag = new Notice_tag;
- $query = 'select tag,count(tag) as weight from notice_tag join file_to_post on (notice_tag.notice_id=post_id) join notice on notice_id = notice.id where file_id=' . $notice_tag->escape($this->out->attachment->id) . ' group by tag order by weight desc';
+ $query = 'select tag, notice_id, count(tag) as weight from notice_tag join file_to_post on (notice_tag.notice_id=post_id) join notice on notice_id = notice.id where file_id=' . $notice_tag->escape($this->out->attachment->id) . ' group by tag order by weight desc';
$notice_tag->query($query);
return $notice_tag;
}
'delete' => false,
'move' => true),
'image' =>
- array('jpegquality' => 85),
+ array('jpegquality' => 95),
'avatar' =>
array('server' => null,
'dir' => INSTALLDIR . '/avatar/',
array('server' => null,
'dir' => INSTALLDIR . '/file/',
'path' => $_path . '/file/',
+ 'chmod' => 0644, // Access rights (chmod) for any attachments
'sslserver' => null,
'sslpath' => null,
'ssl' => null,
$this->filename = $filename;
}
- static function forTitle($title, $paths)
+ static function forTitle($title, array $paths, $language=null)
{
- if (!is_array($paths)) {
- $paths = array($paths);
- }
-
$filename = null;
if (Event::handle('StartDocFileForTitle', array($title, &$paths, &$filename))) {
}
if (!empty($lang) || !empty($def)) {
- $filename = self::negotiateLanguage($lang, $def);
+ $filename = self::negotiateLanguage($lang, $def, $language);
break;
}
}
}
}
- function toHTML($args=null)
+ function toHTML(array $args=array())
{
- if (is_null($args)) {
- $args = array();
- }
-
if (empty($this->contents)) {
$this->contents = file_get_contents($this->filename);
}
INSTALLDIR.'/doc-src/');
$site = GNUsocial::currentSite();
-
+
if (!empty($site)) {
array_unshift($paths, INSTALLDIR.'/local/doc-src/'.$site.'/');
}
INSTALLDIR.'/mail-src/');
$site = GNUsocial::currentSite();
-
+
if (!empty($site)) {
array_unshift($paths, INSTALLDIR.'/local/mail-src/'.$site.'/');
}
return $paths;
}
- static function negotiateLanguage($filenames, $defaultFilename=null)
+ private static function negotiateLanguage(array $filenames, $defaultFilename=null, $language = null)
{
- // XXX: do this better
-
+ // Default is current language
$langcode = common_language();
+ // Is a language set?
+ if (!empty($language)) {
+ // And is it valid?
+ if (common_valid_language($language)) {
+ // Use this as language (e.g. from form)
+ $langcode = strval($language);
+ }
+ }
+
foreach ($filenames as $filename) {
if (preg_match('/\.'.$langcode.'$/', $filename)) {
return $filename;
return true;
}
- public function isReadOnly($args) {
+ public function isReadOnly(array $args=array()) {
return !$this->isPost();
}
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
-define('GNUSOCIAL_CODENAME', 'Not decided yet');
+define('GNUSOCIAL_CODENAME', 'Only a fixed bug is a good bug.');
define('AVATAR_PROFILE_SIZE', 96);
define('AVATAR_STREAM_SIZE', 48);
return GNUsocial::haveConfig();
}
+function common_get_temp_dir()
+{
+ // Try to get it from php.ini first
+ $temp_path = trim(ini_get('upload_tmp_dir'));
+
+ // Is it empty?
+ if (strlen($temp_path) == 0) {
+ // Then try sys_get_temp_dir()
+ $temp_path = trim(sys_get_temp_dir());
+
+ // Still empty?
+ if (strlen($temp_path) == 0) {
+ // Then set it to /tmp (ugly)
+ // @TODO Hard-coded non-Windows stuff!
+ $temp_path = '/tmp';
+ }
+ }
+
+ // Return found path
+ return $temp_path;
+}
+
function GNUsocial_class_autoload($cls)
{
if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) {
}
}
+
// Autoload function queue, starting with our own discovery method
spl_autoload_register('GNUsocial_class_autoload');
$this->out->elementEnd('div');
- if ($user) {
+ if ($user instanceof User) {
$this->out->elementStart('div', 'entity_actions');
$this->out->elementStart('ul');
$this->out->elementStart('li', 'entity_subscribe');
$this->group = $group;
}
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new GroupMemberListItem($profile, $this->group, $this->action);
}
$namestring = implode(',', $quoted);
- $qry = 'SELECT notice_tag.tag, '.
+ $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
$weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' .
$info = @getimagesize($this->filepath);
- if (!(
- ($info[2] == IMAGETYPE_GIF && function_exists('imagecreatefromgif')) ||
- ($info[2] == IMAGETYPE_JPEG && function_exists('imagecreatefromjpeg')) ||
- $info[2] == IMAGETYPE_BMP ||
- ($info[2] == IMAGETYPE_WBMP && function_exists('imagecreatefromwbmp')) ||
- ($info[2] == IMAGETYPE_XBM && function_exists('imagecreatefromxbm')) ||
- ($info[2] == IMAGETYPE_PNG && function_exists('imagecreatefrompng')))) {
+ if (
+ ($info[2] == IMAGETYPE_GIF && !function_exists('imagecreatefromgif')) ||
+ ($info[2] == IMAGETYPE_JPEG && !function_exists('imagecreatefromjpeg')) ||
+ ($info[2] == IMAGETYPE_WBMP && !function_exists('imagecreatefromwbmp')) ||
+ ($info[2] == IMAGETYPE_XBM && !function_exists('imagecreatefromxbm')) ||
+ ($info[2] == IMAGETYPE_PNG && !function_exists('imagecreatefrompng'))) {
// TRANS: Exception thrown when trying to upload an unsupported image file format.
throw new UnsupportedMediaException(_('Unsupported image format.'), $this->filepath);
if ($this->rotate == 0) {
// No rotational difference, just copy it as-is
@copy($this->filepath, $outpath);
+
+ // And set chmod
+ @chmod($outpath, common_config('attachments', 'chmod'));
return $outpath;
} elseif (abs($this->rotate) == 90) {
// Box is rotated 90 degrees in either direction,
throw new Exception(_('Unknown file type'));
}
+ // Always chmod 0644 (default) to have other processes (e.g. queue daemon read it)
+ @chmod($outpath, common_config('attachments', 'chmod'));
+
imagedestroy($image_src);
imagedestroy($image_dest);
}
*
* @return boolean hook return
*/
- function onEndInitializeQueueManager($manager)
+ function onEndInitializeQueueManager(QueueManager $manager)
{
// If we don't require CLI mode, or if we do and GNUSOCIAL_CLI _is_ set, then connect the transports
// This check is made mostly because some IM plugins can't deliver to transports unless they
return true;
}
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
$profile = Profile::getKV($notice->profile_id);
$weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
// @fixme should we use the cutoff too? Doesn't help with indexing per-user.
- $qry = 'SELECT notice_tag.tag, '.
+ $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
$weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' .
return empty($this->title) ? '' : $this->title;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
}
}
- if (!$conn instanceof DB_common) {
+ if (!is_object($conn)) {
+ // No object at all
+ throw new Exception('Fatal error: conn is no object.');
+ } elseif (!$conn instanceof DB_common) {
// Is not the right instance
throw new Exception('Cannot connect to database: ' . $conn->getMessage());
}
function formData()
{
$this->out->elementStart('ul', 'form_data');
+
$this->out->elementStart('li');
$this->out->textarea(
'addresses',
_('Addresses of friends to invite (one per line).')
);
$this->out->elementEnd('li');
+
$this->out->elementStart('li');
$this->out->textarea(
// TRANS: Field label for a personal message to send to invitees.
_('Optionally add a personal message to the invitation.')
);
$this->out->elementEnd('li');
+
+ $language = common_language();
+
+ $this->out->elementStart('li');
+ $this->out->dropdown('language', _('Language'),
+ // TRANS: Tooltip for dropdown list label in form for profile settings.
+ get_nice_language_list(), _('Preferred language.'),
+ false, $language);
+ $this->out->elementEnd('li');
+
$this->out->elementEnd('ul');
}
if ($timeout > 0 && empty($sockets)) {
// If we had no listeners, sleep until the pollers' next requested wakeup.
- common_log(LOG_DEBUG, "Sleeping $timeout seconds until next poll cycle...");
+ common_debug("Sleeping $timeout seconds until next poll cycle...");
$this->logState('sleep');
sleep($timeout);
}
}
} else if (common_config('queue', 'debug_memory')) {
$fmt = number_format($usage);
- common_log(LOG_DEBUG, "Memory usage $fmt");
+ common_debug("Memory usage $fmt");
}
}
}
$this->out->elementStart('ul', $attrs);
foreach ($items as $item) {
+ assert(is_array($item));
+ assert(count($item) == 5);
+
list($actionName, $args, $label, $description, $id) = $item;
+
$this->item($actionName, $args, $label, $description, $id);
}
-
+
$this->out->elementEnd('ul');
-
+
Event::handle('EndNav', array($this, $tag, $items));
}
}
-
+
function item($actionName, array $args, $label, $description, $id=null, $cls=null)
{
if (empty($id)) {
{
if ($actionName != $this->actionName) {
return false;
+ } elseif (!is_array($args)) {
+ /*
+ * No array, then the below loop doesn't need to run and
+ * 'return false' will never be reached.
+ */
+ return true;
}
foreach ($this->actionArgs as $k => $v) {
return true;
}
-
+
function menuItemID($actionName, $args = null)
{
$id = sprintf('nav_%s', $actionName);
-
+
if (!is_null($args)) {
foreach ($args as $key => $value) {
$id .= '_' . $key . '_' . $value;
* 'location_id' ID of location
* 'location_ns' Namespace of location
*/
- function __construct($action, $options=null)
+ function __construct(Action $action, array $options = array())
{
parent::__construct($action);
// When creating a notice form we don't want to collide with
// possibly existing HTML elements, as naming conventions are similar.
- $this->id_suffix = rand();
-
- if (is_null($options)) {
- $options = array();
- }
+ $this->id_suffix = mt_rand();
$this->actionName = $action->trimmed('action');
'type' => 'checkbox',
'class' => 'checkbox',
'id' => $this->id() . '-notice_data-geo',
- 'checked' => true, // ?
+ 'checked' => false, // Must be unchecked by default
));
$this->out->element('label', array('class' => 'notice_data-geo',
'for' => $this->id().'-notice_data-geo'),
{
if (Event::handle('StartShowNoticeOptions', array($this))) {
$user = common_current_user();
- if ($user) {
+
+ if ($user instanceof User) {
$this->out->elementStart('div', 'notice-options');
if (Event::handle('StartShowNoticeOptionItems', array($this))) {
$this->showReplyLink();
}
$this->out->elementEnd('div');
}
+
Event::handle('EndShowNoticeOptions', array($this));
}
}
$weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
// @fixme should we use the cutoff too? Doesn't help with indexing per-user.
- $qry = 'SELECT notice_tag.tag, '.
+ $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
$weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' .
}
}
- function newListItem($plugin)
+ function newListItem(Plugin $plugin)
{
return new PluginListItem($plugin, $this->out);
}
return $this->target;
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
// TRANS: H2 text for user statistics.
$this->element('h2', null, _('Statistics'));
- $profile = $this->target;
- $actionParams = array('nickname' => $profile->nickname);
+ $actionParams = array('nickname' => $this->target->nickname);
$stats = array(
array(
'id' => 'user-id',
// TRANS: Label for user statistics.
'label' => _('User ID'),
- 'value' => $profile->id,
+ 'value' => $this->target->id,
),
array(
'id' => 'member-since',
// TRANS: Label for user statistics.
'label' => _('Member since'),
- 'value' => date('j M Y', strtotime($profile->created))
+ 'value' => date('j M Y', strtotime($this->target->created))
),
array(
'id' => 'notices',
);
// Give plugins a chance to add stats entries
- Event::handle('ProfileStats', array($profile, &$stats));
+ Event::handle('ProfileStats', array($this->target, &$stats));
foreach ($stats as $row) {
$this->showStatsRow($row);
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
// @fixme should we use the cutoff too? Doesn't help with indexing per-user.
- $qry = 'SELECT notice_tag.tag, '.
+ $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
$weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' .
/**
* URL Router
*
- * Cheap wrapper around Net_URL_Mapper
+ * Cheap wrapper around URLMapper
*
* @category URL
* @package StatusNet
foreach (array('profile', 'avatar', 'password', 'im', 'oauthconnections',
'oauthapps', 'email', 'sms', 'url') as $s) {
- $m->connect('settings/'.$s, array('action' => $s.'settings'));
+ $m->connect('settings/' . $s, array('action' => $s . 'settings'));
}
if (common_config('oldschool', 'enabled')) {
// The second of these is needed to make the link work correctly
// when inserted into the page. The first is needed to match the
- // route on the way in. Seems to be another Net_URL_Mapper bug to me.
+ // route on the way in. Seems to be another URLMapper bug to me.
$m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
array('q' => '.+'));
$m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
}
$url = $this->m->generate($args, $params, $fragment);
- // Due to a bug in the Net_URL_Mapper code, the returned URL may
+ // Due to a bug in the URLMapper code, the returned URL may
// contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We
// repair that here rather than modifying the upstream code...
foreach ($this->tables as $table => $def) {
$checksum = $this->checksum($def);
if (empty($checksums[$table])) {
- common_log(LOG_DEBUG, "No previous schema_version for $table: updating to $checksum");
+ common_debug("No previous schema_version for $table: updating to $checksum");
} else if ($checksums[$table] == $checksum) {
- common_log(LOG_DEBUG, "Last schema_version for $table up to date: $checksum");
+ common_debug("Last schema_version for $table up to date: $checksum");
continue;
} else {
- common_log(LOG_DEBUG, "Last schema_version for $table is {$checksums[$table]}: updating to $checksum");
+ common_debug("Last schema_version for $table is {$checksums[$table]}: updating to $checksum");
}
//$this->conn->query('BEGIN');
$this->schema->ensureTable($table, $def);
return $checksums;
} catch (Exception $e) {
// no dice!
- common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
+ common_debug("Possibly schema_version table doesn't exist yet.");
}
return $checksums;
}
} catch (Exception $e) {
// no dice!
- common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
+ common_debug("Possibly schema_version table doesn't exist yet.");
}
$this->checksums[$table] = $checksum;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
function showContent()
{
$tags = $this->getTags();
+ //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] tags[]=' . gettype($tags));
if (!$tags) {
// TRANS: Content displayed in a tag cloud section if there are no tags.
$sum = 0;
while ($tags->fetch() && ++$cnt <= TAGS_PER_SECTION) {
- $tw[$tags->tag] = $tags->weight;
- $sum += $tags->weight;
+ if ($tags->isCurrentProfileInScope()) {
+ $tw[$tags->tag] = $tags->weight;
+ $sum += $tags->weight;
+ }
}
if ($cnt == 0) {
*
* Converts a path into a set of parameters, and vice versa
*
- * We used to use Net_URL_Mapper, so there's a wrapper class at Router, q.v.
+ * We used to use URLMapper, so there's a wrapper class at Router, q.v.
*
* NUM's vagaries are the main reason we have weirdnesses here.
*
--- /dev/null
+<?php
+error_reporting(E_ALL );
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Superclass(Version2) for plugins that do URL shortening
+ *
+ * PHP version >= 5.2
+ *
+ * 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 Craig Andrews <candrews@integralblue.com>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://gnu.io
+ */
+define("STATUSNET", 1);
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+ exit(1);
+}
+
+
+/**
+ * Class to handle Plugin exceptions
+ *
+ * @category Exception
+ * @package StatusNet
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://gnu.io
+ */
+class PluginErrorException extends Exception {
+ protected $severity=0;
+ /**
+ * Setup costumizable Exceptions
+ * @var array $HTML Codes for Exceptionlists(see PluginErrorException::getFull())
+ */
+ protected $HTML=array(
+ 'code'=>array("start"=>'<code>', "end"=>'</code'),
+ 'ulist'=>array("start"=>'<ul>', "end"=>'</ul>' ),
+ 'list'=>array("start"=>"<li>", "end"=>"</li>"));
+ /**
+ * Create specific extension for PluginExceptions
+ * @
+ */
+ public function __construct($message, $code, $severity, $filename, $lineno, $HTML='') {
+ $this->message = $message;
+ $this->code = $code;
+ $this->severity = $severity;
+ $this->file = $filename;
+ $this->line = $lineno;
+ }
+
+ public function getSeverity() {
+ return $this->severity;
+ }
+ public function printFull() {
+ echo "Catched Exception: <ul><br />";
+ echo "<li>Message: <code>".$this->getMessage()."</code></li> ";
+ echo "<li>Code: <code>".$this->getCode()."</code></li> ";
+ echo "<li>Line: <code>".$this->getLine()."</code></li> ";
+ echo "<li>File: <code>".$this->getFile()."</code></li> ";
+ echo "<li>Severity: <code>".$this->getSeverity()."</code></li>";
+ echo "</ul><p>Code: 0 means an uncatched Exception, triggered ";
+ echo "by PHP's parsing. This is probally an Syntax-Error.</p> ";
+ }
+}
+/* Do done some exceptionrelated things done, befor
+ * we can start coding the real.
+ */
+function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ throw new PluginErrorException($errstr, 0, $errno, $errfile, $errline);
+}
+
+/* the Exceptionhandler for Syntax-Errors, throwed by PHP itself */
+/**
+ * Superclass for plugins that perform a url shortening
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://darksider3.de/sn/urlshortenerplugin2.html
+ */
+
+abstract class UrlShortenerPlugin2
+{
+ public $shortenerName;
+ public $freeService = true;
+ /**
+ * Make an URL shorter.
+ *
+ * @param string $url URL to shorten
+ *
+ * @return string shortened version of the url/Null/Error
+ * @todo dont support old "shorten", name it to "shortUrl" to get well-named code.
+ */
+ protected abstract function shorten($url);
+
+
+ /**
+ * Utility to get the data at an URL
+ *
+ * @param string $url URL to fetch
+ * @exception PluginErrorExcpetion $e If HTTPClient throws an exception, print out.
+ * @return string response body
+ * @todo throw an exception in HTTPClient and make the PluginErrorException more generally
+ * so that we can use it more then ones, in every libfile.
+ */
+ protected function httpGet($url)
+ {
+ try
+ {
+ $request = HTTPClient::start();
+ $response = $request->get($url);
+ } catch(PluginErrorException $e)
+ {
+ $e->printFull();
+ return false;
+ }
+ return $response->getBody();
+ }
+ /**
+ * Utility to post a request and get a response URL
+ *
+ * @param string $url URL to fetch
+ * @param array $data post parameters
+ *
+ * @return string response body
+ *
+ */
+ protected function httpPost($url, $data)
+ {
+
+ $request = HTTPClient::start();
+ $response = $request->post($url, null, $data);
+ return $response->getBody();
+ }
+ // Hook handlers
+
+ /**
+ * Called when all plugins have been initialized
+ *
+ * @return boolean hook value
+ */
+
+ function onInitializePlugin()
+ {
+ if (!isset($this->shortenerName))
+ {
+ throw new Exception("@Admin must specifiy $this->shortenerName");
+ }
+ return true;
+ }
+ /**
+ * Called when a showing the URL shortener drop-down box
+ *
+ * Properties of the shortening service currently only
+ * include whether it's a free service.
+ *
+ * @param array &$shorteners array mapping shortener name to properties
+ *
+ * @return boolean hook value
+ */
+ function onGetUrlShorteners(&$shorteners)
+ {
+ $shorteners[$this->shortenerName] =array('freeService' => $this->freeService);
+ return true;
+ }
+
+ /**
+ * Called to shorten an URL
+ *
+ * @param string $url URL to shorten
+ * @param string $shortenerName Shortening service. Don't handle if it's
+ * not you!
+ * @param string &$shortenedUrl URL after shortening; out param.
+ *
+ * @return boolean hook value
+ */
+
+ function onStartShortenUrl($url, $shortenerName, &$shortenedUrl)
+ {
+ if ($shortenerName == $this->shortenerName)
+ {
+ $result = $this->shorten($url);
+ if (isset($result) && $result != null && $result !== false)
+ {
+ $shortenedUrl = $result;
+ //dont create an exception, so we can do that without.
+ common_log(LOG_INFO,
+ __CLASS__ . ": $this->shortenerName ".
+ "shortened $url to $shortenedUrl");
+ return false;
+ }
+ }
+ return true;
+ }
+}
+?>
return false;
}
- if ($user) {
+ if ($user instanceof User) {
if (Event::handle('StartSetUser', array(&$user))) {
if (!empty($user)) {
if (!$user->hasRight(Right::WEBLOGIN)) {
if ($user === false) {
$user = common_current_user();
}
- if ($user) {
+ if ($user instanceof User) {
return crc32($user->id . ':' . $user->nickname);
} else {
return '0';
$_perfCounters[$key] = array($val);
}
if (common_config('site', 'logperf_detail')) {
- common_log(LOG_DEBUG, "PERF COUNTER HIT: $key $val");
+ common_debug("PERF COUNTER HIT: $key $val");
}
}
}
if (isset($_startTime)) {
$endTime = microtime(true);
$diff = round(($endTime - $_startTime) * 1000);
- common_log(LOG_DEBUG, "PERF runtime: ${diff}ms");
+ common_debug("PERF runtime: ${diff}ms");
}
$counters = $_perfCounters;
ksort($counters);
foreach ($counters as $key => $values) {
$count = count($values);
$unique = count(array_unique($values));
- common_log(LOG_DEBUG, "PERF COUNTER: $key $count ($unique unique)");
+ common_debug("PERF COUNTER: $key $count ($unique unique)");
}
}
}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for APC variable cache
+ *
+ * PHP version 5
+ *
+ * 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 Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 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/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use APC's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses APC's variable cache.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 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/
+ */
+
+class APCPlugin extends Plugin
+{
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheGet(&$key, &$value)
+ {
+ $value = apc_fetch($key);
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag (passed through to Memcache)
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
+
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $success = apc_delete($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'APC',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:APC',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
+ return true;
+ }
+}
common_local_url('AccountManagementControlDocument'));
}
- function onStartShowHTML($action)
+ function onStartShowHTML(Action $action)
{
//Account management discovery link
header('Link: <'.common_local_url('AccountManagementControlDocument').'>; rel="'. AccountManagerPlugin::AM_REL.'"; type="application/json"');
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
return true;
}
- function onNoticeDeleteRelated($notice) {
+ function onNoticeDeleteRelated(Notice $notice) {
$score = Spam_score::getKV('notice_id', $notice->id);
if (!empty($score)) {
$score->delete();
return true;
}
- function onUserRightsCheck($profile, $right, &$result) {
+ function onUserRightsCheck(Profile $profile, $right, &$result) {
switch ($right) {
case self::REVIEWSPAM:
case self::TRAINSPAM:
return true;
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->element('style', null,
'.form-train-spam input.submit { background: url('.$this->path('icons/bullet_black.png').') no-repeat 0px 0px } ' . "\n" .
* MAY override
*
* @param array $args other arguments
- *
* @return boolean is read only action?
*/
-
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
public $score; // float
public $created; // datetime
- function saveNew($notice, $result) {
+ function saveNew(Notice $notice, $result) {
$score = new Spam_score();
-a --all All users
END_OF_SILENCESPAMMER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function testAllUsers($filter, $minimum, $percent) {
$found = false;
-a --all All users
END_OF_TESTUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function testAllUsers($filter) {
$found = false;
END_OF_TRAINUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function trainUser($filter, $user, $category) {
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin for Google Adsense
+ *
+ * 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 Ads
+ * @package StatusNet
+ * @author Evan Prodromou <evan@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);
+}
+
+/**
+ * Plugin to add Google Adsense to StatusNet sites
+ *
+ * This plugin lets you add Adsense ad units to your StatusNet site.
+ *
+ * We support the 4 ad sizes for the Universal Ad Platform (UAP):
+ *
+ * Medium Rectangle
+ * (Small) Rectangle
+ * Leaderboard
+ * Wide Skyscraper
+ *
+ * They fit in different places on the default theme. Some themes
+ * might interact quite poorly with this plugin.
+ *
+ * To enable advertising, you must sign up with Google Adsense and
+ * get a client ID.
+ *
+ * https://www.google.com/adsense/
+ *
+ * You'll also need to create an Adsense for Content unit in one
+ * of the four sizes described above. At the end of the process,
+ * note the "google_ad_client" and "google_ad_slot" values in the
+ * resultant Javascript.
+ *
+ * Add the plugin to config.php like so:
+ *
+ * addPlugin('Adsense', array('client' => 'Your client ID',
+ * 'rectangle' => 'slot'));
+ *
+ * Here, your client ID is the value of google_ad_client and the
+ * slot is the value of google_ad_slot. Note that if you create
+ * a different size, you'll need to provide different arguments:
+ * 'mediumRectangle', 'leaderboard', or 'wideSkyscraper'.
+ *
+ * If for some reason your ad server is different from the default,
+ * use the 'adScript' parameter to set the full path to the ad script.
+ *
+ * @category Plugin
+ * @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/
+ *
+ * @seeAlso UAPPlugin
+ */
+class AdsensePlugin extends UAPPlugin
+{
+ public $adScript = 'http://pagead2.googlesyndication.com/pagead/show_ads.js';
+ public $client = null;
+
+ function initialize()
+ {
+ parent::initialize();
+
+ // A little bit of chicanery so we avoid overwriting values that
+ // are passed in with the constructor
+ foreach (array('mediumRectangle', 'rectangle', 'leaderboard', 'wideSkyscraper', 'adScript', 'client') as $setting) {
+ $value = common_config('adsense', strtolower($setting));
+ if (!empty($value)) { // not found
+ $this->$setting = $value;
+ }
+ }
+ }
+
+ /**
+ * Show a medium rectangle 'ad'
+ *
+ * @param Action $action Action being shown
+ *
+ * @return void
+ */
+ protected function showMediumRectangle($action)
+ {
+ $this->showAdsenseCode($action, 300, 250, $this->mediumRectangle);
+ }
+
+ /**
+ * Show a rectangle 'ad'
+ *
+ * @param Action $action Action being shown
+ *
+ * @return void
+ */
+ protected function showRectangle($action)
+ {
+ $this->showAdsenseCode($action, 180, 150, $this->rectangle);
+ }
+
+ /**
+ * Show a wide skyscraper ad
+ *
+ * @param Action $action Action being shown
+ *
+ * @return void
+ */
+ protected function showWideSkyscraper($action)
+ {
+ $this->showAdsenseCode($action, 160, 600, $this->wideSkyscraper);
+ }
+
+ /**
+ * Show a leaderboard ad
+ *
+ * @param Action $action Action being shown
+ *
+ * @return void
+ */
+ protected function showLeaderboard($action)
+ {
+ $this->showAdsenseCode($action, 728, 90, $this->leaderboard);
+ }
+
+ /**
+ * Output the bits of JavaScript code to show Adsense
+ *
+ * @param Action $action Action being shown
+ * @param integer $width Width of the block
+ * @param integer $height Height of the block
+ * @param string $slot Slot identifier
+ *
+ * @return void
+ */
+ protected function showAdsenseCode($action, $width, $height, $slot)
+ {
+ $code = 'google_ad_client = "'.$this->client.'"; ';
+ $code .= 'google_ad_slot = "'.$slot.'"; ';
+ $code .= 'google_ad_width = '.$width.'; ';
+ $code .= 'google_ad_height = '.$height.'; ';
+
+ $action->inlineScript($code);
+
+ $action->script($this->adScript);
+ }
+
+ function onRouterInitialized(URLMapper $m)
+ {
+ $m->connect('panel/adsense',
+ array('action' => 'adsenseadminpanel'));
+
+ return true;
+ }
+
+ function onEndAdminPanelNav(Menu $menu) {
+ if (AdminPanelAction::canAdmin('adsense')) {
+ // TRANS: Menu item title/tooltip
+ $menu_title = _m('AdSense configuration');
+ // TRANS: Menu item for site administration
+ $menu->out->menuItem(common_local_url('adsenseadminpanel'), _m('MENU','AdSense'),
+ $menu_title, $action_name == 'adsenseadminpanel', 'nav_adsense_admin_panel');
+ }
+ return true;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'BlankAdPlugin',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:Adsense',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('Plugin to add Google AdSense to StatusNet sites.'));
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Send and receive notices using the AIM network
+ *
+ * PHP version 5
+ *
+ * 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 IM
+ * @package StatusNet
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+// We bundle the phptoclib library...
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phptoclib');
+
+/**
+ * Plugin for AIM
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+class AimPlugin extends ImPlugin
+{
+ public $user = null;
+ public $password = null;
+ public $publicFeed = array();
+
+ public $transport = 'aim';
+
+ function getDisplayName()
+ {
+ // TRANS: Display name.
+ return _m('AIM');
+ }
+
+ function normalize($screenname)
+ {
+ $screenname = str_replace(" ","", $screenname);
+ return strtolower($screenname);
+ }
+
+ function daemonScreenname()
+ {
+ return $this->user;
+ }
+
+ function validate($screenname)
+ {
+ if(preg_match('/^[a-z]\w{2,15}$/i', $screenname)) {
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * Load related modules when needed
+ *
+ * @param string $cls Name of the class to be loaded
+ *
+ * @return boolean hook value; true means continue processing, false means stop.
+ */
+ function onAutoload($cls)
+ {
+ $dir = dirname(__FILE__);
+
+ switch ($cls)
+ {
+ case 'Aim':
+ require_once(INSTALLDIR.'/plugins/Aim/extlib/phptoclib/aimclassw.php');
+ return false;
+ }
+
+ return parent::onAutoload($cls);
+ }
+
+ function onStartImDaemonIoManagers(&$classes)
+ {
+ parent::onStartImDaemonIoManagers($classes);
+ $classes[] = new AimManager($this); // handles sending/receiving
+ return true;
+ }
+
+ function microiduri($screenname)
+ {
+ return 'aim:' . $screenname;
+ }
+
+ function sendMessage($screenname, $body)
+ {
+ $this->fake_aim->sendIm($screenname, $body);
+ $this->enqueueOutgoingRaw($this->fake_aim->would_be_sent);
+ return true;
+ }
+
+ /**
+ * Accept a queued input message.
+ *
+ * @return true if processing completed, false if message should be reprocessed
+ */
+ function receiveRawMessage($message)
+ {
+ $info=Aim::getMessageInfo($message);
+ $from = $info['from'];
+ $user = $this->getUser($from);
+ $notice_text = $info['message'];
+
+ $this->handleIncoming($from, $notice_text);
+
+ return true;
+ }
+
+ function initialize(){
+ if(!isset($this->user)){
+ // TRANS: Exception thrown in AIM plugin when user has not been specified.
+ throw new Exception(_m('Must specify a user.'));
+ }
+ if(!isset($this->password)){
+ // TRANS: Exception thrown in AIM plugin when password has not been specified.
+ throw new Exception(_m('Must specify a password.'));
+ }
+
+ $this->fake_aim = new Fake_Aim($this->user,$this->password,4);
+ return true;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'AIM',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Craig Andrews',
+ 'homepage' => 'http://status.net/wiki/Plugin:AIM',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('The AIM plugin allows users to send and receive notices over the AIM network.'));
+ return true;
+ }
+}
--- /dev/null
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+
+/**
+ * AIM background connection manager for AIM-using queue handlers,
+ * allowing them to send outgoing messages on the right connection.
+ *
+ * Input is handled during socket select loop, keepalive pings during idle.
+ * Any incoming messages will be handled.
+ *
+ * In a multi-site queuedaemon.php run, one connection will be instantiated
+ * for each site being handled by the current process that has XMPP enabled.
+ */
+class AimManager extends ImManager
+{
+ public $conn = null;
+ /**
+ * Initialize connection to server.
+ * @return boolean true on success
+ */
+ public function start($master)
+ {
+ if(parent::start($master))
+ {
+ $this->connect();
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ public function getSockets()
+ {
+ $this->connect();
+ if($this->conn){
+ return array($this->conn->myConnection);
+ }else{
+ return array();
+ }
+ }
+
+ /**
+ * Process AIM events that have come in over the wire.
+ * @param resource $socket
+ */
+ public function handleInput($socket)
+ {
+ common_debug("Servicing the AIM queue.");
+ $this->stats('aim_process');
+ $this->conn->receive();
+ }
+
+ function connect()
+ {
+ if (!$this->conn) {
+ $this->conn=new Aim($this->plugin->user,$this->plugin->password,4);
+ $this->conn->registerHandler("IMIn",array($this,"handle_aim_message"));
+ $this->conn->myServer="toc.oscar.aol.com";
+ $this->conn->signon();
+ // @todo i18n FIXME: Update translator documentation, please.
+ // TRANS: No idea what the use case for this message is.
+ $this->conn->setProfile(_m('Send me a message to post a notice'),false);
+ }
+ return $this->conn;
+ }
+
+ function handle_aim_message($data)
+ {
+ $this->plugin->enqueueIncomingRaw($data);
+ return true;
+ }
+
+ function send_raw_message($data)
+ {
+ $this->connect();
+ if (!$this->conn) {
+ return false;
+ }
+ $this->conn->sflapSend($data[0],$data[1],$data[2],$data[3]);
+ return true;
+ }
+}
// that anonymous faving is allowed for all users.
public $restricted = array();
- function onArgsInitialize() {
+ function onArgsInitialize(array &$args) {
// We always want a session because we're tracking anon users
common_ensure_session();
}
return true;
}
- function onEndShowHTML($action)
+ function onEndShowHTML(Action $action)
{
if (!common_logged_in()) {
// Set a place to return to when submitting forms
}
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
// Setup ajax calls for favoriting. Usually this is only done when
// a user is logged in.
$action->inlineScript('SN.U.NoticeFavor();');
}
- function onStartInitializeRouter($m)
+ function onStartInitializeRouter(URLMapper $m)
{
$m->connect('main/anonfavor', array('action' => 'AnonFavor'));
$m->connect('main/anondisfavor', array('action' => 'AnonDisFavor'));
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$notice = new Notice();
$notice->find();
// 0.1 will check about 10% of hits, etc.
public $frequency = 1.0;
- function onArgsInitialize($args)
+ function onArgsInitialize(array &$args)
{
if (isset($args['action'])) {
$action = strtolower($args['action']);
parent::__construct();
}
- function onEndShowScripts($action){
+ function onEndShowScripts(Action $action){
if (common_logged_in()) {
$action->element('span', array('id' => 'autocomplete-api',
'data-url' => common_local_url('autocomplete')));
}
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('main/autocomplete/suggest', array('action'=>'autocomplete'));
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
/**
* Add the bit.ly admin panel to the list...
*/
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('bitly')) {
$action_name = $nav->action->trimmed('action');
*
* @return boolean hook value
*/
- function onStartRegisterUser(&$user, &$profile)
+ function onStartRegisterUser(User &$user, Profile &$profile)
{
$homepage = strtolower($profile->homepage);
*
* @return boolean hook value
*/
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('blacklist')) {
return true;
}
- function onEndDeleteUserForm($action, $user)
+ function onEndDeleteUserForm(Action $action, User $user)
{
$cur = common_current_user();
$action->elementEnd('ul');
}
- function onEndDeleteUser($action, $user)
+ function onEndDeleteUser(Action $action, User $user)
{
if ($action->boolean('blacklisthomepage')) {
$pattern = $action->trimmed('blacklisthomepagepattern');
return true;
}
- function checkboxAndText($action, $checkID, $label, $textID, $value)
+ private function checkboxAndText(Action $action, $checkID, $label, $textID, $value)
{
$action->element('input', array('name' => $checkID,
'type' => 'checkbox',
return $hostname;
}
- function onStartHandleFeedEntry($activity)
+ function onStartHandleFeedEntry(Activity $activity)
{
return $this->_checkActivity($activity);
}
- function onStartHandleSalmon($activity)
+ function onStartHandleSalmon(Activity $activity)
{
return $this->_checkActivity($activity);
}
- function _checkActivity($activity)
+ function _checkActivity(Activity $activity)
{
$actor = $activity->actor;
}
}
- function onStartNoticeSave($notice)
+ function onStartNoticeSave(Notice $notice)
{
$args = $this->testArgs($notice);
common_debug("Blogspamnet args = " . print_r($args, TRUE));
*
* @return boolean hook value
*/
- function onUserRightsCheck($profile, $right, &$result)
+ function onUserRightsCheck(Profile $profile, $right, &$result)
{
if ($right == self::IMPORTDELICIOUS) {
$result = !$profile->isSilenced();
*
* @return boolean hook value
*/
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink($this->path('css/bookmark.css'));
return true;
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script($this->path('js/bookmark.js'));
return true;
*
* @return boolean hook value
*/
- function onEndInitializeQueueManager($qm)
+ function onEndInitializeQueueManager(QueueManager $qm)
{
$qm->connect('dlcsback', 'DeliciousBackupImporter');
$qm->connect('dlcsbkmk', 'DeliciousBookmarkImporter');
*
* @return boolean hook value
*/
- function onEndProfileSettingsActions($action)
+ function onEndProfileSettingsActions(Action $action)
{
$user = common_current_user();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showTimeline();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
* Handler method
*
* @param array $args is ignored since it's now passed in in prepare()
- *
* @return void
*/
-
- function handle($args=null)
+ function handle(array $args=array())
{
$this->startHTML('text/xml;charset=utf-8');
$this->elementStart('head');
* MAY override
*
* @param array $args other arguments
- *
* @return boolean is read only action?
*/
-
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$nickname = $this->returnToArgs();
$nickname = $nickname[1]['nickname'];
}
-
+
$this->user = User::getKV('nickname', $nickname);
if (!$this->user) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*/
class BookmarksrssAction extends TargetedRss10Action
{
+<<<<<<< .merge_file_wVLYTY
protected function getNotices()
+=======
+ /** The user whose bookmarks to display */
+
+ var $user = null;
+
+ /**
+ * Find the user to display by supplied nickname
+ *
+ * @param array $args Arguments from $_REQUEST
+ *
+ * @return boolean success
+ */
+ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $nickname = $this->trimmed('nickname');
+ $this->user = User::getKV('nickname', $nickname);
+
+ if (!$this->user) {
+ // TRANS: Client error displayed when trying to get the RSS feed with bookmarks of a user that does not exist.
+ $this->clientError(_('No such user.'));
+ } else {
+ $this->notices = $this->getNotices($this->limit);
+ return true;
+ }
+ }
+
+ /**
+ * Get notices
+ *
+ * @param integer $limit max number of notices to return
+ *
+ * @return array notices
+ */
+ function getNotices($limit=0)
+>>>>>>> .merge_file_BfWnQY
{
$stream = new BookmarksNoticeStream($this->target->getID(), true);
return $stream->getNotices(0, $this->limit)->fetchAll();
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return !$this->isPost();
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return Bookmark The found bookmark object.
* @throws NoResultException When you don't find it after all.
*/
+<<<<<<< .merge_file_5dZvDX
static public function fromStored(Notice $stored)
{
return self::getByPK(array('uri' => $stored->getUri()));
}
public function getStored()
+=======
+ static function getByNotice(Notice $notice)
+>>>>>>> .merge_file_cVGSQX
{
return Notice::getByKeys(array('uri' => $this->getUri()));
}
*
* @return Bookmark the Bookmark object
*/
+<<<<<<< .merge_file_5dZvDX
static function saveActivityObject(ActivityObject $actobj, Notice $stored)
+=======
+ static function saveNew(Profile $profile, $title, $url, $rawtags, $description,
+ array $options=array())
+>>>>>>> .merge_file_cVGSQX
{
$url = null;
// each extra element is array('tagname', array('attr'=>'val', ...), 'content')
throw new ClientException(sprintf(_m('Expected exactly 1 link rel=related in a Bookmark, got %1$d.'), count($relLinkEls)));
}
+<<<<<<< .merge_file_5dZvDX
if (!strlen($actobj->title)) {
throw new ClientException(_m('You must provide a non-empty title.'));
}
if (!common_valid_http_url($url)) {
throw new ClientException(_m('Only web bookmarks can be posted (HTTP or HTTPS).'));
+=======
+ if (array_key_exists('uri', $options)) {
+ $other = Bookmark::getKV('uri', $options['uri']);
+ if (!empty($other)) {
+ // TRANS: Client exception thrown when trying to save a new bookmark that already exists.
+ throw new ClientException(_m('Bookmark already exists.'));
+ }
+>>>>>>> .merge_file_cVGSQX
}
try {
-f --file file to read from (STDIN by default)
END_OF_IMPORTBOOKMARKS_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
/**
* Get the bookmarks file as a string
return parent::onAutoload($cls);
}
- function onArgsInitialize(&$args)
+ function onArgsInitialize(array &$args)
{
if($this->takeOverLogin && $args['action'] == 'login')
{
}
}
- function onStartInitializeRouter($m)
+ function onStartInitializeRouter(URLMapper $m)
{
$m->connect('main/cas', array('action' => 'caslogin'));
return true;
}
- function onEndLoginGroupNav($action)
+ function onEndLoginGroupNav(Action $action)
{
$action_name = $action->trimmed('action');
return true;
}
- function onEndShowPageNotice($action)
+ function onEndShowPageNotice(Action $action)
{
$name = $action->trimmed('action');
class CasloginAction extends Action
{
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (common_is_real_login()) {
parent::__construct();
}
- function onEndShowScripts($action){
+ function onEndShowScripts(Action $action){
if (common_logged_in()) {
$user = common_current_user();
$action->inlineScript('var maxNoticeLength = ' . User_urlshortener_prefs::maxNoticeLength($user));
}
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
if (common_logged_in()) {
$m->connect('plugins/ClientSideShorten/shorten', array('action'=>'shorten'));
{
private $text;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->groups=array();
return true;
}
- function handle($args=null)
+ function handle(array $args=array())
{
parent::handle($args);
header('Content-Type: text/plain');
*
* @return NoticeListItem a list item to show
*/
- function newListItem($notice)
+ function newListItem(Notice $notice)
{
return new ConversationTreeItem($notice, $this->out);
}
return true;
}
- public function onProfileDeleteRelated(Profile $profile, &$related)
+ public function onProfileDeleteRelated(Profile $profile, array &$related)
{
$msg = new Message();
$msg->from_profile = $profile->id;
*
* @return boolean success flag
*/
+<<<<<<< .merge_file_m7N4pd
protected function prepare(array $args=array())
+=======
+ function prepare(array $args=array())
+>>>>>>> .merge_file_lMcE3c
{
parent::prepare($args);
return true;
}
+<<<<<<< .merge_file_m7N4pd
protected function handle()
+=======
+ /**
+ * Handle the request
+ *
+ * Show the messages
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+ function handle(array $args=array())
+>>>>>>> .merge_file_lMcE3c
{
parent::handle();
$this->showMessages();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
$this->showPage();
}
$this->elementEnd('ul');
}
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
$msg->from_profile = $from;
$msg->to_profile = $to;
- if ($user) {
+
+ if ($user instanceof User) {
// Use the sender's URL shortening options.
$msg->content = $user->shortenLinks($content);
} else {
$msg->content = common_shorten_links($content);
}
+
$msg->rendered = common_render_text($msg->content);
$msg->created = common_sql_now();
$msg->source = $source;
class InboxMessageList extends MessageList
{
+<<<<<<< .merge_file_NIw5Kk
function newItem($message)
+=======
+ var $page = null;
+
+ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $nickname = common_canonical_nickname($this->arg('nickname'));
+ $this->user = User::getKV('nickname', $nickname);
+ $this->page = $this->trimmed('page');
+
+ if (!$this->page) {
+ $this->page = 1;
+ }
+
+ common_set_returnto($this->selfUrl());
+
+ return true;
+ }
+
+ /**
+ * output page based on arguments
+ *
+ * @param array $args HTTP arguments (from $_REQUEST)
+ *
+ * @return void
+ */
+ function handle(array $args=array())
+ {
+ parent::handle($args);
+
+ if (!$this->user) {
+ // TRANS: Client error displayed when trying to access a mailbox without providing a user.
+ $this->clientError(_('No such user.'), 404);
+ }
+
+ $cur = common_current_user();
+
+ if (!$cur || $cur->id != $this->user->id) {
+ // TRANS: Client error displayed when trying to access a mailbox that is not of the logged in user.
+ $this->clientError(_('Only the user can read their own mailboxes.'), 403);
+ }
+
+ $this->showPage();
+ }
+
+ function showNoticeForm()
+ {
+ $message_form = new MessageForm($this);
+ $message_form->show();
+ }
+
+ function showContent()
+ {
+ $message = $this->getMessages();
+
+ if ($message) {
+
+ $ml = $this->getMessageList($message);
+
+ $cnt = $ml->show();
+
+ $this->pagination($this->page > 1,
+ $cnt > MESSAGES_PER_PAGE,
+ $this->page,
+ $this->trimmed('action'),
+ array('nickname' => $this->user->nickname));
+ } else {
+ $this->element('p',
+ 'guide',
+ // TRANS: Message displayed when there are no private messages in the inbox of a user.
+ _('You have no private messages. '.
+ 'You can send private message to engage other users in conversation. '.
+ 'People can send you messages for your eyes only.'));
+ }
+ }
+
+ function getMessages()
+ {
+ return null;
+ }
+
+ function getMessageList($message)
+ {
+ return null;
+ }
+
+ /**
+ * Show the page notice
+ *
+ * Shows instructions for the page
+ *
+ * @return void
+ */
+ function showPageNotice()
+ {
+ $instr = $this->getInstructions();
+ $output = common_markup_to_html($instr);
+
+ $this->elementStart('div', 'instructions');
+ $this->raw($output);
+ $this->elementEnd('div');
+ }
+
+ /**
+ * Mailbox actions are read only
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean
+ */
+ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+
+ function showObjectNav()
+>>>>>>> .merge_file_WapUGk
{
return new InboxMessageListItem($this->out, $message);
}
*
* @param object $notice notice is going to be saved
*/
- public function onStartNoticeSave($notice){
+ public function onStartNoticeSave(Notice $notice){
// don't use getRendered() here since it's not saved yet and thus can't ->update in case that would happen
if(!preg_match('/<span class="rtl">/', $notice->rendered) && self::isRTL($notice->content))
$notice->rendered = '<span class="rtl">'.$notice->rendered.'</span>';
* @param string $content
* @return boolean
*/
- public static function isRTL($content){
+ public static function isRTL($content) {
$content = self::getClearText($content);
$words = explode(' ', $content);
$rtl = 0;
* @param string $str
* @return boolean
*/
- public static function startsWithRTLCharacter($str){
+ public static function startsWithRTLCharacter($str ){
if (strlen($str) < 1) {
return false;
}
* @param string $str
* @return string
*/
- private static function getClearText($str){
+ private static function getClearText($str) {
$str = preg_replace('/@[^ ]+|![^ ]+|#[^ ]+/u', '', $str); // reply, tag, group
$str = preg_replace('/^RT[: ]{1}| RT | RT: |^RD[: ]{1}| RD | RD: |[♺♻:]/u', '', $str); // redent, retweet
$str = preg_replace("/[ \r\t\n]+/", ' ', trim($str)); // remove spaces
*
* @param Action $action
*/
- function onEndShowScripts($action){
+ function onEndShowScripts(Action $action){
if (common_logged_in()) {
$action->script($this->path('jquery.DirectionDetector.js'));
}
$m->connect(
'directory/users/:filter/sort_by/:sort/reverse/:reverse',
array('action' => 'userdirectory'),
- array('filter' => '[0-9a-zA-Z]|(0-9)'),
+ array('filter' => '[0-9a-zA-Z]|(0-9)'),
array('sort' => '[a-z]+'),
- array('reverse' => '[0-9]')
+ array('reverse' => '[0-9]')
);
$m->connect(
'directory/users/:filter/sort_by/:sort',
array('action' => 'userdirectory'),
- array('filter' => '[0-9a-zA-Z]|(0-9)'),
- array('sort' => '[a-z]+')
- );
-
+ array('filter' => '[0-9a-zA-Z]|(0-9)'),
+ array('sort' => '[a-z]+')
+ );
$m->connect(
'directory/users/:filter',
array('action' => 'userdirectory'),
array('filter' => '[0-9a-zA-Z]|(0-9)')
);
-
+
$m->connect(
'directory/users/sort_by/:sort/reverse/:reverse',
array('action' => 'userdirectory'),
array('sort' => '[a-z]+'),
- array('reverse' => '[0-9]')
+ array('reverse' => '[0-9]')
);
$m->connect(
'directory/users/sort_by/:sort',
array('action' => 'userdirectory'),
- array('sort' => '[a-z]+')
- );
+ array('sort' => '[a-z]+')
+ );
$m->connect(
'directory/users',
array('action' => 'groupdirectory')
);
-
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
$this->out->elementStart('tbody');
}
+<<<<<<< .merge_file_3awMBt
function newListItem(Profile $profile)
+=======
+ function newListItem(Profile $profile, $odd)
+>>>>>>> .merge_file_0Q1cxt
{
return new SortableGroupListItem($profile, $this->owner, $this->action);
}
function showJoinButton()
{
$user = $this->owner;
- if ($user) {
+ if ($user instanceof User) {
$this->out->elementStart('li', 'entity_subscribe');
// XXX: special-case for user looking at own
// subscriptions page
$this->out->elementEnd('table');
}
+<<<<<<< .merge_file_0ePMGB
function newListItem(Profile $profile)
+=======
+ function showProfiles()
+ {
+ // Note: we don't use fetchAll() because it's borked with query()
+
+ $profiles = array();
+
+ while ($this->profile->fetch()) {
+ $profiles[] = clone($this->profile);
+ }
+
+ $cnt = count($profiles);
+
+ $max = min($cnt, $this->maxProfiles());
+
+ for ($i = 0; $i < $max; $i++) {
+ $odd = ($i % 2 == 0); // for zebra striping
+ $pli = $this->newListItem($profiles[$i], $odd);
+ $pli->show();
+ }
+
+ return $cnt;
+ }
+
+ function newListItem(Profile $profile, $odd)
+>>>>>>> .merge_file_vaqBzB
{
return new SortableSubscriptionListItem($profile, $this->owner, $this->action);
}
return true;
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
if (common_config('globalapi', 'enabled')) {
foreach (array('register', 'login', 'recover') as $method) {
* @return boolean continuation flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
GNUsocial::setApi(true); // reduce exception reports to aid in debugging
END_OF_INSTALLFOREMAIL_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$email = $args[0];
END_OF_SITEFORDOMAIN_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$domain = DomainStatusNetworkPlugin::toDomain($args[0]);
END_OF_SITEFORDOMAIN_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$domain = DomainStatusNetworkPlugin::toDomain($args[0]);
*
* @return boolean hook flag
*/
- function onEndShowStatusNetScripts($action) {
+ public function onEndShowStatusNetScripts(Action $action) {
$name = $action->arg('action');
if ($name == 'invite') {
$action->script($this->getPath() . '/js/whitelistinvite.js');
return true;
}
- function onRequireValidatedEmailPlugin_Override($user, &$knownGood)
+ public function onRequireValidatedEmailPlugin_Override(User $user, &$knownGood)
{
$knownGood = (!empty($user->email) && $this->matchesWhitelist($user->email));
return true;
}
- function onEndValidateUserEmail($user, $email, &$valid)
+ // @TODO Most callers are given NULL as first argument
+ public function onEndValidateUserEmail($user, $email, &$valid)
{
if ($valid) { // it's otherwise valid
if (!$this->matchesWhitelist($email)) {
return true;
}
- function onStartAddEmailAddress($user, $email)
+ public function onStartAddEmailAddress(User $user, $email)
{
if (!$this->matchesWhitelist($email)) {
// TRANS: Exception thrown when an e-mail address does not match the site's domain whitelist.
{
const CONFIRMTYPE = 'register';
- function onArgsInitialize(&$args)
+ function onArgsInitialize(array &$args)
{
if (array_key_exists('action', $args) && $args['action'] == 'register') {
// YOINK!
$dir = dirname(__FILE__);
// @todo FIXME: i18n issue.
- $docFile = DocFile::forTitle($title, $dir.'/doc-src/');
+ $docFile = DocFile::forTitle($title, array($dir . '/doc-src/'));
if (!empty($docFile)) {
$output = $docFile->toHTML();
mail_send($recipients, $headers, $body);
}
- function onEndDocFileForTitle($title, $paths, &$filename)
+ function onEndDocFileForTitle($title, array $paths, &$filename)
{
if ($title == 'confirmemailreg' && empty($filename)) {
$filename = dirname(__FILE__).'/mail-src/'.$title;
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
END_OF_REGISTEREMAILUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) == 0) {
show_help();
END_OF_REGISTEREMAILUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) == 0) {
show_help();
*
* @return boolean hook value
*/
- function onEndInitializeQueueManager($qm)
+ function onEndInitializeQueueManager(QueueManager $qm)
{
$qm->connect('siterem', 'SiteConfirmReminderHandler');
$qm->connect('uregrem', 'UserConfirmRegReminderHandler');
return true;
}
- function onEndDocFileForTitle($title, $paths, &$filename)
+ function onEndDocFileForTitle($title, array $paths, &$filename)
{
if (empty($filename)) {
$filename = dirname(__FILE__) . '/mail-src/' . $title;
* Send a real live email reminder
*
* @todo This would probably be better as two or more sep functions
+ * @todo Add language support?
*
* @param string $type type of reminder
* @param mixed $object Confirm_address or Invitation object
END_OF_SENDEMAILREMINDER_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
$quiet = have_option('q', 'quiet');
*
* @return boolean hook value
*/
- function onEndInitializeQueueManager($qm)
+ function onEndInitializeQueueManager(QueueManager $qm)
{
$qm->connect('sitesum', 'SiteEmailSummaryHandler');
$qm->connect('usersum', 'UserEmailSummaryHandler');
END_OF_SENDEMAILSUMMARY_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('u', 'universe')) {
$sn = new Status_network();
{
switch ($notice->object_type) {
case Happening::OBJECT_TYPE:
- common_log(LOG_DEBUG, "Deleting event from notice...");
+ common_debug("Deleting event from notice...");
$happening = Happening::fromNotice($notice);
$happening->delete();
break;
case RSVP::POSITIVE:
case RSVP::NEGATIVE:
case RSVP::POSSIBLE:
- common_log(LOG_DEBUG, "Deleting rsvp from notice...");
+ common_debug("Deleting rsvp from notice...");
$rsvp = RSVP::fromNotice($notice);
- common_log(LOG_DEBUG, "to delete: $rsvp->id");
+ common_debug("to delete: $rsvp->id");
$rsvp->delete();
break;
default:
- common_log(LOG_DEBUG, "Not deleting related, wtf...");
+ common_debug("Not deleting related, wtf...");
}
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script($this->path('js/event.js'));
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink($this->path('css/event.css'));
return true;
$notice = $this->rsvp->getNotice();
// NB: this will delete the rsvp, too
if (!empty($notice)) {
+<<<<<<< .merge_file_GZsuBh
common_log(LOG_DEBUG, "Deleting notice...");
$notice->deleteAs($this->scoped);
+=======
+ common_debug("Deleting notice...");
+ $notice->delete();
+>>>>>>> .merge_file_6baWxh
} else {
- common_log(LOG_DEBUG, "Deleting RSVP alone...");
+ common_debug("Deleting RSVP alone...");
$this->rsvp->delete();
}
} catch (ClientException $ce) {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean true
*/
- function prepare($args) {
+ function prepare(array $args=array()) {
parent::prepare($args);
$this->start = $this->arg('start');
$this->duration = $this->boolean('duration', false);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
);
}
- static function saveNew($profile, $start_time, $end_time, $title, $location, $description, $url, $options=array())
+ static function saveNew(Profile $profile, $start_time, $end_time, $title, $location, $description, $url, array $options=array())
{
if (array_key_exists('uri', $options)) {
$other = Happening::getKV('uri', $options['uri']);
return Notice::getKV('uri', $this->getUri());
}
- static function fromNotice($notice)
+ static function fromNotice(Notice $notice)
{
return Happening::getKV('uri', $notice->getUri());
}
);
}
+<<<<<<< .merge_file_5LWulC
static public function beforeSchemaUpdate()
+=======
+ function saveNew(Profile $profile, $event, $verb, array $options = array())
+>>>>>>> .merge_file_iCY7gC
{
$table = strtolower(get_called_class());
$schema = Schema::get();
$this->response);
}
- static function toHTML($profile, $event, $response)
+ static function toHTML(Profile $profile, Event $event, $response)
{
$fmt = null;
function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile) {
$user = User::getKV('id', $profile->id);
- if ($user) {
+
+ if ($user instanceof User) {
$url = common_local_url('profiledetail', array('nickname' => $user->nickname));
// TRANS: Link text on user profile page leading to extended profile page.
$out->element('a', array('href' => $url, 'class' => 'profiledetail'), _m('More details...'));
class ProfileDetailAction extends ShowstreamAction
{
+<<<<<<< .merge_file_YX3UPL
function isReadOnly($args)
+=======
+
+ function isReadOnly(array $args=array())
+>>>>>>> .merge_file_HWH83L
{
return true;
}
*
* @return boolean true if nothing goes wrong
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->query = $this->trimmed('term');
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showResults();
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return void
*/
- function onEndLoginGroupNav($action)
+ function onEndLoginGroupNav(Action $action)
{
$action_name = $action->trimmed('action');
*
* @return boolean hook value
*/
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('facebook')) {
* @param Action $action the current action
*
*/
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
if ($this->needsScripts($action)) {
*
* @return boolean hook return
*/
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
if (self::hasApplication() && $notice->isLocal() && $notice->inScope(null)) {
array_push($transports, 'facebook');
*
* @return boolean hook return
*/
- function onEndInitializeQueueManager($manager)
+ function onEndInitializeQueueManager(QueueManager $manager)
{
if (self::hasApplication()) {
$manager->connect('facebook', 'FacebookQueueHandler');
*
* @return boolean true
*/
- function prepare($args)
+ function prepare(array $args=array())
{
$this->facebook = Facebookclient::getFacebook();
*
* @param array $args is ignored since it's now passed in in prepare()
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
private $fbuser = null; // Facebook user object (JSON)
private $accessToken = null; // Access token provided by Facebook JS API
- function prepare($args) {
+ function prepare(array $args=array()) {
parent::prepare($args);
// Check cookie for a valid access_token
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
class FacebookloginAction extends Action
{
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
class FacebooksettingsAction extends SettingsAction {
private $facebook; // Facebook PHP-SDK client obj
+<<<<<<< .merge_file_3MYh91
protected $flink;
+=======
+ /**
+ * For initializing members of the class.
+ *
+ * @param array $argarray misc. arguments
+ *
+ * @return boolean true
+ */
+ function prepare(array $args=array()) {
+ parent::prepare($args);
+>>>>>>> .merge_file_egnS41
protected function doPreparation()
{
protected $needPost = true;
+ /**
+ * Take arguments for running
+ *
+ * @return boolean success flag
+ */
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->notice = Notice::getKV($this->arg('id'));
if (!empty($this->notice->repeat_of)) {
- common_log(LOG_DEBUG, 'Trying to Fave '.$this->notice->id.', repeat of '.$this->notice->repeat_of);
- common_log(LOG_DEBUG, 'Will Fave '.$this->notice->repeat_of.' instead');
+ common_debug('Trying to Fave '.$this->notice->id.', repeat of '.$this->notice->repeat_of);
+ common_debug('Will Fave '.$this->notice->repeat_of.' instead');
$real_notice_id = $this->notice->repeat_of;
$this->notice = Notice::getKV($real_notice_id);
}
return true;
}
+ /**
+ * Handle the request
+ *
+ * Check the format and show the user info
+ *
+ * @return void
+ */
protected function handle()
{
parent::handle();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->user = $this->auth_user;
$this->notice = Notice::getKV($this->arg('id'));
if ($this->notice->repeat_of != '' ) {
- common_log(LOG_DEBUG, 'Trying to unFave '.$this->notice->id);
- common_log(LOG_DEBUG, 'Will unFave '.$this->notice->repeat_of.' instead');
+ common_debug('Trying to unFave '.$this->notice->id);
+ common_debug('Will unFave '.$this->notice->repeat_of.' instead');
$real_notice_id = $this->notice->repeat_of;
$this->notice = Notice::getKV($real_notice_id);
}
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$profile = Profile::getKV('id', $id);
$ids_with_profile_data[$i]['user_id'] = $id;
$ids_with_profile_data[$i]['nickname'] = $profile->nickname;
- $ids_with_profile_data[$i]['fullname'] = $profile->fullname;
- $ids_with_profile_data[$i]['profileurl'] = $profile->profileurl;
+ $ids_with_profile_data[$i]['fullname'] = $profile->fullname;
+ $ids_with_profile_data[$i]['profileurl'] = $profile->profileurl;
$profile = new Profile();
$profile->id = $id;
$avatarurl = $profile->avatarUrl(24);
- $ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
+ $ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
$i++;
}
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean true
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @todo move queries from showContent() to here
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*/
class FavoritesrssAction extends TargetedRss10Action
{
+<<<<<<< .merge_file_ZRP5X2
protected function getNotices()
+=======
+ /** The user whose favorites to display */
+
+ var $user = null;
+
+ /**
+ * Find the user to display by supplied nickname
+ *
+ * @param array $args Arguments from $_REQUEST
+ *
+ * @return boolean success
+ */
+ function prepare(array $args=array())
+>>>>>>> .merge_file_e11sr1
{
// is this our own stream?
$own = $this->scoped instanceof Profile ? $this->target->getID() === $this->scoped->getID() : false;
*/
class ShowfavoritesAction extends ShowstreamAction
{
+<<<<<<< .merge_file_M0c3R1
+=======
+ /** User we're getting the faves of */
+ var $user = null;
+ /** Page of the faves we're on */
+ var $page = null;
+
+ /**
+ * Is this a read-only page?
+ *
+ * @return boolean true
+ */
+ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+
+ /**
+ * Title of the page
+ *
+ * Includes name of user and page number.
+ *
+ * @return string title of page
+ */
+>>>>>>> .merge_file_PD3TQ1
function title()
{
if ($this->page == 1) {
}
}
+<<<<<<< .merge_file_M0c3R1
public function getStream()
{
$own = $this->scoped instanceof Profile ? $this->scoped->sameAs($this->getTarget()) : false;
return new FaveNoticeStream($this->getTarget()->getID(), $own);
+=======
+ /**
+ * Prepare the object
+ *
+ * Check the input values and initialize the object.
+ * Shows an error page on bad input.
+ *
+ * @param array $args $_REQUEST data
+ *
+ * @return boolean success flag
+ */
+ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $nickname = common_canonical_nickname($this->arg('nickname'));
+
+ $this->user = User::getKV('nickname', $nickname);
+
+ if (!$this->user) {
+ // TRANS: Client error displayed when trying to display favourite notices for a non-existing user.
+ $this->clientError(_('No such user.'));
+ }
+
+ $this->page = $this->trimmed('page');
+
+ if (!$this->page) {
+ $this->page = 1;
+ }
+
+ common_set_returnto($this->selfUrl());
+
+ $cur = common_current_user();
+
+ // Show imported/gateway notices as well as local if
+ // the user is looking at their own favorites, otherwise not.
+ $this->notice = Fave::stream($this->user->id,
+ ($this->page-1)*NOTICES_PER_PAGE, // offset
+ NOTICES_PER_PAGE + 1, // limit
+ (!empty($cur) && $cur->id == $this->user->id) // own feed?
+ );
+
+ if (empty($this->notice)) {
+ // TRANS: Server error displayed when favourite notices could not be retrieved from the database.
+ $this->serverError(_('Could not retrieve favorite notices.'));
+ }
+
+ if($this->page > 1 && $this->notice->N == 0){
+ // TRANS: Client error when page not found (404)
+ $this->clientError(_('No such page.'), 404);
+ }
+
+ return true;
+ }
+
+ /**
+ * Handle a request
+ *
+ * Just show the page. All args already handled.
+ *
+ * @param array $args $_REQUEST data
+ *
+ * @return void
+ */
+ function handle(array $args=array())
+ {
+ parent::handle($args);
+ $this->showPage();
+>>>>>>> .merge_file_PD3TQ1
}
function getFeeds()
class FavoritesNoticeList extends NoticeList
{
- function newListItem($notice)
+ function newListItem(Notice $notice)
{
return new FavoritesNoticeListItem($notice, $this->out);
}
*
* @return array Array of Fave objects
*/
- static public function byNotice($notice)
+ static public function byNotice(Notice $notice)
{
if (!isset(self::$_faves[$notice->id])) {
self::fillFaves(array($notice->id));
* @param Notice $notice
* @return boolean event hook return
*/
- function onStartNoticeDistribute($notice)
+ function onStartNoticeDistribute(Notice $notice)
{
$profile = $notice->getProfile();
return true;
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('main/photo/new', array('action' => 'newphoto'));
$m->connect('main/photo/:id', array('action' => 'showphoto'));
{
var $user = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->user = common_current_user();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
public $description; // text
public $profile_id; // int
- public static function getByNotice($notice)
+ public static function getByNotice(Notice $notice)
{
return self::getKV('uri', $notice->uri);
}
);
}
- static function saveNew(Profile $profile, $photo_uri, $thumb_uri, $title, $description, $options=array())
+ static function saveNew(Profile $profile, $photo_uri, $thumb_uri, $title, $description, array $options=array())
{
$photo = new Photo();
$schema->ensureTable('GNUsocialPhotoAlbum', GNUsocialPhotoAlbum::schemaDef());
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect(':nickname/photos', array('action' => 'photos'));
$m->connect(':nickname/photos/:albumid', array('action' => 'photos'));
return true;
}
- function onStartNoticeDistribute($notice)
+ function onStartNoticeDistribute(Notice $notice)
{
common_log(LOG_INFO, "event: StartNoticeDistribute");
if (GNUsocialPhotoTemp::$tmp) {
}
- function onStartHandleFeedEntry($activity)
+ function onStartHandleFeedEntry(Activity $activity)
{
common_log(LOG_INFO, 'photo plugin: onEndAtomPubNewActivity');
$oprofile = Ostatus_profile::ensureActorProfile($activity);
return true;
}
- function onStartShowNoticeItem($action)
+ function onStartShowNoticeItem(Action $action)
{
$photo = GNUsocialPhoto::getKV('notice_id', $action->notice->id);
if($photo) {
_('Photo gallery'), $nav->action->trimmed('action') == 'photos', 'nav_photos');
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink('/plugins/GNUsocialPhotos/res/style.css');
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script('plugins/GNUsocialPhotos/res/gnusocialphotos.js');
}
{
var $user = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$args = $this->returnToArgs();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if($_SERVER['REQUEST_METHOD'] == 'POST') {
{
var $user = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
$this->element('option', array('value' => '120'), _("Medium"));
$this->element('option', array('value' => '400'), _("Normal"));
$this->elementEnd('select');
- }
+ }
function showAlbums()
{
{
var $user = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->user = common_current_user();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$schema = Schema::get();
$schema->ensureTable('GNUsocialProfileExtensionField', GNUsocialProfileExtensionField::schemaDef());
$schema->ensureTable('GNUsocialProfileExtensionResponse', GNUsocialProfileExtensionResponse::schemaDef());
-
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect(':nickname/bio', array('action' => 'bio'));
$m->connect('admin/profilefields', array('action' => 'profilefieldsAdminPanel'));
}
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink('/plugins/GNUsocialProfileExtensions/res/style.css');
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script('plugins/GNUsocialProfileExtensions/js/profile.js');
}
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('profilefields')) {
{
var $user = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
$this->out->elementEnd('li');
}
- function newListItem($notice)
+ function newListItem(Notice $notice)
{
return new NoticeTreeItem($notice, $this->out);
}
return true;
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('main/postvideo', array('action' => 'postvideo'));
$m->connect('showvideo/:id', array('action' => 'showvideo'));
var $user = null;
var $url = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->user = common_current_user();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
protected $id = null;
protected $vid = null;
- function prepare($args)
+ function prepare(array $args=array())
{
OwnerDesignAction::prepare($args);
$this->id = $this->trimmed('id');
public $url; // varchar (191) not 255 because utf8mb4 takes more space
public $profile_id; // int
- public static function getByNotice($notice)
+ public static function getByNotice(Notice $notice)
{
return self::getKV('uri', $notice->uri);
}
);
}
- static function saveNew(Profile $profile, $url, $options=array())
+ static function saveNew(Profile $profile, $url, array $options=array())
{
$vid = new Video();
*
* @result boolean hook value
*/
- function onEndGroupSave($group)
+ function onEndGroupSave(User_group $group)
{
$gps = new Group_privacy_settings();
assert(is_callable(array($action, 'getGroup')));
$gps = null;
+ $group = $action->getGroup();
- if ($action->getGroup() instanceof User_group) {
- $gps = Group_privacy_settings::getKV('group_id', $action->getGroup()->id);
+ if ($group instanceof User_group) {
+ $gps = Group_privacy_settings::getKV('group_id', $group->id);
}
$orig = null;
foreach (array_unique($match[1]) as $nickname) {
$group = User_group::getForNickname($nickname, $profile);
- if (empty($group)) {
+ if (!$group instanceof User_group) {
continue;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Send and receive notices using an IRC network
+ *
+ * PHP version 5
+ *
+ * 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 IM
+ * @package StatusNet
+ * @author Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+// We bundle the Phergie library...
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phergie');
+
+/**
+ * Plugin for IRC
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+class IrcPlugin extends ImPlugin {
+ public $host = null;
+ public $port = null;
+ public $username = null;
+ public $realname = null;
+ public $nick = null;
+ public $password = null;
+ public $nickservidentifyregexp = null;
+ public $nickservpassword = null;
+ public $channels = null;
+ public $transporttype = null;
+ public $encoding = null;
+ public $pinginterval = null;
+
+ public $regcheck = null;
+ public $unregregexp = null;
+ public $regregexp = null;
+
+ public $transport = 'irc';
+ protected $whiteList;
+ protected $fake_irc;
+
+ /**
+ * Get the internationalized/translated display name of this IM service
+ *
+ * @return string Name of service
+ */
+ public function getDisplayName() {
+ // TRANS: Service name for IRC.
+ return _m('IRC');
+ }
+
+ /**
+ * Normalize a screenname for comparison
+ *
+ * @param string $screenname Screenname to normalize
+ * @return string An equivalent screenname in normalized form
+ */
+ public function normalize($screenname) {
+ $screenname = str_replace(" ","", $screenname);
+ return strtolower($screenname);
+ }
+
+ /**
+ * Get the screenname of the daemon that sends and receives messages
+ *
+ * @return string Screenname
+ */
+ public function daemonScreenname() {
+ return $this->nick;
+ }
+
+ /**
+ * Validate (ensure the validity of) a screenname
+ *
+ * @param string $screenname Screenname to validate
+ * @return boolean true if screenname is valid
+ */
+ public function validate($screenname) {
+ if (preg_match('/\A[a-z0-9\-_]{1,1000}\z/i', $screenname)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Load related modules when needed
+ *
+ * @param string $cls Name of the class to be loaded
+ * @return boolean hook value; true means continue processing, false means stop.
+ */
+ public function onAutoload($cls) {
+ // in the beginning of this file, we have added an include path
+ if (substr($cls, 0, 7) == 'Phergie') {
+ include_once str_replace('_', DIRECTORY_SEPARATOR, $cls) . '.php';
+ return false;
+ }
+
+ return parent::onAutoload($cls);
+ }
+
+ /*
+ * Start manager on daemon start
+ *
+ * @param array &$versions Array to insert manager into
+ * @return boolean
+ */
+ public function onStartImDaemonIoManagers(&$classes) {
+ parent::onStartImDaemonIoManagers($classes);
+ $classes[] = new IrcManager($this); // handles sending/receiving
+ return true;
+ }
+
+ /**
+ * Ensure the database table is present
+ *
+ */
+ public function onCheckSchema() {
+ $schema = Schema::get();
+
+ // For storing messages while sessions become ready
+ $schema->ensureTable('irc_waiting_message', Irc_waiting_message::schemaDef());
+ return true;
+ }
+
+ /**
+ * Get a microid URI for the given screenname
+ *
+ * @param string $screenname Screenname
+ * @return string microid URI
+ */
+ public function microiduri($screenname) {
+ return 'irc:' . $screenname;
+ }
+
+ /**
+ * Send a message to a given screenname
+ *
+ * @param string $screenname Screenname to send to
+ * @param string $body Text to send
+ * @return boolean true on success
+ */
+ public function sendMessage($screenname, $body) {
+ $lines = explode("\n", $body);
+ foreach ($lines as $line) {
+ $this->fake_irc->doPrivmsg($screenname, $line);
+ $this->enqueueOutgoingRaw(array('type' => 'message', 'prioritise' => 0, 'data' => $this->fake_irc->would_be_sent));
+ }
+ return true;
+ }
+
+ /**
+ * Accept a queued input message.
+ *
+ * @return boolean true if processing completed, false if message should be reprocessed
+ */
+ public function receiveRawMessage($data) {
+ if (strpos($data['source'], '#') === 0) {
+ $message = $data['message'];
+ $parts = explode(' ', $message, 2);
+ $command = $parts[0];
+ if (in_array($command, $this->whiteList)) {
+ $this->handle_channel_incoming($data['sender'], $data['source'], $message);
+ } else {
+ $this->handleIncoming($data['sender'], $message);
+ }
+ } else {
+ $this->handleIncoming($data['sender'], $data['message']);
+ }
+ return true;
+ }
+
+ /**
+ * Helper for handling incoming messages from a channel requiring response
+ * to the channel instead of via PM
+ *
+ * @param string $nick Screenname the message was sent from
+ * @param string $channel Channel the message originated from
+ * @param string $message Message text
+ * @param boolean true on success
+ */
+ protected function handle_channel_incoming($nick, $channel, $notice_text) {
+ $user = $this->getUser($nick);
+ // For common_current_user to work
+ global $_cur;
+ $_cur = $user;
+
+ if (!$user) {
+ $this->sendFromSite($nick, 'Unknown user; go to ' .
+ common_local_url('imsettings') .
+ ' to add your address to your account');
+ common_log(LOG_WARNING, 'Message from unknown user ' . $nick);
+ return;
+ }
+ if ($this->handle_channel_command($user, $channel, $notice_text)) {
+ common_log(LOG_INFO, "Command message by $nick handled.");
+ return;
+ } else if ($this->isAutoreply($notice_text)) {
+ common_log(LOG_INFO, 'Ignoring auto reply from ' . $nick);
+ return;
+ } else if ($this->isOtr($notice_text)) {
+ common_log(LOG_INFO, 'Ignoring OTR from ' . $nick);
+ return;
+ } else {
+ common_log(LOG_INFO, 'Posting a notice from ' . $user->nickname);
+ $this->addNotice($nick, $user, $notice_text);
+ }
+
+ $user->free();
+ unset($user);
+ unset($_cur);
+ unset($message);
+ }
+
+ /**
+ * Attempt to handle a message from a channel as a command
+ *
+ * @param User $user User the message is from
+ * @param string $channel Channel the message originated from
+ * @param string $body Message text
+ * @return boolean true if the message was a command and was executed, false if it was not a command
+ */
+ protected function handle_channel_command($user, $channel, $body) {
+ $inter = new CommandInterpreter();
+ $cmd = $inter->handle_command($user, $body);
+ if ($cmd) {
+ $chan = new ChannelResponseChannel($this, $channel);
+ $cmd->execute($chan);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Send a confirmation code to a user
+ *
+ * @param string $screenname screenname sending to
+ * @param string $code the confirmation code
+ * @param User $user user sending to
+ * @return boolean success value
+ */
+ public function sendConfirmationCode($screenname, $code, $user, $checked = false) {
+ // TRANS: Body text for e-mail confirmation message for IRC.
+ // TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename,
+ // TRANS: %3$s is the plugin display name ("IRC"), %4$s is the confirm address URL.
+ $body = sprintf(_m('User "%1$s" on %2$s has said that your %3$s screenname belongs to them. ' .
+ 'If that\'s true, you can confirm by clicking on this URL: ' .
+ '%4$s' .
+ ' . (If you cannot click it, copy-and-paste it into the ' .
+ 'address bar of your browser). If that user is not you, ' .
+ 'or if you did not request this confirmation, just ignore this message.'),
+ $user->nickname, common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', array('code' => $code)));
+
+ if ($this->regcheck && !$checked) {
+ return $this->checked_sendConfirmationCode($screenname, $code, $user);
+ } else {
+ return $this->sendMessage($screenname, $body);
+ }
+ }
+
+ /**
+ * Only sends the confirmation message if the nick is
+ * registered
+ *
+ * @param string $screenname Screenname sending to
+ * @param string $code The confirmation code
+ * @param User $user User sending to
+ * @return boolean true on succes
+ */
+ public function checked_sendConfirmationCode($screenname, $code, $user) {
+ $this->fake_irc->doPrivmsg('NickServ', 'INFO '.$screenname);
+ $this->enqueueOutgoingRaw(
+ array(
+ 'type' => 'nickcheck',
+ 'prioritise' => 1,
+ 'data' => $this->fake_irc->would_be_sent,
+ 'nickdata' =>
+ array(
+ 'screenname' => $screenname,
+ 'code' => $code,
+ 'user' => $user
+ )
+ )
+ );
+ return true;
+ }
+
+ /**
+ * Initialize plugin
+ *
+ * @return boolean
+ */
+ public function initialize() {
+ if (!isset($this->host)) {
+ // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+ throw new Exception(_m('You must specify a host.'));
+ }
+ if (!isset($this->username)) {
+ // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+ throw new Exception(_m('You must specify a username.'));
+ }
+ if (!isset($this->realname)) {
+ // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+ throw new Exception(_m('You must specify a "real name".'));
+ }
+ if (!isset($this->nick)) {
+ // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+ throw new Exception(_m('You must specify a nickname.'));
+ }
+
+ if (!isset($this->port)) {
+ $this->port = 6667;
+ }
+ if (!isset($this->transporttype)) {
+ $this->transporttype = 'tcp';
+ }
+ if (!isset($this->encoding)) {
+ $this->encoding = 'UTF-8';
+ }
+ if (!isset($this->pinginterval)) {
+ $this->pinginterval = 120;
+ }
+
+ if (!isset($this->regcheck)) {
+ $this->regcheck = true;
+ }
+
+ $this->fake_irc = new FakeIrc;
+
+ /*
+ * Commands allowed to return output to a channel
+ */
+ $this->whiteList = array('stats', 'last', 'get');
+
+ return true;
+ }
+
+ /**
+ * Get plugin information
+ *
+ * @param array $versions Array to insert information into
+ * @return void
+ */
+ public function onPluginVersion(array &$versions) {
+ $versions[] = array('name' => 'IRC',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Luke Fitzgerald',
+ 'homepage' => 'http://status.net/wiki/Plugin:IRC',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('The IRC plugin allows users to send and receive notices over an IRC network.'));
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category Phergie
+ * @package Phergie_Tests
+ * @author Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license http://phergie.org/license New BSD License
+ * @link http://pear.phergie.org/package/Phergie_Tests
+ */
+
+/**
+ * Unit test suite for Pherge_Plugin_Handler.
+ *
+ * @category Phergie
+ * @package Phergie_Tests
+ * @author Phergie Development Team <team@phergie.org>
+ * @license http://phergie.org/license New BSD License
+ * @link http://pear.phergie.org/package/Phergie_Tests
+ */
+class Phergie_Plugin_HandlerTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Plugin handler instance being tested
+ *
+ * @var Phergie_Plugin_Handler
+ */
+ protected $handler;
+
+ /**
+ * Mock Phergie_Config instance passed to the plugin handler constructor
+ *
+ * @var Phergie_Config
+ */
+ protected $config;
+
+ /**
+ * Mock Phergie_Event_Handler instance passed to the plugin handler
+ * constructor
+ *
+ * @var Phergie_Event_Handler
+ */
+ protected $events;
+
+ /**
+ * Returns a mock plugin instance.
+ *
+ * @param string $name Optional short name for the mock plugin, defaults
+ * to 'TestPlugin'
+ * @param array $methods Optional list of methods to override
+ *
+ * @return Phergie_Plugin_Abstract
+ */
+ protected function getMockPlugin($name = 'TestPlugin', array $methods = array())
+ {
+ $methods[] = 'getName';
+ $plugin = $this->getMock('Phergie_Plugin_Abstract', $methods);
+ $plugin
+ ->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue($name));
+ return $plugin;
+ }
+
+ /**
+ * Sets up a new handler instance before each test.
+ *
+ * @return void
+ */
+ public function setUp()
+ {
+ $this->config = $this->getMock('Phergie_Config');
+ $this->events = $this->getMock('Phergie_Event_Handler');
+ $this->handler = new Phergie_Plugin_Handler(
+ $this->config,
+ $this->events
+ );
+ }
+
+ /**
+ * Tests iterability of the plugin handler.
+ *
+ * @return void
+ */
+ public function testImplementsIteratorAggregate()
+ {
+ $reflection = new ReflectionObject($this->handler);
+
+ $this->assertTrue(
+ $reflection->implementsInterface('IteratorAggregate'),
+ 'Handler does not implement IteratorAggregate'
+ );
+
+ $this->assertType(
+ 'Iterator',
+ $this->handler->getIterator(),
+ 'getIterator() must return an iterator'
+ );
+ }
+
+ /**
+ * Tests that a default iterator is returned if none is explicitly set.
+ *
+ * @return void
+ */
+ public function testGetIteratorReturnsDefault()
+ {
+ $this->assertType(
+ 'Phergie_Plugin_Iterator',
+ $this->handler->getIterator()
+ );
+ }
+
+ /**
+ * Tests the ability to change the handler's iterator class when a valid
+ * class is specified.
+ *
+ * @return void
+ */
+ public function testSetIteratorClassWithValidClass()
+ {
+ eval('
+ class DummyIterator extends FilterIterator {
+ public function accept() {
+ return true;
+ }
+ }
+ ');
+
+ $this->handler->setIteratorClass('DummyIterator');
+
+ $this->assertType(
+ 'DummyIterator',
+ $this->handler->getIterator()
+ );
+ }
+
+ /**
+ * Tests that a failure occurs when a nonexistent iterator class is
+ * specified.
+ *
+ * @return void
+ */
+ public function testSetIteratorClassWithNonexistentClass()
+ {
+ try {
+ $this->handler->setIteratorClass('FooIterator');
+ $this->fail('Expected exception was not thrown');
+ } catch (Phergie_Plugin_Exception $e) {
+ return;
+ }
+ $this->fail('Unexpected exception was thrown');
+ }
+
+ /**
+ * Tests that a failure occurs when a class that is not a subclass of
+ * FilterIterator is specified.
+ *
+ * @return void
+ */
+ public function testSetIteratorClassWithNonFilterIteratorClass()
+ {
+ try {
+ $this->handler->setIteratorClass('ArrayIterator');
+ $this->fail('Expected exception was not thrown');
+ } catch (Phergie_Plugin_Exception $e) {
+ return;
+ }
+ $this->fail('Unexpected exception was thrown');
+ }
+
+ /**
+ * Tests countability of the plugin handler.
+ *
+ * @return void
+ */
+ public function testImplementsCountable()
+ {
+ $reflection = new ReflectionObject($this->handler);
+
+ $this->assertTrue(
+ $reflection->implementsInterface('Countable'),
+ 'Handler does not implement Countable'
+ );
+
+ $this->assertType(
+ 'int',
+ count($this->handler),
+ 'count() must return an integer'
+ );
+ }
+
+ /**
+ * Tests the plugin handler exposing added plugins as instance
+ * properties of the handler via isset().
+ *
+ * @return void
+ */
+ public function testImplementsIsset()
+ {
+ $pluginName = 'TestPlugin';
+ $this->assertFalse(isset($this->handler->{$pluginName}));
+ $plugin = $this->getMockPlugin($pluginName);
+ $this->handler->addPlugin($plugin);
+ $this->assertTrue(isset($this->handler->{$pluginName}));
+ }
+
+ /**
+ * Tests the plugin handler exposing added plugins as instance
+ * properties of the handler.
+ *
+ * @depends testImplementsIsset
+ * @return void
+ */
+ public function testImplementsGet()
+ {
+ $plugin = $this->getMockPlugin();
+ $this->handler->addPlugin($plugin);
+ $name = $plugin->getName();
+ $getPlugin = $this->handler->getPlugin($name);
+ $this->assertTrue(isset($this->handler->$name));
+ $get = $this->handler->$name;
+ $this->assertSame($getPlugin, $get);
+ }
+
+ /**
+ * Tests the plugin handler allowing for plugin removal via unset().
+ *
+ * @depends testImplementsGet
+ * @return void
+ */
+ public function testImplementsUnset()
+ {
+ $plugin = $this->getMockPlugin();
+ $this->handler->addPlugin($plugin);
+ unset($this->handler->{$plugin->getName()});
+ $this->assertFalse($this->handler->hasPlugin($plugin->getName()));
+ }
+
+ /**
+ * Tests the plugin handler executing a callback on all contained
+ * plugins.
+ *
+ * @return void
+ */
+ public function testImplementsCall()
+ {
+ foreach (range(1, 2) as $index) {
+ $plugin = $this->getMockPlugin('TestPlugin' . $index, array('callback'));
+ $plugin
+ ->expects($this->once())
+ ->method('callback');
+ $this->handler->addPlugin($plugin);
+ }
+
+ $this->assertTrue($this->handler->callback());
+ }
+
+ /**
+ * Tests a newly instantiated handler not having plugins associated with
+ * it.
+ *
+ * @depends testImplementsCountable
+ * @return void
+ */
+ public function testEmptyHandlerHasNoPlugins()
+ {
+ $this->assertEquals(0, count($this->handler));
+ }
+
+ /**
+ * Tests a newly instantiated handler not having autoloading enabled by
+ * default.
+ *
+ * @return void
+ */
+ public function testGetAutoloadDefaultsToNotAutoload()
+ {
+ $this->assertFalse($this->handler->getAutoload());
+ }
+
+ /**
+ * Tests setAutoload().
+ *
+ * @depends testGetAutoloadDefaultsToNotAutoload
+ * @return void
+ */
+ public function testSetAutoload()
+ {
+ $this->assertSame(
+ $this->handler->setAutoload(true),
+ $this->handler,
+ 'setAutoload() does not provide a fluent interface'
+ );
+
+ $this->assertTrue(
+ $this->handler->getAutoload(),
+ 'setAutoload() had no effect on getAutoload()'
+ );
+ }
+
+ /**
+ * Tests addPath() providing a fluent interface.
+ *
+ * @return void
+ */
+ public function testAddPathProvidesFluentInterface()
+ {
+ $handler = $this->handler->addPath(dirname(__FILE__));
+ $this->assertSame($this->handler, $handler);
+ }
+
+ /**
+ * Tests addPath() throwing an exception when it cannot read the
+ * directory.
+ *
+ * @return void
+ */
+ public function testAddPathThrowsExceptionOnUnreadableDirectory()
+ {
+ try {
+ $this->handler->addPath('/an/unreadable/directory/path');
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_DIRECTORY_NOT_READABLE,
+ $e->getCode()
+ );
+ return;
+ }
+
+ $this->fail('An expected exception has not been raised');
+ }
+
+ /**
+ * Tests adding a path to the plugin handler.
+ *
+ * @return void
+ */
+ public function testAddPath()
+ {
+ $pluginName = 'Mock';
+
+ try {
+ $this->handler->addPlugin($pluginName);
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+ $e->getCode()
+ );
+ }
+
+ if (!isset($e)) {
+ $this->fail('Plugin loaded, path was already present');
+ }
+
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+ try {
+ $this->handler->addPlugin($pluginName);
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->fail('Added path, plugin still not found');
+ }
+ }
+
+ /**
+ * Tests addPlugin() returning an added plugin instance.
+ *
+ * @return void
+ */
+ public function testAddPluginByInstanceReturnsPluginInstance()
+ {
+ $plugin = $this->getMockPlugin();
+ $returnedPlugin = $this->handler->addPlugin($plugin);
+ $this->assertSame(
+ $returnedPlugin,
+ $plugin,
+ 'addPlugin() does not return the instance passed to it'
+ );
+ }
+
+ /**
+ * Tests adding a plugin to the handler using the plugin's short name.
+ *
+ * @return void
+ */
+ public function testAddPluginByShortName()
+ {
+ $pluginName = 'Mock';
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+ $returnedPlugin = $this->handler->addPlugin($pluginName);
+ $this->assertTrue($this->handler->hasPlugin($pluginName));
+
+ $this->assertType(
+ 'Phergie_Plugin_Mock',
+ $this->handler->getPlugin($pluginName)
+ );
+
+ $this->assertSame(
+ $this->handler->getPlugin($pluginName),
+ $returnedPlugin,
+ 'Handler does not contain added plugin'
+ );
+ }
+
+
+ /**
+ * Tests adding a plugin instance to the handler.
+ *
+ * @return void
+ */
+ public function testAddPluginByInstance()
+ {
+ $plugin = $this->getMockPlugin();
+ $returnedPlugin = $this->handler->addPlugin($plugin);
+ $this->assertTrue($this->handler->hasPlugin('TestPlugin'));
+
+ $this->assertSame(
+ $plugin,
+ $returnedPlugin,
+ 'addPlugin() does not return added plugin instance'
+ );
+
+ $this->assertSame(
+ $plugin,
+ $this->handler->getPlugin('TestPlugin'),
+ 'getPlugin() does not return added plugin instance'
+ );
+ }
+
+ /**
+ * Tests addPlugin() throwing an exception when the plugin class file
+ * can't be found.
+ *
+ * @return void
+ */
+ public function testAddPluginThrowsExceptionWhenPluginFileNotFound()
+ {
+ try {
+ $this->handler->addPlugin('TestPlugin');
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+ $e->getCode()
+ );
+ return;
+ }
+
+ $this->fail('An expected exception has not been raised');
+ }
+
+ /**
+ * Recursively removes all files and subdirectories in a directory.
+ *
+ * @param string $path Directory path
+ * @return void
+ */
+ private function removeDirectory($path)
+ {
+ if (file_exists($path)) {
+ $it = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path),
+ RecursiveIteratorIterator::CHILD_FIRST
+ );
+ foreach ($it as $entry) {
+ if ($it->isDot()) {
+ continue;
+ }
+ if ($entry->isDir()) {
+ rmdir($entry->getPathname());
+ } else {
+ unlink($entry->getPathname());
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests addPlugin() throwing an exception when the plugin class file is
+ * found, but does not contain the plugin class as expected.
+ *
+ * @return void
+ */
+ public function testAddPluginThrowsExceptionWhenPluginClassNotFound()
+ {
+ $path = common_get_temp_dir() . '/Phergie/Plugin';
+ $this->removeDirectory(dirname($path));
+ mkdir($path, 0777, true);
+ touch($path . '/TestPlugin.php');
+ $this->handler->addPath($path, 'Phergie_Plugin_');
+
+ try {
+ $this->handler->addPlugin('TestPlugin');
+ } catch(Phergie_Plugin_Exception $e) { }
+
+ if (isset($e)) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+ $e->getCode()
+ );
+ } else {
+ $this->fail('An expected exception has not been raised');
+ }
+
+ $this->removeDirectory(dirname($path));
+ }
+
+ /**
+ * Tests addPlugin() throwing an exception when trying to instantiate a
+ * class that doesn't extend Phergie_Plugin_Abstract.
+ *
+ * @return void
+ */
+ public function testAddPluginThrowsExceptionIfRequestingNonPlugin()
+ {
+ try {
+ $this->handler->addPlugin('Handler');
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_INCORRECT_BASE_CLASS,
+ $e->getCode()
+ );
+ return;
+ }
+
+ $this->fail('An expected exception has not been raised');
+ }
+
+ /**
+ * Tests addPlugin() throwing an exception when trying to instantiate a
+ * class that can't be instantiated.
+ *
+ * @return void
+ */
+ public function testAddPluginThrowsExceptionIfPluginNotInstantiable()
+ {
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+ try {
+ $this->handler->addPlugin('TestNonInstantiablePluginFromFile');
+ } catch(Phergie_Plugin_Exception $e) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_CLASS_NOT_INSTANTIABLE,
+ $e->getCode()
+ );
+ return;
+ }
+
+ $this->fail('An expected exception has not been raised');
+ }
+
+ /**
+ * Tests adding a plugin by its short name with arguments passed to the
+ * plugin constructor.
+ *
+ * @return void
+ */
+ public function testAddPluginShortNamePassesArgsToConstructor()
+ {
+ $pluginName = 'Mock';
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+ $arguments = array('a', 'b', 'c');
+ $plugin = $this->handler->addPlugin($pluginName, $arguments);
+
+ $this->assertAttributeSame(
+ $arguments,
+ 'arguments',
+ $plugin,
+ 'Arguments do not match'
+ );
+ }
+
+ /**
+ * Tests addPlugin() passing Phergie_Config to an instantiated plugin.
+ *
+ * @return void
+ */
+ public function testAddPluginPassesConstructorArguments()
+ {
+ $pluginName = 'Mock';
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+ $plugin = $this->handler->addPlugin($pluginName);
+
+ $this->assertSame(
+ $this->config,
+ $plugin->getConfig(),
+ 'Phergie_Config instances do not match'
+ );
+
+ $this->assertSame(
+ $this->events,
+ $plugin->getEventHandler(),
+ 'Phergie_Event_Handler instances do not match'
+ );
+ }
+
+ /**
+ * Tests addPlugin() calling onLoad() on an instantiated plugin.
+ *
+ * @return void
+ */
+ public function testAddPluginCallsOnLoadOnInstantiatedPlugin()
+ {
+ $plugin = $this->getMockPlugin(null, array('onLoad'));
+ $plugin
+ ->expects($this->once())
+ ->method('onLoad');
+ $this->handler->addPlugin($plugin);
+ }
+
+ /**
+ * Tests addPlugin() returning the same plugin when called twice.
+ *
+ * @return void
+ */
+ public function testAddPluginReturnsSamePluginWhenAskedTwice()
+ {
+ $pluginName = 'Mock';
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+ $plugin1 = $this->handler->addPlugin($pluginName);
+ $plugin2 = $this->handler->addPlugin($pluginName);
+ $this->assertSame($plugin1, $plugin2);
+ }
+
+ /**
+ * Tests getPlugin() throwing an exception when trying to get an
+ * unloaded plugin with autoload disabled.
+ *
+ * @depends testGetAutoloadDefaultsToNotAutoload
+ * @return void
+ */
+ public function testExceptionThrownWhenLoadingPluginWithoutAutoload()
+ {
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+ try {
+ $this->handler->getPlugin('Mock');
+ } catch (Phergie_Plugin_Exception $expected) {
+ $this->assertEquals(
+ Phergie_Plugin_Exception::ERR_PLUGIN_NOT_LOADED,
+ $expected->getCode()
+ );
+ return;
+ }
+
+ $this->fail('An expected exception has not been raised');
+ }
+
+ /**
+ * Tests addPlugins() with a plugin short name and no plugin constructor
+ * arguments.
+ *
+ * @depends testAddPluginByShortName
+ * @depends testAddPluginByInstance
+ * @return void
+ */
+ public function testAddPluginsWithoutArguments()
+ {
+ $prefix = 'Phergie_Plugin_';
+ $this->handler->addPath(dirname(__FILE__), $prefix);
+
+ $plugin = 'Mock';
+ $this->handler->addPlugins(array($plugin));
+ $returnedPlugin = $this->handler->getPlugin($plugin);
+ $this->assertContains(
+ get_class($returnedPlugin),
+ $prefix . $plugin,
+ 'Short name plugin not of expected class'
+ );
+ }
+
+ /**
+ * Tests addPlugins() with a plugin short name and plugin constructor
+ * arguments.
+ *
+ * @depends testAddPluginByShortName
+ * @depends testAddPluginByInstance
+ * @return void
+ */
+ public function testAddPluginsWithArguments()
+ {
+ $prefix = 'Phergie_Plugin_';
+ $this->handler->addPath(dirname(__FILE__), $prefix);
+
+ $arguments = array(1, 2, 3);
+ $plugin = array('Mock', $arguments);
+ $this->handler->addPlugins(array($plugin));
+ $returnedPlugin = $this->handler->getPlugin('Mock');
+ $this->assertEquals(
+ $arguments,
+ $returnedPlugin->getArguments(),
+ 'Constructor arguments for instance plugin do not match'
+ );
+ }
+
+ /**
+ * Tests removePlugin() with a plugin instance.
+ *
+ * @depends testAddPluginByInstance
+ * @return void
+ */
+ public function testRemovePluginByInstance()
+ {
+ $plugin = $this->getMockPlugin();
+ $this->handler->addPlugin($plugin);
+ $this->handler->removePlugin($plugin);
+ $this->assertFalse(
+ $this->handler->hasPlugin($plugin->getName()),
+ 'Plugin was not removed'
+ );
+ }
+
+ /**
+ * Tests removePlugin() with a plugin short name.
+ *
+ * @depends testAddPluginByShortName
+ * @return void
+ */
+ public function testRemovePluginByShortName()
+ {
+ $plugin = 'Mock';
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+ $this->handler->addPlugin($plugin);
+ $this->handler->removePlugin($plugin);
+ $this->assertFalse(
+ $this->handler->hasPlugin($plugin),
+ 'Plugin was not removed'
+ );
+ }
+
+ /**
+ * Tests getPlugin() when the plugin is not already loaded and
+ * autoloading is disabled.
+ *
+ * @depends testSetAutoload
+ * @return void
+ */
+ public function testGetPluginWithAutoloadEnabled()
+ {
+ $this->handler->setAutoload(true);
+ $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+ $plugin = $this->handler->getPlugin('Mock');
+ $this->assertType(
+ 'Phergie_Plugin_Mock',
+ $plugin,
+ 'Retrieved plugin not of expected class'
+ );
+ }
+
+ /**
+ * Tests getPlugins().
+ *
+ * @depends testGetPluginWithAutoloadEnabled
+ * @return void
+ */
+ public function testGetPlugins()
+ {
+ $plugin1 = $this->getMockPlugin('TestPlugin1');
+ $this->handler->addPlugin($plugin1);
+
+ $plugin2 = $this->getMockPlugin('TestPlugin2');
+ $this->handler->addPlugin($plugin2);
+
+ $expected = array(
+ 'testplugin1' => $plugin1,
+ 'testplugin2' => $plugin2,
+ );
+
+ $actual = $this->handler->getPlugins();
+ $this->assertEquals($expected, $actual);
+
+ $actual = $this->handler->getPlugins(array('testplugin1', 'testplugin2'));
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests that multiple plugin iterators can be used concurrently.
+ *
+ * @return void
+ */
+ public function testUseMultiplePluginIteratorsConcurrently()
+ {
+ $plugin1 = $this->getMockPlugin('TestPlugin1');
+ $this->handler->addPlugin($plugin1);
+
+ $plugin2 = $this->getMockPlugin('TestPlugin2');
+ $this->handler->addPlugin($plugin2);
+
+ $iterator1 = $this->handler->getIterator();
+ $iterator1->next();
+ $this->assertSame($plugin2, $iterator1->current());
+
+ $iterator2 = $this->handler->getIterator();
+ $this->assertSame($plugin1, $iterator2->current());
+ }
+
+ /**
+ * Tests adding plugin paths via configuration.
+ *
+ * @return void
+ */
+ public function testAddPluginPathsViaConfiguration()
+ {
+ $dir = dirname(__FILE__);
+ $prefix = 'Phergie_Plugin_';
+ $paths = array($dir => $prefix);
+ $this->config
+ ->expects($this->any())
+ ->method('offsetExists')
+ ->will($this->returnValue(true));
+ $this->config
+ ->expects($this->any())
+ ->method('offsetGet')
+ ->will($this->returnValue($paths));
+
+ // Reinitialize the handler so the configuration change takes effect
+ // within the constructor
+ $this->handler = new Phergie_Plugin_Handler(
+ $this->config,
+ $this->events
+ );
+
+ $this->handler->setAutoload(true);
+ $this->handler->getPlugin('Mock');
+ }
+}
--- /dev/null
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+
+/**
+ * IRC background connection manager for IRC-using queue handlers,
+ * allowing them to send outgoing messages on the right connection.
+ *
+ * Input is handled during socket select loop, Any incoming messages will be handled.
+ *
+ * In a multi-site queuedaemon.php run, one connection will be instantiated
+ * for each site being handled by the current process that has IRC enabled.
+ */
+class IrcManager extends ImManager {
+ protected $conn = null;
+ protected $lastPing = null;
+ protected $messageWaiting = true;
+ protected $lastMessage = null;
+
+ protected $regChecks = array();
+ protected $regChecksLookup = array();
+
+ protected $connected = false;
+
+ /**
+ * Initialize connection to server.
+ *
+ * @return boolean true on success
+ */
+ public function start($master) {
+ if (parent::start($master)) {
+ $this->connect();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return any open sockets that the run loop should listen
+ * for input on.
+ *
+ * @return array Array of socket resources
+ */
+ public function getSockets() {
+ $this->connect();
+ if ($this->conn) {
+ return $this->conn->getSockets();
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * Request a maximum timeout for listeners before the next idle period.
+ *
+ * @return integer Maximum timeout
+ */
+ public function timeout() {
+ if ($this->messageWaiting) {
+ return 1;
+ } else {
+ return $this->plugin->pinginterval;
+ }
+ }
+
+ /**
+ * Idle processing for io manager's execution loop.
+ *
+ * @return void
+ */
+ public function idle() {
+ // Send a ping if necessary
+ if (empty($this->lastPing) || time() - $this->lastPing > $this->plugin->pinginterval) {
+ $this->sendPing();
+ }
+
+ if ($this->connected) {
+ // Send a waiting message if appropriate
+ if ($this->messageWaiting && time() - $this->lastMessage > 1) {
+ $wm = Irc_waiting_message::top();
+ if ($wm === NULL) {
+ $this->messageWaiting = false;
+ return;
+ }
+
+ $data = unserialize($wm->data);
+ $wm->incAttempts();
+
+ if ($this->send_raw_message($data)) {
+ $wm->delete();
+ } else {
+ if ($wm->attempts <= common_config('queue', 'max_retries')) {
+ // Try again next idle
+ $wm->releaseClaim();
+ } else {
+ // Exceeded the maximum number of retries
+ $wm->delete();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Process IRC events that have come in over the wire.
+ *
+ * @param resource $socket Socket to handle input on
+ * @return void
+ */
+ public function handleInput($socket) {
+ common_debug('Servicing the IRC queue.');
+ $this->stats('irc_process');
+
+ try {
+ $this->conn->handleEvents();
+ } catch (Phergie_Driver_Exception $e) {
+ $this->connected = false;
+ $this->conn->reconnect();
+ }
+ }
+
+ /**
+ * Initiate connection
+ *
+ * @return void
+ */
+ public function connect() {
+ if (!$this->conn) {
+ $this->conn = new Phergie_StatusnetBot;
+
+ $config = new Phergie_Config;
+ $config->readArray(
+ array(
+ 'connections' => array(
+ array(
+ 'host' => $this->plugin->host,
+ 'port' => $this->plugin->port,
+ 'username' => $this->plugin->username,
+ 'realname' => $this->plugin->realname,
+ 'nick' => $this->plugin->nick,
+ 'password' => $this->plugin->password,
+ 'transport' => $this->plugin->transporttype,
+ 'encoding' => $this->plugin->encoding
+ )
+ ),
+
+ 'driver' => 'statusnet',
+
+ 'processor' => 'async',
+ 'processor.options' => array('sec' => 0, 'usec' => 0),
+
+ 'plugins' => array(
+ 'Pong',
+ 'NickServ',
+ 'AutoJoin',
+ 'Statusnet',
+ ),
+
+ 'plugins.autoload' => true,
+
+ // Uncomment to enable debugging output
+ //'ui.enabled' => true,
+
+ 'nickserv.password' => $this->plugin->nickservpassword,
+ 'nickserv.identify_message' => $this->plugin->nickservidentifyregexp,
+
+ 'autojoin.channels' => $this->plugin->channels,
+
+ 'statusnet.messagecallback' => array($this, 'handle_irc_message'),
+ 'statusnet.regcallback' => array($this, 'handle_reg_response'),
+ 'statusnet.connectedcallback' => array($this, 'handle_connected'),
+ 'statusnet.unregregexp' => $this->plugin->unregregexp,
+ 'statusnet.regregexp' => $this->plugin->regregexp
+ )
+ );
+
+ $this->conn->setConfig($config);
+ $this->conn->connect();
+ $this->lastPing = time();
+ $this->lastMessage = time();
+ }
+ return $this->conn;
+ }
+
+ /**
+ * Called via a callback when a message is received
+ * Passes it back to the queuing system
+ *
+ * @param array $data Data
+ * @return boolean
+ */
+ public function handle_irc_message($data) {
+ $this->plugin->enqueueIncomingRaw($data);
+ return true;
+ }
+
+ /**
+ * Called via a callback when NickServ responds to
+ * the bots query asking if a nick is registered
+ *
+ * @param array $data Data
+ * @return void
+ */
+ public function handle_reg_response($data) {
+ // Retrieve data
+ $screenname = $data['screenname'];
+ $nickdata = $this->regChecks[$screenname];
+ $usernick = $nickdata['user']->nickname;
+
+ if (isset($this->regChecksLookup[$usernick])) {
+ if ($data['registered']) {
+ // Send message
+ $this->plugin->sendConfirmationCode($screenname, $nickdata['code'], $nickdata['user'], true);
+ } else {
+ // TRANS: Message given when using an unregistered IRC nickname.
+ $this->plugin->sendMessage($screenname, _m('Your nickname is not registered so IRC connectivity cannot be enabled.'));
+
+ $confirm = new Confirm_address();
+
+ $confirm->user_id = $user->id;
+ $confirm->address_type = $this->plugin->transport;
+
+ if ($confirm->find(true)) {
+ $result = $confirm->delete();
+
+ if (!$result) {
+ common_log_db_error($confirm, 'DELETE', __FILE__);
+ // TRANS: Server error thrown on database error when deleting IRC nickname confirmation.
+ throw new ServerException(_m('Could not delete confirmation.'));
+ }
+ }
+ }
+
+ // Unset lookup value
+ unset($this->regChecksLookup[$usernick]);
+
+ // Unset data
+ unset($this->regChecks[$screename]);
+ }
+ }
+
+ /**
+ * Called when the connection is established
+ *
+ * @return void
+ */
+ public function handle_connected() {
+ $this->connected = true;
+ }
+
+ /**
+ * Enters a message into the database for sending when ready
+ *
+ * @param string $command Command
+ * @param array $args Arguments
+ * @return boolean
+ */
+ protected function enqueue_waiting_message($data) {
+ $wm = new Irc_waiting_message();
+
+ $wm->data = serialize($data);
+ $wm->prioritise = $data['prioritise'];
+ $wm->attempts = 0;
+ $wm->created = common_sql_now();
+ $result = $wm->insert();
+
+ if (!$result) {
+ common_log_db_error($wm, 'INSERT', __FILE__);
+ // TRANS: Server exception thrown when an IRC waiting queue item could not be added to the database.
+ throw new ServerException(_m('Database error inserting IRC waiting queue item.'));
+ }
+
+ return true;
+ }
+
+ /**
+ * Send a message using the daemon
+ *
+ * @param $data Message data
+ * @return boolean true on success
+ */
+ public function send_raw_message($data) {
+ $this->connect();
+ if (!$this->conn) {
+ return false;
+ }
+
+ if ($data['type'] != 'delayedmessage') {
+ if ($data['type'] != 'message') {
+ // Nick checking
+ $nickdata = $data['nickdata'];
+ $usernick = $nickdata['user']->nickname;
+ $screenname = $nickdata['screenname'];
+
+ // Cancel any existing checks for this user
+ if (isset($this->regChecksLookup[$usernick])) {
+ unset($this->regChecks[$this->regChecksLookup[$usernick]]);
+ }
+
+ $this->regChecks[$screenname] = $nickdata;
+ $this->regChecksLookup[$usernick] = $screenname;
+ }
+
+ // If there is a backlog or we need to wait, queue the message
+ if ($this->messageWaiting || time() - $this->lastMessage < 1) {
+ $this->enqueue_waiting_message(
+ array(
+ 'type' => 'delayedmessage',
+ 'prioritise' => $data['prioritise'],
+ 'data' => $data['data']
+ )
+ );
+ $this->messageWaiting = true;
+ return true;
+ }
+ }
+
+ try {
+ $this->conn->send($data['data']['command'], $data['data']['args']);
+ } catch (Phergie_Driver_Exception $e) {
+ $this->connected = false;
+ $this->conn->reconnect();
+ return false;
+ }
+
+ $this->lastMessage = time();
+ return true;
+ }
+
+ /**
+ * Sends a ping
+ *
+ * @return void
+ */
+ protected function sendPing() {
+ $this->lastPing = time();
+ $this->conn->send('PING', $this->lastPing);
+ }
+}
return parent::onAutoload($cls);
}
- function onEndShowPageNotice($action)
+ function onEndShowPageNotice(Action $action)
{
$name = $action->trimmed('action');
$instr = false;
mt_srand((double)microtime() * 1000000);
while( strlen( $str ) < $length )
- $str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
+ $str .= substr( $possible, ( mt_rand() % strlen( $possible ) ), 1 );
return $str;
}
* @param Action $action
* @return boolean hook result
*/
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$user = common_current_user();
if ($user && common_config('attachments', 'process_links')) {
*/
class OembedproxyAction extends OembedAction
{
- function handle($args)
+ function handle(array $args=array())
{
// Trigger short error responses; not a human-readable web page.
GNUsocial::setApi(true);
*
* @return boolean event handler return
*/
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect(':nickname/all/map',
array('action' => 'allmap'),
*
* @return boolean event handler return
*/
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$actionName = $action->trimmed('action');
*/
class AllmapAction extends MapAction
{
- function prepare($args)
+ function prepare(array $args=array())
{
if (parent::prepare($args)) {
$stream = new InboxNoticeStream($this->user->getProfile(), $this->scoped);
var $page = null;
var $notices = null;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
return true;
}
- function noticeAsJson($notice)
+ function noticeAsJson(Notice $notice)
{
// FIXME: this code should be abstracted to a neutral third
// party, like Notice::asJson(). I'm not sure of the ethics
*/
class UsermapAction extends MapAction
{
- function prepare($args)
+ function prepare(array $args=array())
{
if(parent::prepare($args)) {
$this->notice = empty($this->tag)
*
* @return boolean hook return
*/
- function onStartInitializeRouter($m)
+ function onStartInitializeRouter(URLMapper $m)
{
$m->connect('main/min',
array('action' => 'minify'));
return JSMin::minify($code);
}
- static function minifyCss($code, $options = array()) {
+ static function minifyCss($code, array $options = array()) {
require_once('Minify/CSS.php');
return Minify_CSS::minify($code,$options);
}
var $file;
var $v;
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->v = $args['v'];
return filemtime($this->file);
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (! Solar_Dir::$_tmp) {
// use the system if we can
- if (function_exists('sys_get_temp_dir')) {
- $tmp = sys_get_temp_dir();
+ if (function_exists('common_get_temp_dir')) {
+ $tmp = common_get_temp_dir();
} else {
$tmp = Solar_Dir::_tmp();
}
return true;
}
- function onUserRightsCheck($profile, $right, &$result)
+ function onUserRightsCheck(Profile $profile, $right, &$result)
{
if (in_array($right, self::$rights)) {
// Hrm.... really we should confirm that the *other* user isn't privleged. :)
return true;
}
- function onEndGrantRole($profile, $role)
+ function onEndGrantRole(Profile $profile, $role)
{
$modlog = new ModLog();
$modlog->profile_id = $profile->id;
$cur = common_current_user();
-
+
if (!empty($cur)) {
$modlog->moderator_id = $cur->id;
}
return true;
}
- function onEndRevokeRole($profile, $role)
+ function onEndRevokeRole(Profile $profile, $role)
{
$modlog = new ModLog();
$modlog->profile_id = $profile->id;
$scoped = Profile::current();
-
+
if ($scoped instanceof Profile) {
$modlog->moderator_id = $scoped->getID();
}
}
}
- function onUserRightsCheck($profile, $right, &$result) {
+ function onUserRightsCheck(Profile $profile, $right, &$result) {
switch ($right) {
case self::VIEWMODLOG:
$result = ($profile->hasRole(Profile_role::MODERATOR) || $profile->hasRole('modhelper'));
*
* @param ProfileListItem $item
*/
- function onStartProfileListItemProfile($item)
+ function onStartProfileListItemProfile(ProfileListItem $item)
{
$this->showProfileOptions($item->out, $item->profile->getProfile());
return true;
public $private_key;
public $servers;
- function onStartNoticeSave($notice)
+ function onStartNoticeSave(Notice $notice)
{
if ( $this->public_key ) {
//Check spam
*
* @return boolean hook value
*/
- function onNoticeDeleteRelated($notice)
+ function onNoticeDeleteRelated(Notice $notice)
{
$nt = Notice_title::getKV('notice_id', $notice->id);
*
* @return boolean hook value
*/
- function onStartShowHeadTitle($action)
+ function onStartShowHeadTitle(Action $action)
{
$actionName = $action->trimmed('action');
*
* @return string title of the notice, or null if none
*/
- static function fromNotice($notice)
+ static function fromNotice(Notice $notice)
{
$nt = Notice_title::getKV('notice_id', $notice->id);
if (empty($nt)) {
/**
* Put saved notices into the queue for pubsub distribution.
*/
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
if ($notice->inScope(null)) {
// put our transport first, in case there's any conflict (like OMB)
/*
* If the field being looked for is URI look for the profile
*/
- function onStartProfileCompletionSearch($action, $profile, $search_engine) {
+ public function onStartProfileCompletionSearch(Action $action, Profile $profile, $search_engine) {
if ($action->field == 'uri') {
$profile->joinAdd(array('id', 'user:id'));
$profile->whereAdd('uri LIKE "%' . $profile->escape($q) . '%"');
* @param array &$mention in/out param: set of found mentions
* @return boolean hook return value
*/
- function onEndFindMentions(Profile $sender, $text, &$mentions)
+ function onEndFindMentions(Profile $sender, $text, array &$mentions)
{
$matches = array();
* @param Profile &$profile
* @return hook return code
*/
- function onStartCommandGetProfile($command, $arg, &$profile)
+ public function onStartCommandGetProfile(Command $command, $arg, Profile &$profile = null)
{
$oprofile = $this->pullRemoteProfile($arg);
if ($oprofile instanceof Ostatus_profile && !$oprofile->isGroup()) {
* @param User_group &$group
* @return hook return code
*/
- function onStartCommandGetGroup($command, $arg, &$group)
+ function onStartCommandGetGroup(Command $command, $arg, User_group &$group = null)
{
$oprofile = $this->pullRemoteProfile($arg);
if ($oprofile instanceof Ostatus_profile && $oprofile->isGroup()) {
return true;
}
- function onEndShowStatusNetScripts($action) {
+ public function onEndShowStatusNetScripts(Action $action) {
$action->script($this->path('js/ostatus.js'));
return true;
}
if ($oprofile instanceof Ostatus_profile) {
$oprofile->processFeed($feed, 'push');
} else {
- common_log(LOG_DEBUG, "No ostatus profile for incoming feed $feedsub->uri");
+ common_debug("No ostatus profile for incoming feed $feedsub->uri");
}
}
$oprofile->query(sprintf($sql, $profile->id, $profile->id));
if ($oprofile->N == 0) {
- common_log(LOG_DEBUG, "No OStatus remote subscribees for $profile->nickname");
+ common_debug("No OStatus remote subscribees for $profile->nickname");
return true;
}
return true;
}
- public function onProfileDeleteRelated($profile, &$related)
+ public function onProfileDeleteRelated(Profile $profile, array &$related)
{
// Ostatus_profile has a 'profile_id' property, which will be used to find the object
$related[] = 'Ostatus_profile';
{
if ($this->nickname) {
$user = User::getKV('nickname', $this->nickname);
- if ($user) {
+
+ if ($user instanceof User) {
return common_local_url('userbyid', array('id' => $user->id));
} else {
// TRANS: Client error.
var $profile;
var $err;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
if (common_config('feedsub', 'debug')) {
- $tempfile = tempnam(sys_get_temp_dir(), 'feedsub-receive');
+ $tempfile = tempnam(common_get_temp_dir(), 'feedsub-receive');
if ($tempfile) {
file_put_contents($tempfile, $post);
}
* send immediately but won't get the return value.
*
* @param mixed $entry XML string, Notice, or Activity
+ * @param Profile $actor Acting profile
* @return boolean success
*/
- public function notifyDeferred($entry, $actor)
+ public function notifyDeferred($entry, Profile $actor)
{
if ($this->salmonuri) {
try {
* @param string $method 'push' or 'salmon'
* @return mixed saved Notice or false
*/
- public function processPost($activity, $method)
+ public function processPost(Activity $activity, $method)
{
$actor = ActivityUtils::checkAuthorship($activity, $this->localProfile());
*/
static public function filterAttention(Profile $sender, array $attention)
{
- common_log(LOG_DEBUG, "Original reply recipients: " . implode(', ', array_keys($attention)));
+ common_debug("Original reply recipients: " . implode(', ', array_keys($attention)));
$groups = array();
$replies = array();
foreach ($attention as $recipient=>$type) {
if ($sender->isMember($group)) {
$groups[] = $group->id;
} else {
- common_log(LOG_DEBUG, sprintf('Skipping reply to local group %s as sender %d is not a member', $group->getNickname(), $sender->id));
+ common_debug(sprintf('Skipping reply to local group %s as sender %d is not a member', $group->getNickname(), $sender->id));
}
continue;
} else {
- common_log(LOG_DEBUG, "Skipping reply to bogus group $recipient");
+ common_debug("Skipping reply to bogus group $recipient");
}
}
continue;
} catch (Exception $e) {
// Neither a recognizable local nor remote user!
- common_log(LOG_DEBUG, "Skipping reply to unrecognized profile $recipient: " . $e->getMessage());
+ common_debug("Skipping reply to unrecognized profile $recipient: " . $e->getMessage());
}
}
- common_log(LOG_DEBUG, "Local reply recipients: " . implode(', ', $replies));
- common_log(LOG_DEBUG, "Local group recipients: " . implode(', ', $groups));
+ common_debug("Local reply recipients: " . implode(', ', $replies));
+ common_debug("Local group recipients: " . implode(', ', $groups));
return array($groups, $replies);
}
// @todo FIXME: This should be better encapsulated
// ripped from oauthstore.php (for old OMB client)
- $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
+ $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
try {
$imgData = HTTPClient::quickGet($url);
+
// Make sure it's at least an image file. ImageFile can do the rest.
if (false === getimagesizefromstring($imgData)) {
throw new UnsupportedMediaException(_('Downloaded group avatar was not an image.'));
}
+
file_put_contents($temp_filename, $imgData);
unset($imgData); // No need to carry this in memory.
$discover = false;
if (!$homeuri) {
- common_log(LOG_DEBUG, __METHOD__ . " empty actor profile URI: " . var_export($activity, true));
+ common_debug(__METHOD__ . " empty actor profile URI: " . var_export($activity, true));
// TRANS: Exception.
throw new Exception(_m('No profile URI.'));
}
// @todo tags from categories
if ($profile->id) {
- common_log(LOG_DEBUG, "Updating OStatus profile $profile->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+ common_debug("Updating OStatus profile $profile->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
$profile->update($orig);
}
}
$group->homepage = self::getActivityObjectHomepage($object, $hints);
if ($group->id) { // If no id, we haven't called insert() yet, so don't run update()
- common_log(LOG_DEBUG, "Updating OStatus group $group->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+ common_debug("Updating OStatus group $group->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
$group->update($orig);
}
}
- protected static function updatePeopletag($tag, ActivityObject $object, array $hints=array()) {
+ protected static function updatePeopletag(Peopletag $tag, ActivityObject $object, array $hints=array()) {
$orig = clone($tag);
$tag->tag = $object->title;
$tag->tagger = $tagger->profile_id;
if ($tag->id) {
- common_log(LOG_DEBUG, "Updating OStatus peopletag $tag->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+ common_debug("Updating OStatus peopletag $tag->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
$tag->update($orig);
}
}
} else {
$actor = $activity->actor;
- if (empty($actor)) {
+ if (!$actor instanceof Profile) {
// OK here! assume the default
} else if ($actor->id == $this->getUri() || $actor->link == $this->getUri()) {
$this->updateFromActivityObject($actor);
public function verify(Profile $profile)
{
if ($this->alg != 'RSA-SHA256') {
- common_log(LOG_DEBUG, "Salmon error: bad algorithm");
+ common_debug("Salmon error: bad algorithm");
return false;
}
if ($this->encoding != self::ENCODING) {
- common_log(LOG_DEBUG, "Salmon error: bad encoding");
+ common_debug("Salmon error: bad encoding");
return false;
}
try {
$magicsig = $this->getKeyPair($profile, true); // Do discovery too if necessary
} catch (Exception $e) {
- common_log(LOG_DEBUG, "Salmon error: ".$e->getMessage());
+ common_debug("Salmon error: ".$e->getMessage());
return false;
}
$this->pushFeed($feed, array($this, 'peopletagFeedForNotice'), $ptag);
}
+<<<<<<< .merge_file_sx4QDh
function pingReply(Ostatus_profile $oprofile)
+=======
+ function pingReply(OStatus_profile $oprofile)
+>>>>>>> .merge_file_FBa6yh
{
if ($this->user) {
common_debug("OSTATUS [{$this->notice->getID()}]: pinging reply to {$oprofile->localProfile()->getNickname()} for local user '{$this->user->getID()}'");
// remote user or group.
// @fixme as an optimization we can skip this if the
// remote profile is subscribed to the author.
- $oprofile->notifyDeferred($this->notice, $this->user);
+ $oprofile->notifyDeferred($this->notice, $this->user->getProfile());
}
}
$this->clientError($e->getMessage());
}
+<<<<<<< .merge_file_rmpNGn
// Cryptographic verification test, throws exception on failure
$magic_env->verify($this->actor);
+=======
+ // Cryptographic verification test
+ if (!$magic_env->verify($this->actor)) {
+ common_debug("Salmon signature verification failed.");
+ // TRANS: Client error.
+ $this->clientError(_m('Salmon signature verification failed.'));
+ }
+>>>>>>> .merge_file_utstUn
return true;
}
{
parent::handle();
- common_log(LOG_DEBUG, "Got a " . $this->activity->verb);
+ common_debug("Got a " . $this->activity->verb);
try {
if (Event::handle('StartHandleSalmonTarget', array($this->activity, $this->target)) &&
Event::handle('StartHandleSalmon', array($this->activity))) {
END_OF_USERROLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$dry = have_option('dry-run');
if (preg_match('!/group/(\d+)/id!', $oprofile->getUri(), $matches)) {
$id = intval($matches[1]);
$group = Local_group::getKV('group_id', $id);
- if ($group) {
+ if ($group instanceof Local_group) {
$nick = $group->nickname;
} else {
$nick = '<deleted>';
} else if (preg_match('!/user/(\d+)!', $uri, $matches)) {
$id = intval($matches[1]);
$user = User::getKV('id', $id);
- if ($user) {
+
+ if ($user instanceof User) {
$nick = $user->nickname;
} else {
$nick = '<deleted>';
}
+
echo "user $id ($nick) hidden by $uri";
} else {
echo "$uri matched query, but we don't recognize it.\n";
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$delete_inactive = have_option('d', 'delete-inactive');
$delcount = 0;
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
$sub = FeedSub::renewalCheck();
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$validate = new Validate();
END_OF_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
$dry = false;
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$validate = new Validate();
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function showProfileInfo(Ostatus_profile $oprofile) {
if ($oprofile->isGroup()) {
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$validate = new Validate();
UPDATE_OSTATUS_PROFILES;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
/*
* Hacky class to remove some checks and get public access to
* @throws Exception on various error conditions
* @throws OStatusShadowException if this reference would obscure a local user/group
*/
- public static function updateProfileURL($profile_url, $hints=array())
+ public static function updateProfileURL($profile_url, array $hints=array())
{
$oprofile = null;
define('GNUSOCIAL', true);
define('STATUSNET', true); // compatibility
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require_once INSTALLDIR . '/extlib/php-gettext/gettext.inc';
common_init_locale("en_US");
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (!have_option('--notice')) {
print "$helptext";
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @param int $file_id
*/
public static function saveNew($data, $file_id) {
+ // @TODO Must be an object
+ assert(is_object($data));
+
$file_oembed = new File_oembed;
$file_oembed->file_id = $file_id;
if (!isset($data->version)) {
END_OF_USERROLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$dry = have_option('dry-run');
class OfflineBackupPlugin extends Plugin
{
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('main/backupaccount',
array('action' => 'offlinebackup'));
* @return boolean hook value
*/
- function onEndInitializeQueueManager($qm)
+ function onEndInitializeQueueManager(QueueManager $qm)
{
$qm->connect('backoff', 'OfflineBackupQueueHandler');
return true;
{
// XXX: this is pretty lose-y; try another way
- $tmpdir = sys_get_temp_dir() . '/offline-backup/' . $user->nickname . '/' . common_date_iso8601(common_sql_now());
+ $tmpdir = common_get_temp_dir() . '/offline-backup/' . $user->nickname . '/' . common_date_iso8601(common_sql_now());
common_log(LOG_INFO, 'Writing backup data to ' . $tmpdir . ' for ' . $user->nickname);
*/
class OpenExternalLinkTargetPlugin extends Plugin
{
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->inlineScript('$(document).on("click", "a[rel~=external]:not([class~=attachment])", function () { window.open(this.href); return false; });');
*
* @return boolean hook return
*/
- function onArgsInitialize($args)
+ function onArgsInitialize(array &$args)
{
if (common_config('site', 'openidonly')) {
if (array_key_exists('action', $args)) {
*
* @return boolean hook return
*/
- function onEndLoginGroupNav($action)
+ function onEndLoginGroupNav(Action $action)
{
$this->showOpenIDLoginTab($action);
*
* @return boolean hook value
*/
- function onEndShowPageNotice($action)
+ function onEndShowPageNotice(Action $action)
{
$name = $action->trimmed('action');
*
* @return boolean hook value
*/
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('openid')) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (!common_logged_in()) {
var $username = null;
var $message = null;
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (common_is_real_login()) {
$user = oid_get_user($canonical);
- if ($user) {
+ if ($user instanceof User) {
oid_set_last($display);
// XXX: commented out at @edd's request until better
// control over how data flows from OpenID provider.
// oid_update_user($user, $sreg);
common_set_user($user);
common_real_login(true);
+
if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
common_rememberme($user);
}
+
unset($_SESSION['openid_rememberme']);
$this->goHome($user->nickname);
} else {
class OpenidloginAction extends Action
{
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if (common_is_real_login()) {
{
var $oserver;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$this->oserver = oid_server();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$request = $this->oserver->decodeRequest();
*
* @return boolean false
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
return _m('OpenID Identity Verification');
}
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
common_ensure_session();
return true;
}
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$match = in_array($requiredTeam, $teams);
$is = $match ? 'is' : 'is not';
- common_log(LOG_DEBUG, "Remote user $is in required team $requiredTeam: [" . implode(', ', $teams) . "]");
+ common_debug("Remote user $is in required team $requiredTeam: [" . implode(', ', $teams) . "]");
return $match;
}
var $form_html = null;
var $form_id = null;
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
$this->showPage();
return true;
}
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('panel/openx',
array('action' => 'openxadminpanel'));
return true;
}
- function onEndAdminPanelNav($menu) {
+ function onEndAdminPanelNav(Menu $menu) {
if (AdminPanelAction::canAdmin('openx')) {
// TRANS: Menu item title.
$menu_title = _m('OpenX configuration.');
<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * PHP version 5
+ *
+ * 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 OpportunisticQMPlugin
+ * @package StatusNet
+ * @author Brion Vibber <brion@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
class OpportunisticQMPlugin extends Plugin {
public $qmkey = false;
public $secs_per_action = 1; // total seconds to run script per action
public $rel_to_pageload = true; // relative to pageload or queue start
- public function onRouterInitialized($m)
+ public function onRouterInitialized(URLMapper $m)
{
$m->connect('main/runqueue', array('action' => 'runqueue'));
}
try {
$this->poll();
} catch (RunQueueOutOfWorkException $e) {
+ common_debug('Opportunistic queue manager finished: ' . $e->getMessage());
return true;
}
}
*
* @return boolean ignored
*/
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
// Slight modification to the default code.
// Loading the piwik.js file from a <script> created in a document.write
*
* @return boolean hook value
*/
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink($this->path('css/poll.css'));
return true;
function saveNoticeFromActivity(Activity $activity, Profile $profile, array $options=array())
{
// @fixme
- common_log(LOG_DEBUG, "XXX activity: " . var_export($activity, true));
- common_log(LOG_DEBUG, "XXX profile: " . var_export($profile, true));
- common_log(LOG_DEBUG, "XXX options: " . var_export($options, true));
+ common_debug("XXX activity: " . var_export($activity, true));
+ common_debug("XXX profile: " . var_export($profile, true));
+ common_debug("XXX options: " . var_export($options, true));
// Ok for now, we can grab stuff from the XML entry directly.
// This won't work when reading from JSON source
}
try {
$notice = Poll::saveNew($profile, $question, $opts, $options);
- common_log(LOG_DEBUG, "Saved Poll from ActivityStream data ok: notice id " . $notice->id);
+ common_debug("Saved Poll from ActivityStream data ok: notice id " . $notice->id);
return $notice;
} catch (Exception $e) {
- common_log(LOG_DEBUG, "Poll save from ActivityStream data failed: " . $e->getMessage());
+ common_debug("Poll save from ActivityStream data failed: " . $e->getMessage());
}
} else if ($responseElements->length) {
$data = $responseElements->item(0);
}
try {
$notice = Poll_response::saveNew($profile, $poll, $selection, $options);
- common_log(LOG_DEBUG, "Saved Poll_response ok, notice id: " . $notice->id);
+ common_debug("Saved Poll_response ok, notice id: " . $notice->id);
return $notice;
} catch (Exception $e) {
- common_log(LOG_DEBUG, "Poll response save fail: " . $e->getMessage());
+ common_debug("Poll response save fail: " . $e->getMessage());
}
} else {
- common_log(LOG_DEBUG, "YYY no poll data");
+ common_debug("YYY no poll data");
}
}
}
*/
public function activityObjectOutputJson(ActivityObject $obj, array &$out)
{
- common_log(LOG_DEBUG, 'QQQ: ' . var_export($obj, true));
+ common_debug('QQQ: ' . var_export($obj, true));
if (isset($obj->pollQuestion)) {
/**
* "poll": {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return Poll found poll or null
*/
- static function getByNotice($notice)
+ static function getByNotice(Notice $notice)
{
return self::getKV('uri', $notice->uri);
}
*
* @return Notice saved notice
*/
- static function saveNew($profile, $question, $opts, $options=null)
+ static function saveNew(Profile $profile, $question, $opts, array $options = array())
{
- if (empty($options)) {
- $options = array();
- }
-
$p = new Poll();
$p->id = UUID::gen();
array('id' => $p->id));
}
- common_log(LOG_DEBUG, "Saving poll: $p->id $p->uri");
+ common_debug("Saving poll: $p->id $p->uri");
$p->insert();
// TRANS: Notice content creating a poll.
*
* @return Poll_response found response or null
*/
- static function getByNotice($notice)
+ static function getByNotice(Notice $notice)
{
return self::getKV('uri', $notice->uri);
}
*
* @return Notice saved notice
*/
- static function saveNew($profile, $poll, $selection, $options=null)
+ static function saveNew(Profile $profile, $poll, $selection, array $options=array())
{
- if (empty($options)) {
- $options = array();
- }
-
if (!$poll->isValidSelection($selection)) {
// TRANS: Client exception thrown when responding to a poll with an invalid option.
throw new ClientException(_m('Invalid poll selection.'));
array('id' => $pr->id));
}
- common_log(LOG_DEBUG, "Saving poll response: $pr->id $pr->uri");
+ common_debug("Saving poll response: $pr->id $pr->uri");
$pr->insert();
// TRANS: Notice content voting for a poll.
*/
public $dir=false;
- public function onArgsInitialize(&$args)
+ public function onArgsInitialize(array &$args)
{
if (isset($_SERVER['REQUEST_METHOD']) &&
$_SERVER['REQUEST_METHOD'] == 'POST') {
$file = $this->dir . DIRECTORY_SEPARATOR . $this->logFileName();
file_put_contents($file, $output);
} else {
- common_log(LOG_DEBUG, "PostDebug: $output");
+ common_debug("PostDebug: $output");
}
}
@$dom->loadHTML($response);
$y = @simplexml_import_dom($dom);
if (!isset($y->body)) return;
+ // @TODO Super-ugly style???
$xml = $y->body->center->table->tr->td->pre->a->attributes();
if (isset($xml['href'])) {
return strval($xml['href']);
{
switch ($notice->object_type) {
case QnA_Question::OBJECT_TYPE:
- common_log(LOG_DEBUG, "Deleting question from notice...");
+ common_debug("Deleting question from notice...");
$question = QnA_Question::fromNotice($notice);
$question->delete();
break;
case QnA_Answer::OBJECT_TYPE:
- common_log(LOG_DEBUG, "Deleting answer from notice...");
+ common_debug("Deleting answer from notice...");
$answer = QnA_Answer::fromNotice($notice);
- common_log(LOG_DEBUG, "to delete: $answer->id");
+ common_debug("to delete: $answer->id");
$answer->delete();
break;
default:
- common_log(LOG_DEBUG, "Not deleting related, wtf...");
+ common_debug("Not deleting related, wtf...");
}
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script($this->path('js/qna.js'));
return true;
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->cssLink($this->path('css/qna.css'));
return true;
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
*
* @return QnA_Answer found response or null
*/
- static function getByNotice($notice)
+ static function getByNotice(Notice $notice)
{
$answer = self::getKV('uri', $notice->uri);
if (empty($answer)) {
return Notice::getKV('uri', $this->uri);
}
- static function fromNotice($notice)
+ static function fromNotice(Notice $notice)
{
return QnA_Answer::getKV('uri', $notice->uri);
}
);
}
- static function toHTML($profile, $question, $answer)
+ static function toHTML(Profile $profile, $question, $answer)
{
$notice = $question->getNotice();
*
* @return Notice saved notice
*/
- static function saveNew($profile, $question, $text, $options = null)
+ static function saveNew(Profile $profile, $question, $text, array $options = array())
{
- if (empty($options)) {
- $options = array();
- }
-
$answer = new QnA_Answer();
$answer->id = UUID::gen();
$answer->profile_id = $profile->id;
array('id' => $answer->id)
);
- common_log(LOG_DEBUG, "Saving answer: $answer->id, $answer->uri");
+ common_debug("Saving answer: $answer->id, $answer->uri");
$answer->insert();
$content = sprintf(
*
* @return Question found question or null
*/
- static function getByNotice($notice)
+ static function getByNotice(Notice $notice)
{
return self::getKV('uri', $notice->uri);
}
return $a->count();
}
- static function fromNotice($notice)
+ static function fromNotice(Notice $notice)
{
return QnA_Question::getKV('uri', $notice->uri);
}
return self::toString($this->getProfile(), $this);
}
- static function toHTML($profile, $question)
+ static function toHTML(Profile $profile, $question)
{
$notice = $question->getNotice();
*
* @return Notice saved notice
*/
- static function saveNew($profile, $title, $description, $options = array())
+ static function saveNew(Profile $profile, $title, $description, array $options = array())
{
$q = new QnA_Question();
);
}
- common_log(LOG_DEBUG, "Saving question: $q->id $q->uri");
+ common_debug("Saving question: $q->id $q->uri");
$q->insert();
if (Notice::contentTooLong($q->title . ' ' . $q->uri)) {
$v->vote = $vote;
$v->created = common_sql_now();
- common_log(LOG_DEBUG, "Saving vote: $v->id $v->vote");
+ common_debug("Saving vote: $v->id $v->vote");
$v->insert();
}
*
* @return void
*/
- function __construct($out = null, $title = null, $description = null, $options = null)
+ function __construct($out = null, $title = null, $description = null, array $options = array())
{
parent::__construct($out);
$this->title = $title;
*
* @return boolean hook return
*/
- function onRouterInitialized($m)
+ function onRouterInitialized(URLMapper $m)
{
$m->connect('/main/rsscloud/request_notify',
array('action' => 'RSSCloudRequestNotify'));
* @return boolean hook return
*/
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
if ($notice->isLocal()) {
array_push($transports, 'rsscloud');
*
* @return boolean hook return
*/
- function onEndInitializeQueueManager($manager)
+ function onEndInitializeQueueManager(QueueManager $manager)
{
$manager->connect('rsscloud', 'RSSCloudQueueHandler');
return true;
*
* @return boolean false if user doesn't exist
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean false if user doesn't exist
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
return true;
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$channel = $this->_getChannel($action);
return false; // No default processing
}
- function noticeAsJson($notice)
+ function noticeAsJson(Notice $notice)
{
// FIXME: this code should be abstracted to a neutral third
// party, like Notice::asJson(). I'm not sure of the ethics
return $arr;
}
- function getNoticeTags($notice)
+ function getNoticeTags(Notice $notice)
{
$tags = null;
*
* @return boolean hook return value
*/
- function onEndScriptMessages($action, &$messages)
+ function onEndScriptMessages(Action $action, &$messages)
{
// TRANS: Text label for realtime view "play" button, usually replaced by an icon.
$messages['realtime_play'] = _m('BUTTON', 'Play');
* MAY override
*
* @param array $args other arguments
- *
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
* MAY override
*
* @param array $args other arguments
- *
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
END_OF_CLEANUPCHANNELS_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function cleanupChannels()
{
return true;
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
if (isset($action->recaptchaPluginNeedsOutput) && $action->recaptchaPluginNeedsOutput) {
// Load the AJAX API
return true;
}
- function onStartRegistrationTry($action)
+ /**
+ * Called when someone tries to register.
+ *
+ * We check the IP here to determine if it goes over any of our
+ * configured limits.
+ *
+ * @param Action $action Action that is being executed
+ *
+ * @return boolean hook value
+ */
+ function onStartRegistrationTry(Action $action)
{
$resp = recaptcha_check_answer ($this->private_key,
$_SERVER["REMOTE_ADDR"],
*
* @return boolean hook value
*/
- public function onStartRegistrationTry($action)
+ public function onStartRegistrationTry(Action $action)
{
$ipaddress = $this->_getIpAddress();
*
* @return boolean hook value
*/
- public function onEndGrantRole($profile, $role)
+ public function onEndGrantRole(Profile $profile, $role)
{
if (!self::$enabled) {
return true;
*
* @return bool hook result code
*/
- function onStartRegisterUser(&$user, &$profile)
+ function onStartRegisterUser(User &$user, Profile &$profile)
{
$email = $user->email;
END_OF_REGISTERBYEMAIL_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$email = get_option_value('e', 'email');
(strpos($extra, 'Using temporary') !== false);
if ($evil) {
$xquery = $xobj->sanitizeQuery($query);
- common_log(LOG_DEBUG, "$extra | $xquery");
+ common_debug("$extra | $xquery");
}
}
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return false;
}
function onStartNoticeSearchShowResults($action, $q, $notice)
{
$user = common_current_user();
- if ($user) {
+
+ if ($user instanceof User) {
$search = $q;
$searchsub = SearchSub::pkeyGet(array('search' => $search,
'profile_id' => $user->id));
} else {
$form = new SearchSubForm($action, $search);
}
+
$action->elementStart('div', 'entity_actions');
$action->elementStart('ul');
$action->elementStart('li', 'entity_subscribe');
$action->elementEnd('ul');
$action->elementEnd('div');
}
+
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
if ($this->boolean('ajax')) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
class SearchSubscriptionsList extends SubscriptionList
{
- function newListItem($searchsub)
+ function newListItem(SearchSub $searchsub)
{
return new SearchSubscriptionsListItem($searchsub, $this->owner, $this->action);
}
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
return $ts;
}
+ /**
+ * Getter for Profile instance
+ *
+ * @return $profile Profile instance
+ */
+ public function getProfile () {
+ assert($this->profile_id > 0);
+ $profile = new Profile();
+ $profile->id = $this->profile_id;
+ return $profile;
+ }
+
/**
* End a search subscription!
*
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return boolean success flag
*
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return boolean is read only action?
*/
- function isReadOnly($args)
+ function isReadOnly(array $args=array())
{
return true;
}
* @return
*/
- function onStartShowSiteNotice($action)
+ function onStartShowSiteNotice(Action $action)
{
return false;
}
return true;
}
- function onEndShowStyles($action)
+ function onEndShowStyles(Action $action)
{
$action->element('style', null, '#site_notice { width: 100% }');
return true;
return true;
}
- function onEndAdminPanelNav($menu) {
+ function onEndAdminPanelNav(Menu $menu) {
if (AdminPanelAction::canAdmin('sitemap')) {
// TRANS: Menu item title/tooltip
$menu_title = _m('Sitemap configuration');
var $notices = null;
var $j = 0;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
header('Content-Type: text/xml; charset=UTF-8');
$this->startXML();
var $users = null;
var $j = 0;
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
END_OF_UPDATECOUNTS_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
// Will fill the cache
}
// Take over the default... :D
- function onArgsInitialize($args)
+ function onArgsInitialize(array &$args)
{
if (array_key_exists('action', $args)) {
$action = trim($args['action']);
*
* @todo move queries from showContent() to here
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
$exclude = $this->nicknamesToIds($this->excludeUsers);
if (count($include) == 1) {
- return "profile_id = " . intval($include[0]);
+ return '`profile_id` = ' . intval($include[0]);
} else if (count($include) > 1) {
- return "profile_id IN (" . implode(',', $include) . ")";
+ return '`profile_id` IN (' . implode(',', $include) . ')';
} else if (count($exclude) == 1) {
- return "profile_id != " . intval($exclude[0]);
+ return '`profile_id` != ' . intval($exclude[0]);
} else if (count($exclude) > 1) {
- return "profile_id NOT IN (" . implode(',', $exclude) . ")";
+ return '`profile_id` NOT IN (' . implode(',', $exclude) . ')';
} else {
return false;
}
foreach ($nicks as $nick) {
// not the most efficient way for a big list!
$user = User::getKV('nickname', $nick);
- if ($user) {
+
+ if ($user instanceof User) {
$ids[] = intval($user->id);
}
}
END_OF_TRIM_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require dirname(__FILE__) . '/sphinx-utils.php';
END_OF_TRIM_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require dirname(__FILE__) . '/sphinx-utils.php';
sphinx_iterate_sites('sphinx_index_update');
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to create pretty Spotify URLs
+ *
+ * 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 Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @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
+ */
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+define('SPOTIFYPLUGIN_VERSION', '0.1');
+
+/**
+ * Plugin to create pretty Spotify URLs
+ *
+ * The Spotify API is called before the notice is saved to gather artist and track information.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @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 SpotifyPlugin extends Plugin
+{
+ function __construct()
+ {
+ parent::__construct();
+ }
+
+ function onStartNoticeSave(Notice $notice)
+ {
+ $notice->rendered = preg_replace_callback('/spotify:[a-z]{5,6}:[a-z0-9]{22}/i',
+ "renderSpotifyURILink",
+ $notice->rendered);
+
+ $notice->rendered = preg_replace_callback('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}<\/a>/i',
+ "renderSpotifyHTTPLink",
+ $notice->rendered);
+
+ return true;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'Spotify',
+ 'version' => SPOTIFYPLUGIN_VERSION,
+ 'author' => 'Nick Holliday',
+ 'homepage' => 'http://status.net/wiki/Plugin:Spotify',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('Create pretty <a href="http://www.spotify.com">Spotify</a> URLs.'));
+
+ return true;
+ }
+}
+
+// @todo FIXME: This probably should not be global functions.
+function doSpotifyLookup($uri, $isArtist)
+{
+ $request = HTTPClient::start();
+ $response = $request->get('http://ws.spotify.com/lookup/1/?uri=' . $uri);
+ if ($response->isOk()) {
+ $xml = simplexml_load_string($response->getBody());
+
+ if($isArtist)
+ return $xml->name;
+ else
+ return $xml->artist->name . ' - ' . $xml->name;
+ }
+}
+
+function renderSpotifyURILink($match)
+{
+ $isArtist = false;
+ if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+ $name = doSpotifyLookup($match[0], $isArtist);
+ return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
+
+function renderSpotifyHTTPLink($match)
+{
+ $match[0] = preg_replace('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\//i', 'spotify:', $match[0]);
+ $match[0] = preg_replace('/<\/a>/', '', $match[0]);
+ $match[0] = preg_replace('/\//', ':', $match[0]);
+
+ $isArtist = false;
+ if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+ $name = doSpotifyLookup($match[0], $isArtist);
+ return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
--- /dev/null
+../../statistics_plugin/README.md
\ No newline at end of file
--- /dev/null
+../../statistics_plugin/StatisticsPlugin-gnusocial.php
\ No newline at end of file
--- /dev/null
+../../statistics_plugin/actions/
\ No newline at end of file
parent::__construct();
}
- function onArgsInitialize($args)
+ function onArgsInitialize(array &$args)
{
$path = common_config('site', 'path');
if(common_config('site', 'ssl') == 'always' && ($path == '/' || ! $path )) {
return true;
}
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
$transports[] = 'mirror';
}
* @param array $stats
* @return boolean hook return value
*/
- function onProfileStats($profile, &$stats)
+ function onProfileStats(Profile $profile, array &$stats)
{
$cur = common_current_user();
if (!empty($cur) && $cur->id == $profile->id) {
function showFeedForm(SubMirror $mirror)
{
+<<<<<<< .merge_file_ha7DQl
$profile = Profile::getByID($mirror->subscribed);
$form = new EditMirrorForm($this, $profile);
$form->show();
+=======
+ $profile = Profile::getKV('id', $mirror->subscribed);
+
+ if ($profile instanceof Profile) {
+ $form = new EditMirrorForm($this, $profile);
+ $form->show();
+ }
+>>>>>>> .merge_file_SAOPKl
}
function showAddFeedForm()
}
/**
+<<<<<<< .merge_file_ha7DQl
+=======
+ *
+ * @param array $args
+ *
+ * @todo move the ajax display handling to common code
+ */
+ function handle(array $args=array())
+ {
+ if ($this->boolean('ajax')) {
+ $this->startHTML('text/xml;charset=utf-8');
+ $this->elementStart('head');
+ // TRANS: Title for page with form to add a mirror feed provider on.
+ $this->element('title', null, _m('Provider add'));
+ $this->elementEnd('head');
+ $this->elementStart('body');
+
+ $this->showAddFeedForm();
+
+ $this->elementEnd('body');
+ $this->endHTML();
+ } else {
+ return parent::handle($args);
+ }
+ }
+ /**
+ * Handle a POST request
+ *
+ * Muxes to different sub-functions based on which button was pushed
+ *
+ * @return void
+ */
+ function handlePost()
+ {
+ }
+
+ /**
+>>>>>>> .merge_file_SAOPKl
* Show the local navigation menu
*
* This is the same for all settings, so we show it here.
* Kind of dirty, but if pulling an external data feed into an account
* that may be what you want.
*
- * @param Notice $notice
- * @return mixed Notice on successful repeat, true if already repeated, false on failure
+ * @param Profile $profile
+ * @param Notice $notice
+ * @return mixed Notice on successful repeat, true if already repeated, false on failure
*/
- protected function copyNotice($profile, $notice)
+ protected function copyNotice(Profile $profile, Notice $notice)
{
$options = array('is_local' => Notice::LOCAL_PUBLIC,
'url' => $notice->getUrl(), // pass through the foreign link...
parent::__construct();
}
- function onEndShowScripts($action)
+ function onEndShowScripts(Action $action)
{
$action->script($this->path('tabfocus.js'));
}
function onStartTagShowContent(TagAction $action)
{
$user = common_current_user();
- if ($user) {
+
+ if ($user instanceof User) {
$tag = $action->trimmed('tag');
$tagsub = TagSub::pkeyGet(array('tag' => $tag,
'profile_id' => $user->id));
$action->elementEnd('ul');
$action->elementEnd('div');
}
+
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
if ($this->boolean('ajax')) {
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
class TagSubscriptionsList extends SubscriptionList
{
- function newListItem($tagsub)
+ function newListItem(TagSub $tagsub)
{
return new TagSubscriptionsListItem($tagsub, $this->owner, $this->action);
}
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
// Throws exception on error
return $tags;
}
+
+ /**
+ * Getter for Profile instance
+ *
+ * @return $profile Profile instance
+ */
+ public function getProfile () {
+ assert($this->profile_id > 0);
+ $profile = new Profile();
+ $profile->id = $this->profile_id;
+ return $profile;
+ }
}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Use TinyMCE library to allow rich text editing in the browser
+ *
+ * PHP version 5
+ *
+ * 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 WYSIWYG
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Use TinyMCE library to allow rich text editing in the browser
+ *
+ * Converts the notice form in browser to a rich-text editor.
+ *
+ * FIXME: this plugin DOES NOT load its static files from the configured
+ * plugin server if one exists. There are cross-server permissions errors
+ * if you try to do that (something about window.tinymce).
+ *
+ * @category WYSIWYG
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+class TinyMCEPlugin extends Plugin
+{
+ var $html;
+
+ // By default, TinyMCE editor will be available to all users.
+ // With restricted on, only users who have been granted the
+ // "richedit" role get it.
+ public $restricted = false;
+
+ function onEndShowScripts(Action $action)
+ {
+ if (common_logged_in() && $this->isAllowedRichEdit()) {
+ $action->script(common_path('plugins/TinyMCE/js/jquery.tinymce.js'));
+ $action->inlineScript($this->_inlineScript());
+ }
+
+ return true;
+ }
+
+ function onEndShowStyles(Action $action)
+ {
+ if ($this->isAllowedRichEdit()) {
+ $action->style('span#notice_data-text_container, span#notice_data-text_parent { float: left }');
+ }
+ return true;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'TinyMCE',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:TinyMCE',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('Use TinyMCE library to allow rich text editing in the browser.'));
+ return true;
+ }
+
+ /**
+ * Sanitize HTML input and strip out potentially dangerous bits.
+ *
+ * @param string $raw HTML
+ * @return string HTML
+ */
+ private function sanitizeHtml($raw)
+ {
+ require_once INSTALLDIR . '/extlib/htmLawed/htmLawed.php';
+
+ $config = array('safe' => 1,
+ 'deny_attribute' => 'id,style,on*');
+
+ return htmLawed($raw, $config);
+ }
+
+ /**
+ * Hook for new-notice form processing to take our HTML goodies;
+ * won't affect API posting etc.
+ *
+ * @param NewNoticeAction $action
+ * @param User $user
+ * @param string $content
+ * @param array $options
+ * @return boolean hook return
+ */
+ function onStartSaveNewNoticeWeb($action, $user, &$content, &$options)
+ {
+ if ($action->arg('richedit') && $this->isAllowedRichEdit()) {
+ $html = $this->sanitizeHtml($content);
+ $options['rendered'] = $html;
+ $content = common_strip_html($html);
+ }
+ return true;
+ }
+
+ /**
+ * Hook for new-notice form processing to process file upload appending...
+ *
+ * @param NewNoticeAction $action
+ * @param MediaFile $media
+ * @param string $content
+ * @param array $options
+ * @return boolean hook return
+ */
+ function onStartSaveNewNoticeAppendAttachment($action, $media, &$content, &$options)
+ {
+ if ($action->arg('richedit') && $this->isAllowedRichEdit()) {
+ // See if we've got a placeholder inline image; if so, fill it!
+ $dom = new DOMDocument();
+
+ if ($dom->loadHTML($options['rendered'])) {
+ $imgs = $dom->getElementsByTagName('img');
+ foreach ($imgs as $img) {
+ if (preg_match('/(^| )placeholder( |$)/', $img->getAttribute('class'))) {
+ // Create a link to the attachment page...
+ $this->formatAttachment($img, $media);
+ }
+ }
+ $options['rendered'] = $this->saveHtml($dom);
+ }
+
+ // The regular code will append the short URL to the plaintext content.
+ // Carry on and let it through...
+ }
+ return true;
+ }
+
+ /**
+ * Format the attachment placeholder img with the final version.
+ *
+ * @param DOMElement $img
+ * @param MediaFile $media
+ */
+ private function formatAttachment($img, $media)
+ {
+ $parent = $img->parentNode;
+ $dom = $img->ownerDocument;
+
+ $link = $dom->createElement('a');
+ $link->setAttribute('href', $media->fileurl);
+ $link->setAttribute('title', File::url($media->filename));
+
+ if ($this->isEmbeddable($media)) {
+ // Fix the the <img> attributes and wrap the link around it...
+ $this->insertImage($img, $media);
+ $parent->replaceChild($link, $img); //it dies in here?!
+ $link->appendChild($img);
+ } else {
+ // Not an image? Replace it with a text link.
+ $link->setAttribute('rel', 'external');
+ $link->setAttribute('class', 'attachment');
+ $link->setAttribute('id', 'attachment-' . $media->fileRecord->id);
+ $text = $dom->createTextNode($media->shortUrl());
+ $link->appendChild($text);
+ $parent->replaceChild($link, $img);
+ }
+ }
+
+ /**
+ * Is this media file a type we can display inline?
+ *
+ * @param MediaFile $media
+ * @return boolean
+ */
+ private function isEmbeddable($media)
+ {
+ $showable = array('image/png',
+ 'image/gif',
+ 'image/jpeg');
+ return in_array($media->mimetype, $showable);
+ }
+
+ /**
+ * Rewrite and resize a placeholder image element to match the uploaded
+ * file. If the holder is smaller than the file, the file is scaled to fit
+ * with correct aspect ratio (but will be loaded at full resolution).
+ *
+ * @param DOMElement $img
+ * @param MediaFile $media
+ */
+ private function insertImage($img, $media)
+ {
+ $img->setAttribute('src', $media->fileRecord->url);
+
+ $holderWidth = intval($img->getAttribute('width'));
+ $holderHeight = intval($img->getAttribute('height'));
+
+ $path = File::path($media->filename);
+ $imgInfo = getimagesize($path);
+
+ if ($imgInfo) {
+ $origWidth = $imgInfo[0];
+ $origHeight = $imgInfo[1];
+
+ list($width, $height) = $this->sizeBox(
+ $origWidth, $origHeight,
+ $holderWidth, $holderHeight);
+
+ $img->setAttribute('width', $width);
+ $img->setAttribute('height', $height);
+ }
+ }
+
+ /**
+ *
+ * @param int $origWidth
+ * @param int $origHeight
+ * @param int $holderWidth
+ * @param int $holderHeight
+ * @return array($width, $height)
+ */
+ private function sizeBox($origWidth, $origHeight, $holderWidth, $holderHeight)
+ {
+ $holderAspect = $holderWidth / $holderHeight;
+ $origAspect = $origWidth / $origHeight;
+ if ($origAspect >= 1.0) {
+ // wide image
+ if ($origWidth > $holderWidth) {
+ return array($holderWidth, intval($holderWidth / $origAspect));
+ } else {
+ return array($origWidth, $origHeight);
+ }
+ } else {
+ if ($origHeight > $holderHeight) {
+ return array(intval($holderWidth * $origAspect), $holderHeight);
+ } else {
+ return array($origWidth, $origHeight);
+ }
+ }
+ }
+
+ private function saveHtml($dom)
+ {
+ $html = $dom->saveHTML();
+ // hack to remove surrounding crap added to the dom
+ // all we wanted was a fragment
+ $stripped = preg_replace('/^.*<body[^>]*>(.*)<\/body.*$/is', '$1', $html);
+ return $stripped;
+ }
+
+ function _inlineScript()
+ {
+ $path = common_path('plugins/TinyMCE/js/tiny_mce.js');
+ $placeholder = common_path('plugins/TinyMCE/icons/placeholder.png');
+
+ // Note: the normal on-submit triggering to save data from
+ // the HTML editor into the textarea doesn't play well with
+ // our AJAX form submission. Manually moving it to trigger
+ // on our send button click.
+ $scr = <<<END_OF_SCRIPT
+ (function() {
+ var origInit = SN.Init.NoticeFormSetup;
+ SN.Init.NoticeFormSetup = function(form) {
+ origInit(form);
+ var noticeForm = form;
+ var textarea = form.find('.notice_data-text');
+ if (textarea.length == 0) return;
+ textarea.tinymce({
+ script_url : '{$path}',
+ // General options
+ theme : "advanced",
+ plugins : "paste,fullscreen,autoresize,inlinepopups,tabfocus,linkautodetect",
+ theme_advanced_buttons1 : "bold,italic,strikethrough,|,undo,redo,|,link,unlink,image,|,fullscreen",
+ theme_advanced_buttons2 : "",
+ theme_advanced_buttons3 : "",
+ add_form_submit_trigger : false,
+ theme_advanced_resizing : true,
+ tabfocus_elements: ":prev,:next",
+ setup: function(ed) {
+ noticeForm.append('<input type="hidden" name="richedit" value="1">');
+
+ form.find('.submit:first').click(function() {
+ tinymce.triggerSave();
+ });
+
+ var origCounter = SN.U.CharacterCount;
+ SN.U.CharacterCount = function(form) {
+ var text = $(ed.getDoc()).text();
+ return text.length;
+ };
+ ed.onKeyUp.add(function (ed, e) {
+ SN.U.Counter(noticeForm);
+ });
+
+ form.find('input[type=file]').change(function() {
+ var img = '<img src="{$placeholder}" class="placeholder" width="320" height="240">';
+ var html = tinyMCE.activeEditor.getContent();
+ ed.setContent(html + img);
+ });
+ }
+ });
+ };
+ })();
+END_OF_SCRIPT;
+
+ return $scr;
+ }
+
+ /**
+ * Does the current user have permission to use the rich-text editor?
+ * Always true unless the plugin's "restricted" setting is on, in which
+ * case it's limited to users with the "richedit" role.
+ *
+ * @fixme make that more sanely configurable :)
+ *
+ * @return boolean
+ */
+ private function isAllowedRichEdit()
+ {
+ if ($this->restricted) {
+ $user = common_current_user();
+ return !empty($user) && $user->hasRole('richedit');
+ } else {
+ return true;
+ }
+ }
+}
*
* @return void
*/
- function onEndLoginGroupNav($action)
+ function onEndLoginGroupNav(Action $action)
{
$action_name = $action->trimmed('action');
*
* @return boolean hook return
*/
- function onStartEnqueueNotice($notice, &$transports)
+ function onStartEnqueueNotice(Notice $notice, array &$transports)
{
if (self::hasKeys() && $notice->isLocal() && $notice->inScope(null)) {
// Avoid a possible loop
*
* @return boolean hook return
*/
- function onGetValidDaemons(&$daemons)
+ function onGetValidDaemons(array &$daemons)
{
if (self::hasKeys()) {
array_push(
*
* @return boolean hook return
*/
- function onEndInitializeQueueManager($manager)
+ function onEndInitializeQueueManager(QueueManager $manager)
{
if (self::hasKeys()) {
// Outgoing notices -> twitter
* @return boolean hook value
*/
- function onEndAdminPanelNav($nav)
+ function onEndAdminPanelNav(Menu $nav)
{
if (AdminPanelAction::canAdmin('twitter')) {
var $access_token = null;
var $verifier = null;
+<<<<<<< .merge_file_31TpHZ
protected $needLogin = false; // authorization page can also be used to create a new user
+=======
+ /**
+ * Initialize class members. Looks for 'oauth_token' parameter.
+ *
+ * @param array $args misc. arguments
+ *
+ * @return boolean true
+ */
+ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+>>>>>>> .merge_file_WZLnVZ
protected function doPreparation()
{
$this->oauth_token = $this->arg('oauth_token');
$this->verifier = $this->arg('oauth_verifier');
+<<<<<<< .merge_file_31TpHZ
if ($this->scoped instanceof Profile) {
try {
$flink = Foreign_link::getByUserID($this->scoped->getID(), TWITTER_SERVICE);
$fuser = $flink->getForeignUser();
+=======
+ return true;
+ }
+
+ /**
+ * Handler method
+ *
+ * @param array $args is ignored since it's now passed in in prepare()
+ *
+ * @return nothing
+ */
+ function handle(array $args=array())
+ {
+ parent::handle($args);
+
+ if (common_logged_in()) {
+ $user = common_current_user();
+ $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
+>>>>>>> .merge_file_WZLnVZ
// If there's already a foreign link record and a foreign user
// (no exceptions were thrown when fetching either of them...)
*/
class TwitterloginAction extends LoginAction
{
+<<<<<<< .merge_file_mLRVVe
+=======
+ function handle(array $args=array())
+ {
+ parent::handle($args);
+
+ if (common_is_real_login()) {
+ // TRANS: Client error displayed when trying to log in using Twitter while already logged in to StatusNet.
+ $this->clientError(_m('Already logged in.'));
+ }
+
+ $this->showPage();
+ }
+
+>>>>>>> .merge_file_zp4mod
function title()
{
// TRANS: Title for login using Twitter page.
END_OF_TRIM_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require_once dirname(__DIR__) . '/twitter.php';
/**
END_OF_TWITTERDAEMON_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
class TwitterDaemon extends SpawningDaemon
{
END_OF_TRIM_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require_once INSTALLDIR . '/lib/common.php';
require_once INSTALLDIR . '/lib/daemon.php';
require_once dirname(__DIR__) . '/twitter.php';
function getTimeline(Foreign_link $flink, $timelineUri = 'home_timeline')
{
+<<<<<<< .merge_file_ri6ecg
common_log(LOG_DEBUG, $this->name() . ' - Trying to get ' . $timelineUri .
+=======
+ if (empty($flink)) {
+ common_log(LOG_ERR, $this->name() .
+ " - Can't retrieve Foreign_link for foreign ID $fid");
+ return;
+ }
+
+ common_debug($this->name() . ' - Trying to get ' . $timelineUri .
+>>>>>>> .merge_file_UuUk8f
' timeline for Twitter user ' . $flink->foreign_id);
$client = null;
if (TwitterOAuthClient::isPackedToken($flink->credentials)) {
$token = TwitterOAuthClient::unpackToken($flink->credentials);
$client = new TwitterOAuthClient($token->key, $token->secret);
- common_log(LOG_DEBUG, $this->name() . ' - Grabbing ' . $timelineUri . ' timeline with OAuth.');
+ common_debug($this->name() . ' - Grabbing ' . $timelineUri . ' timeline with OAuth.');
} else {
common_log(LOG_ERR, "Skipping " . $timelineUri . " timeline for " .
$flink->foreign_id . " since not OAuth.");
$lastId = Twitter_synch_status::getLastId($flink->foreign_id, $timelineUri);
- common_log(LOG_DEBUG, "Got lastId value '" . $lastId . "' for foreign id '" .
+ common_debug("Got lastId value '" . $lastId . "' for foreign id '" .
$flink->foreign_id . "' and timeline '" . $timelineUri. "'");
try {
*/
public function connect($url)
{
- common_log(LOG_DEBUG, "$this->id opening connection to $url");
+ common_debug("$this->id opening connection to $url");
$scheme = parse_url($url, PHP_URL_SCHEME);
if ($scheme == 'http') {
public function close()
{
if ($this->isConnected()) {
- common_log(LOG_DEBUG, "$this->id closing connection.");
+ common_debug("$this->id closing connection.");
fclose($this->socket);
$this->socket = null;
}
// TRANS: %1$s is the response code, %2$s is the line.
throw new Exception(sprintf(_m('Bad HTTP response code %1$s: %2$s.'),$status,$line));
}
- common_log(LOG_DEBUG, "$this->id $line");
+ common_debug("$this->id $line");
$this->state = 'headers';
}
{
if ($line == '') {
$this->state = 'active';
- common_log(LOG_DEBUG, "$this->id connection is active!");
+ common_debug("$this->id connection is active!");
} else {
- common_log(LOG_DEBUG, "$this->id read HTTP header: $line");
+ common_debug("$this->id read HTTP header: $line");
$this->responseHeaders[] = $line;
}
}
$importer = new TwitterImport();
$notice = $importer->importStatus($status);
if ($notice instanceof Notice) {
+<<<<<<< .merge_file_wUmh9j
try {
$flink = Foreign_link::getByForeignID($receiver, TWITTER_SERVICE);
common_log(LOG_DEBUG, "TweetInQueueHandler - Got flink so add notice ".
+=======
+ $flink = Foreign_link::getByForeignID($receiver, TWITTER_SERVICE);
+ if ($flink instanceof Foreign_link) {
+ common_debug("TweetInQueueHandler - Got flink so add notice ".
+>>>>>>> .merge_file_PpxjMj
$notice->id." to attentions for user ".$flink->user_id);
try {
Attention::saveNew($notice, $flink->getProfile());
common_log(LOG_ERR, "Failed adding notice {$notice->id} to attentions for user {$flink->user_id}: " .
$e->getMessage());
}
+<<<<<<< .merge_file_wUmh9j
} catch (NoResultException $e) {
common_log(LOG_DEBUG, "TweetInQueueHandler - No flink found for foreign user ".$receiver);
+=======
+ } else {
+ common_debug("TweetInQueueHandler - No flink found for foreign user ".$receiver);
+>>>>>>> .merge_file_PpxjMj
}
}
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('n')) {
$nickname = get_option_value('n');
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
// We update any notices that may have come in from
// Twitter that we don't have a status_id for. Note that
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
require_once dirname(dirname(__FILE__)) . '/lib/jsonstreamreader.php';
require_once dirname(dirname(__FILE__)) . '/lib/twitterstreamreader.php';
* @param boolean &$result out, result of the check
*
* @return boolean hook result
+ * @TODO Other implementing classes expect Profile here!!!
+ * @WARNING
*/
function onUserRightsCheck($user, $right, &$result)
{
*
* @return boolean hook result
*/
- function onEndBlockProfile($user, $profile)
+ function onEndBlockProfile(User $user, Profile $profile)
{
if ($this->flagOnBlock && !User_flag_profile::exists($profile->id,
$user->id)) {
*
* @return boolean hook result
*/
- function onProfileDeleteRelated($profile, &$related)
+ public function onProfileDeleteRelated(Profile $profile, array &$related)
{
- $related[] = 'user_flag_profile';
+ $related[] = 'User_flag_profile';
return true;
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
parent::prepare($args);
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
parent::handle($args);
*
* @return ProfileListItem newly-created item
*/
- function newListItem($profile)
+ function newListItem(Profile $profile)
{
return new FlaggedProfileListItem($this->profile, $this->action);
}
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost();
*
* @return boolean success flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
if (!parent::prepare($args)) {
return false;
*
* @return void
*/
- function handle($args)
+ function handle(array $args=array())
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost();
return true;
}
- function onStartRegistrationTry($action)
+ /**
+ * Called when someone tries to register.
+ *
+ * We check the IP here to determine if it goes over any of our
+ * configured limits.
+ *
+ * @param Action $action Action that is being executed
+ *
+ * @return boolean hook value
+ */
+ function onStartRegistrationTry(Action $action)
{
$this->_checkMaxUsers();
return true;
common_config_set('webfinger', 'http_alias', $this->http_alias);
}
- public function onRouterInitialized($m)
+ public function onRouterInitialized(URLMapper $m)
{
$m->connect('.well-known/host-meta', array('action' => 'hostmeta'));
$m->connect('.well-known/host-meta.:format',
/**
* Add a link header for LRDD Discovery
*/
- public function onStartShowHTML($action)
+ public function onStartShowHTML(Action $action)
{
if ($action instanceof ShowstreamAction) {
$acct = 'acct:'. $action->getTarget()->getNickname() .'@'. common_config('site', 'server');
protected $xrd = null;
- public function isReadOnly($args)
+ public function isReadOnly(array $args=array())
{
return true;
}
$absolute = $base->resolve($src);
$avatarUrl = strval($absolute);
- common_log(LOG_DEBUG, "WikiHow avatar found for $profileUrl - $avatarUrl");
+ common_debug("WikiHow avatar found for $profileUrl - $avatarUrl");
$data['avatar'] = $avatarUrl;
}
// @todo FIXME: This should be better encapsulated
// ripped from OStatus via oauthstore.php (for old OMB client)
- $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
+ $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
try {
if (!copy($url, $temp_filename)) {
// TRANS: Exception thrown when fetching an avatar from a URL fails.
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for XCache variable cache
+ *
+ * PHP version 5
+ *
+ * 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 Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 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/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use XCache's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses XCache's variable cache.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 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/
+ */
+class XCachePlugin extends Plugin
+{
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheGet(&$key, &$value)
+ {
+ if (!xcache_isset($key)) {
+ $value = false;
+ } else {
+ $value = xcache_get($key);
+ $value = unserialize($value);
+ }
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag (passed through to Memcache)
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $success = xcache_set($key, serialize($value));
+
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $success = xcache_unset($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onPluginVersion(array &$versions)
+ {
+ $versions[] = array('name' => 'XCache',
+ 'version' => GNUSOCIAL_VERSION,
+ 'author' => 'Craig Andrews',
+ 'homepage' => 'http://status.net/wiki/Plugin:XCache',
+ 'rawdescription' =>
+ // TRANS: Plugin description.
+ _m('Use the <a href="http://xcache.lighttpd.net/">XCache</a> variable cache to cache query results.'));
+ return true;
+ }
+}
*
* @return boolean hook return
*/
- function onGetValidDaemons(&$daemons)
+ function onGetValidDaemons(array &$daemons)
{
if( isset($this->server) &&
isset($this->port) &&
{
// Process the queue for as long as needed
try {
- common_log(LOG_DEBUG, "Servicing the XMPP queue.");
+ common_debug("Servicing the XMPP queue.");
$this->stats('xmpp_process');
$this->conn->processTime(0);
} catch (XMPPHP_Exception $e) {
$this->pingid++;
}
- common_log(LOG_DEBUG, "Sending ping #{$this->pingid}");
+ common_debug("Sending ping #{$this->pingid}");
$this->conn->send("<iq from='{" . $this->plugin->daemonScreenname() . "}' to='{$this->plugin->server}' id='ping_{$this->pingid}' type='get'><ping xmlns='urn:xmpp:ping'/></iq>");
$this->lastping = $now;
return true;
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Yammer import administration panel
+ *
+ * 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 Settings
+ * @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);
+}
+
+class YammeradminpanelAction extends AdminPanelAction
+{
+ private $runner;
+
+ /**
+ * Returns the page title
+ *
+ * @return string page title
+ */
+ function title()
+ {
+ // TRANS: Page title for Yammer import administration panel.
+ return _m('Yammer Import');
+ }
+
+ /**
+ * Instructions for using this form.
+ *
+ * @return string instructions
+ */
+ function getInstructions()
+ {
+ // TRANS: Instructions for Yammer import administration panel.
+ return _m('This Yammer import tool is still undergoing testing, ' .
+ 'and is incomplete in some areas. ' .
+ 'Currently user subscriptions and group memberships are not ' .
+ 'transferred; in the future this may be supported for ' .
+ 'imports done by verified administrators on the Yammer side.');
+ }
+
+ function prepare(array $args=array())
+ {
+ $ok = parent::prepare($args);
+
+ $this->subaction = $this->trimmed('subaction');
+ $this->runner = YammerRunner::init();
+
+ return $ok;
+ }
+
+ function handle(array $args=array())
+ {
+ // @fixme move this to saveSettings and friends?
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ StatusNet::setApi(true); // short error pages :P
+ $this->checkSessionToken();
+ if ($this->subaction == 'change-apikey') {
+ $form = new YammerApiKeyForm($this);
+ } else if ($this->subaction == 'apikey') {
+ if ($this->saveKeys()) {
+ $form = new YammerAuthInitForm($this, $this->runner);
+ } else {
+ $form = new YammerApiKeyForm($this);
+ }
+ } else if ($this->subaction == 'authinit') {
+ // hack
+ if ($this->arg('change-apikey')) {
+ $form = new YammerApiKeyForm($this);
+ } else {
+ $url = $this->runner->requestAuth();
+ $form = new YammerAuthVerifyForm($this, $this->runner);
+ }
+ } else if ($this->subaction == 'authverify') {
+ $this->runner->saveAuthToken($this->trimmed('verify_token'));
+
+ // Haho! Now we can make THE FUN HAPPEN
+ $this->runner->startBackgroundImport();
+
+ $form = new YammerProgressForm($this, $this->runner);
+ } else if ($this->subaction == 'pause-import') {
+ // TRANS: Error message about an import job being paused from the admin panel.
+ $this->runner->recordError(_m('Paused from admin panel.'));
+ $form = $this->statusForm();
+ } else if ($this->subaction == 'continue-import') {
+ $this->runner->clearError();
+ $this->runner->startBackgroundImport();
+ $form = $this->statusForm();
+ } else if ($this->subaction == 'abort-import') {
+ $this->runner->reset();
+ $form = $this->statusForm();
+ } else if ($this->subaction == 'progress') {
+ $form = $this->statusForm();
+ } else {
+ // TRANS: Client exception thrown when encountering an unhandled sub action.
+ throw new ClientException(_m('Invalid POST'));
+ }
+ return $this->showAjaxForm($form);
+ }
+ return parent::handle($args);
+ }
+
+ function saveKeys()
+ {
+ $key = $this->trimmed('consumer_key');
+ $secret = $this->trimmed('consumer_secret');
+ Config::save('yammer', 'consumer_key', $key);
+ Config::save('yammer', 'consumer_secret', $secret);
+
+ return !empty($key) && !empty($secret);
+ }
+
+ function showAjaxForm($form)
+ {
+ $this->startHTML('text/xml;charset=utf-8');
+ $this->elementStart('head');
+ // TRANS: Page title for Yammer import administration panel.
+ $this->element('title', null, _m('Yammer import'));
+ $this->elementEnd('head');
+ $this->elementStart('body');
+ $form->show();
+ $this->elementEnd('body');
+ $this->endHTML();
+ }
+
+ /**
+ * Fetch the appropriate form for our current state.
+ * @return Form
+ */
+ function statusForm()
+ {
+ if (!(common_config('yammer', 'consumer_key'))
+ || !(common_config('yammer', 'consumer_secret'))) {
+ return new YammerApiKeyForm($this);
+ }
+ switch($this->runner->state())
+ {
+ case 'init':
+ return new YammerAuthInitForm($this, $this->runner);
+ case 'requesting-auth':
+ return new YammerAuthVerifyForm($this, $this->runner);
+ default:
+ return new YammerProgressForm($this, $this->runner);
+ }
+ }
+
+ /**
+ * Show the Yammer admin panel form
+ *
+ * @return void
+ */
+ function showForm()
+ {
+ $this->elementStart('fieldset');
+ $this->statusForm()->show();
+ $this->elementEnd('fieldset');
+ }
+
+ function showStylesheets()
+ {
+ parent::showStylesheets();
+ $this->cssLink(Plugin::staticPath('YammerImport', 'css/admin.css'), null, 'screen, projection, tv');
+ }
+
+ function showScripts()
+ {
+ parent::showScripts();
+ $this->script(Plugin::staticPath('YammerImport', 'js/yammer-admin.js'));
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Yammer import administration panel
+ *
+ * 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 Settings
+ * @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);
+}
+
+class YammerauthAction extends AdminPanelAction
+{
+ /**
+ * Show the Yammer admin panel form
+ *
+ * @return void
+ */
+ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $this->verify_token = $this->trim('verify_token');
+ }
+
+ /**
+ * Handle request
+ *
+ * Does the subscription and returns results.
+ *
+ * @param Array $args unused.
+ *
+ * @return void
+ */
+ function handle(array $args=array())
+ {
+ if ($this->verify_token) {
+ $runner->saveAuthToken($this->verify_token);
+ $form = new YammerAuthProgressForm();
+ } else {
+ $url = $runner->requestAuth();
+ $form = new YammerAuthVerifyForm($this, $url);
+ }
+
+ $this->startHTML('text/xml;charset=utf-8');
+ $this->elementStart('head');
+ // TRANS: Page title for Yammer administration panel.
+ $this->element('title', null, _m('Connect to Yammer'));
+ $this->elementEnd('head');
+ $this->elementStart('body');
+ $form->show();
+ $this->elementEnd('body');
+ $this->endHTML();
+ }
+}
--- /dev/null
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, 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/>.
+ */
+
+/**
+ * Basic client class for Yammer's OAuth/JSON API.
+ *
+ * Depends on Favorite plugin
+ *
+ * @package YammerImportPlugin
+ * @author Brion Vibber <brion@status.net>
+ */
+class YammerImporter
+{
+ protected $client;
+
+ function __construct(SNYammerClient $client)
+ {
+ $this->client = $client;
+ }
+
+ /**
+ * Load or create an imported profile from Yammer data.
+ *
+ * @param object $item loaded JSON data for Yammer importer
+ * @return Profile
+ */
+ function importUser($item)
+ {
+ $data = $this->prepUser($item);
+ $nickname = $data['options']['nickname'];
+
+ $profileId = $this->findImportedUser($data['orig_id']);
+ if ($profileId) {
+ return Profile::getKV('id', $profileId);
+ } else {
+ $user = User::getKV('nickname', $nickname);
+
+ if ($user instanceof User) {
+ common_log(LOG_WARNING, "Copying Yammer profile info onto existing user $nickname");
+ $profile = $user->getProfile();
+ $this->savePropertiesOn($profile, $data['options'],
+ array('fullname', 'homepage', 'bio', 'location'));
+ } else {
+ $user = User::register($data['options']);
+ $profile = $user->getProfile();
+ }
+
+ if ($data['avatar']) {
+ try {
+ $this->saveAvatar($data['avatar'], $profile);
+ } catch (Exception $e) {
+ common_log(LOG_ERR, "Error importing Yammer avatar: " . $e->getMessage());
+ }
+ }
+ $this->recordImportedUser($data['orig_id'], $profile->id);
+ return $profile;
+ }
+ }
+
+ /**
+ * Load or create an imported group from Yammer data.
+ *
+ * @param object $item loaded JSON data for Yammer importer
+ * @return User_group
+ */
+ function importGroup($item)
+ {
+ $data = $this->prepGroup($item);
+ $nickname = $data['options']['nickname'];
+
+ $groupId = $this->findImportedGroup($data['orig_id']);
+ if ($groupId) {
+ return User_group::getKV('id', $groupId);
+ } else {
+ $local = Local_group::getKV('nickname', $nickname);
+ if ($local) {
+ common_log(LOG_WARNING, "Copying Yammer group info onto existing group $nickname");
+ $group = User_group::getKV('id', $local->group_id);
+ $this->savePropertiesOn($group, $data['options'],
+ array('fullname', 'description'));
+ } else {
+ $group = User_group::register($data['options']);
+ }
+ if ($data['avatar']) {
+ try {
+ $this->saveAvatar($data['avatar'], $group);
+ } catch (Exception $e) {
+ common_log(LOG_ERR, "Error importing Yammer avatar: " . $e->getMessage());
+ }
+ }
+ $this->recordImportedGroup($data['orig_id'], $group->id);
+ return $group;
+ }
+ }
+
+ private function savePropertiesOn($target, $options, $propList)
+ {
+ $changed = 0;
+ $orig = clone($target);
+ foreach ($propList as $prop) {
+ if (!empty($options[$prop]) && $target->$prop != $options[$prop]) {
+ $target->$prop = $options[$prop];
+ $changed++;
+ }
+ }
+ $target->update($orig);
+ }
+
+ /**
+ * Load or create an imported notice from Yammer data.
+ *
+ * @param object $item loaded JSON data for Yammer importer
+ * @return Notice
+ */
+ function importNotice($item)
+ {
+ $data = $this->prepNotice($item);
+
+ $noticeId = $this->findImportedNotice($data['orig_id']);
+ if ($noticeId) {
+ return Notice::getKV('id', $noticeId);
+ } else {
+ $notice = Notice::getKV('uri', $data['options']['uri']);
+ $content = $data['content'];
+ $user = User::getKV($data['profile']);
+
+ // Fetch file attachments and add the URLs...
+ $uploads = array();
+ foreach ($data['attachments'] as $url) {
+ try {
+ $upload = $this->saveAttachment($url, $user);
+ $content .= ' ' . $upload->shortUrl();
+ $uploads[] = $upload;
+ } catch (Exception $e) {
+ common_log(LOG_ERR, "Error importing Yammer attachment: " . $e->getMessage());
+ }
+ }
+
+ // Here's the meat! Actually save the dang ol' notice.
+ $notice = Notice::saveNew($user->id,
+ $content,
+ $data['source'],
+ $data['options']);
+
+ // Save "likes" as favorites...
+ foreach ($data['faves'] as $nickname) {
+ $user = User::getKV('nickname', $nickname);
+ if ($user instanceof User) {
+ try {
+ Fave::addNew($user->getProfile(), $notice);
+ } catch (Exception $e) {
+ // failed, let's move to the next
+ common_debug('YammerImport failed favoriting a notice: '.$e->getMessage());
+ }
+ }
+ }
+
+ // And finally attach the upload records...
+ foreach ($uploads as $upload) {
+ $upload->attachToNotice($notice);
+ }
+ $this->recordImportedNotice($data['orig_id'], $notice->id);
+ return $notice;
+ }
+ }
+
+ /**
+ * Pull relevant info out of a Yammer data record for a user import.
+ *
+ * @param array $item
+ * @return array
+ */
+ function prepUser($item)
+ {
+ if ($item['type'] != 'user') {
+ // TRANS: Exception thrown when a non-user item type is used, but expected.
+ throw new Exception(_m('Wrong item type sent to Yammer user import processing.'));
+ }
+
+ $origId = $item['id'];
+ $origUrl = $item['url'];
+
+ // @fixme check username rules?
+
+ $options['nickname'] = $item['name'];
+ $options['fullname'] = trim($item['full_name']);
+
+ // Avatar... this will be the "_small" variant.
+ // Remove that (pre-extension) suffix to get the orig-size image.
+ $avatar = $item['mugshot_url'];
+
+ // The following info is only available in full data, not in the reference version.
+
+ // There can be extensive contact info, but for now we'll only pull the primary email.
+ if (isset($item['contact'])) {
+ foreach ($item['contact']['email_addresses'] as $addr) {
+ if ($addr['type'] == 'primary') {
+ $options['email'] = $addr['address'];
+ $options['email_confirmed'] = true;
+ break;
+ }
+ }
+ }
+
+ // There can be multiple external URLs; for now pull the first one as home page.
+ if (isset($item['external_urls'])) {
+ foreach ($item['external_urls'] as $url) {
+ if (common_valid_http_url($url)) {
+ $options['homepage'] = $url;
+ break;
+ }
+ }
+ }
+
+ // Combine a few bits into the bio...
+ $bio = array();
+ if (!empty($item['job_title'])) {
+ $bio[] = $item['job_title'];
+ }
+ if (!empty($item['summary'])) {
+ $bio[] = $item['summary'];
+ }
+ if (!empty($item['expertise'])) {
+ // TRANS: Used as a prefix for the Yammer expertise field contents.
+ $bio[] = _m('Expertise:') . ' ' . $item['expertise'];
+ }
+ $options['bio'] = implode("\n\n", $bio);
+
+ // Pull raw location string, may be lookupable
+ if (!empty($item['location'])) {
+ $options['location'] = $item['location'];
+ }
+
+ // Timezone is in format like 'Pacific Time (US & Canada)'
+ // We need to convert that to a zone id. :P
+ // @fixme timezone not yet supported at registration time :)
+ if (!empty($item['timezone'])) {
+ $tz = $this->timezone($item['timezone']);
+ if ($tz) {
+ $options['timezone'] = $tz;
+ }
+ }
+
+ return array('orig_id' => $origId,
+ 'orig_url' => $origUrl,
+ 'avatar' => $avatar,
+ 'options' => $options);
+
+ }
+
+ /**
+ * Pull relevant info out of a Yammer data record for a group import.
+ *
+ * @param array $item
+ * @return array
+ */
+ function prepGroup($item)
+ {
+ if ($item['type'] != 'group') {
+ // TRANS: Exception thrown when a non-group item type is used, but expected.
+ throw new Exception(_m('Wrong item type sent to Yammer group import processing.'));
+ }
+
+ $origId = $item['id'];
+ $origUrl = $item['url'];
+
+ $privacy = $item['privacy']; // Warning! only public groups in SN so far
+
+ $options['nickname'] = $item['name'];
+ $options['fullname'] = $item['full_name'];
+ $options['description'] = $item['description'];
+ $options['created'] = $this->timestamp($item['created_at']);
+
+ $avatar = $item['mugshot_url']; // as with user profiles...
+
+ $options['mainpage'] = common_local_url('showgroup',
+ array('nickname' => $options['nickname']));
+
+ // Set some default vals or User_group::register will whine
+ $options['homepage'] = '';
+ $options['location'] = '';
+ $options['aliases'] = array();
+ // @todo FIXME: What about admin user for the group?
+
+ $options['local'] = true;
+ return array('orig_id' => $origId,
+ 'orig_url' => $origUrl,
+ 'options' => $options,
+ 'avatar' => $avatar);
+ }
+
+ /**
+ * Pull relevant info out of a Yammer data record for a notice import.
+ *
+ * @param array $item
+ * @return array
+ */
+ function prepNotice($item)
+ {
+ if (isset($item['type']) && $item['type'] != 'message') {
+ // TRANS: Exception thrown when a non-message item type is used, but expected.
+ throw new Exception(_m('Wrong item type sent to Yammer message import processing.'));
+ }
+
+ $origId = $item['id'];
+ $origUrl = $item['url'];
+
+ $profile = $this->findImportedUser($item['sender_id']);
+ $content = $item['body']['plain'];
+ $source = 'yammer';
+ $options = array();
+
+ if ($item['replied_to_id']) {
+ $replyTo = $this->findImportedNotice($item['replied_to_id']);
+ if ($replyTo) {
+ $options['reply_to'] = $replyTo;
+ }
+ }
+ $options['created'] = $this->timestamp($item['created_at']);
+
+ if (!empty($item['group_id'])) {
+ $groupId = $this->findImportedGroup($item['group_id']);
+ if ($groupId) {
+ $options['groups'] = array($groupId);
+
+ // @fixme if we see a group link inline, don't add this?
+ $group = User_group::getKV('id', $groupId);
+ if ($group instanceof User_group) {
+ $content .= ' !' . $group->nickname;
+ }
+ }
+ }
+
+ $faves = array();
+ foreach ($item['liked_by']['names'] as $liker) {
+ // "permalink" is the username. wtf?
+ $faves[] = $liker['permalink'];
+ }
+
+ $attachments = array();
+ foreach ($item['attachments'] as $attach) {
+ if ($attach['type'] == 'image' || $attach['type'] == 'file') {
+ $attachments[] = $attach[$attach['type']]['url'];
+ } else {
+ common_log(LOG_WARNING, "Unrecognized Yammer attachment type: " . $attach['type']);
+ }
+ }
+
+ return array('orig_id' => $origId,
+ 'orig_url' => $origUrl,
+ 'profile' => $profile,
+ 'content' => $content,
+ 'source' => $source,
+ 'options' => $options,
+ 'faves' => $faves,
+ 'attachments' => $attachments);
+ }
+
+ private function findImportedUser($origId)
+ {
+ $map = Yammer_user::getKV('id', $origId);
+ return $map ? $map->user_id : null;
+ }
+
+ private function findImportedGroup($origId)
+ {
+ $map = Yammer_group::getKV('id', $origId);
+ return $map ? $map->group_id : null;
+ }
+
+ private function findImportedNotice($origId)
+ {
+ $map = Yammer_notice::getKV('id', $origId);
+ return $map ? $map->notice_id : null;
+ }
+
+ private function recordImportedUser($origId, $userId)
+ {
+ Yammer_user::record($origId, $userId);
+ }
+
+ private function recordImportedGroup($origId, $groupId)
+ {
+ Yammer_group::record($origId, $groupId);
+ }
+
+ private function recordImportedNotice($origId, $noticeId)
+ {
+ Yammer_notice::record($origId, $noticeId);
+ }
+
+ /**
+ * Normalize timestamp format.
+ * @param string $ts
+ * @return string
+ */
+ private function timestamp($ts)
+ {
+ return common_sql_date(strtotime($ts));
+ }
+
+ private function timezone($tz)
+ {
+ // Blaaaaaarf!
+ $known = array('Pacific Time (US & Canada)' => 'America/Los_Angeles',
+ 'Eastern Time (US & Canada)' => 'America/New_York');
+ if (array_key_exists($tz, $known)) {
+ return $known[$tz];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Download and update given avatar image
+ *
+ * @param string $url
+ * @param mixed $dest either a Profile or User_group object
+ * @throws Exception in various failure cases
+ */
+ private function saveAvatar($url, $dest)
+ {
+ // Yammer API data mostly gives us the small variant.
+ // Try hitting the source image if we can!
+ // @fixme no guarantee of this URL scheme I think.
+ $url = preg_replace('/_small(\..*?)$/', '$1', $url);
+
+ if (!common_valid_http_url($url)) {
+ // TRANS: Server exception thrown when an avatar URL is invalid.
+ // TRANS: %s is the invalid avatar URL.
+ throw new ServerException(sprintf(_m('Invalid avatar URL %s.'), $url));
+ }
+
+ // @fixme this should be better encapsulated
+ // ripped from oauthstore.php (for old OMB client)
+ $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
+ try {
+ if (!copy($url, $temp_filename)) {
+ // TRANS: Server exception thrown when an avatar could not be fetched.
+ // TRANS: %s is the failed avatar URL.
+ throw new ServerException(sprintf(_m('Unable to fetch avatar from %s.'), $url));
+ }
+
+ $id = $dest->id;
+ // @fixme should we be using different ids?
+ $imagefile = new ImageFile($id, $temp_filename);
+ $filename = Avatar::filename($id,
+ image_type_to_extension($imagefile->type),
+ null,
+ common_timestamp());
+ rename($temp_filename, Avatar::path($filename));
+ } catch (Exception $e) {
+ unlink($temp_filename);
+ throw $e;
+ }
+ // @fixme hardcoded chmod is lame, but seems to be necessary to
+ // keep from accidentally saving images from command-line (queues)
+ // that can't be read from web server, which causes hard-to-notice
+ // problems later on:
+ //
+ // http://status.net/open-source/issues/2663
+ chmod(Avatar::path($filename), 0644);
+
+ $dest->setOriginal($filename);
+ }
+
+ /**
+ * Fetch an attachment from Yammer and save it into our system.
+ * Unlike avatars, the attachment URLs are guarded by authentication,
+ * so we need to run the HTTP hit through our OAuth API client.
+ *
+ * @param string $url
+ * @param User $user
+ * @return MediaFile
+ *
+ * @throws Exception on low-level network or HTTP error
+ */
+ private function saveAttachment($url, User $user)
+ {
+ // Fetch the attachment...
+ // WARNING: file must fit in memory here :(
+ $body = $this->client->fetchUrl($url);
+
+ // Save to a temporary file and shove it into our file-attachment space...
+ $temp = tmpfile();
+ fwrite($temp, $body);
+ try {
+ $upload = MediaFile::fromFilehandle($temp, $user->getProfile());
+ fclose($temp);
+ return $upload;
+ } catch (Exception $e) {
+ fclose($temp);
+ throw $e;
+ }
+ }
+}
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function print_all_sites() {
END_OF_EXPORTACTIVITYSTREAM_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
$user = getUser();
END_OF_CHECKSCHEMA_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function tableDefs()
{
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (!have_option('y', 'yes')) {
print "About to delete locally generated thumbnails to allow regeneration. Are you sure? [y/N] ";
END_OF_DELETEUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
END_OF_CLEARCACHE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$karg = get_option_value('k', 'key');
END_OF_USERROLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function interpretCommand($user, $body)
{
+++ /dev/null
-<?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/>.
- */
-
-// -*- mode: php -*-
-
-# Abort if called from a web server
-
-if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
- print "This script must be run from the command line\n";
- exit();
-}
-
-define('GNUSOCIAL', true);
-define('STATUSNET', true); //compatibility
-
-define('GNUSOCIAL_CLI', true); // to know we're in a CLI environment
-
-// Set various flags so we don't time out on long-running processes
-
-ini_set("max_execution_time", "0");
-ini_set("max_input_time", "0");
-set_time_limit(0);
-mb_internal_encoding('UTF-8');
-error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
-
-// Add extlib to our path so we can get Console_Getopt
-
-$_extra_path = array(INSTALLDIR.'/extlib/');
-
-set_include_path(implode(PATH_SEPARATOR, $_extra_path) . PATH_SEPARATOR . get_include_path());
-
-require_once 'Console/Getopt.php';
-
-// Note: $shortoptions and $longoptions should be pre-defined!
-
-$_default_shortoptions = 'qvhc:s:p:';
-
-$_default_longoptions = array('quiet', 'verbose', 'help', 'conf=', 'server=', 'path=');
-
-if (isset($shortoptions)) {
- $shortoptions .= $_default_shortoptions;
-} else {
- $shortoptions = $_default_shortoptions;
-}
-
-if (isset($longoptions)) {
- $longoptions = array_merge($longoptions, $_default_longoptions);
-} else {
- $longoptions = $_default_longoptions;
-}
-
-$parser = new Console_Getopt();
-
-$result = $parser->getopt($argv, $shortoptions, $longoptions);
-
-if (PEAR::isError($result)) {
- print $result->getMessage()."\n";
- exit(1);
-} else {
- list($options, $args) = $result;
-}
-
-function show_help()
-{
- global $helptext;
-
- $_default_help_text = <<<END_OF_DEFAULT
- General options:
-
- -q --quiet Quiet (little output)
- -v --verbose Verbose (lots of output)
- -c --conf=<filename> Use <filename> as config file
- -s --server=<name> Use <name> as server name
- -p --path=<path> Use <path> as path name
- -h --help Show this message and quit.
-
-END_OF_DEFAULT;
- if (isset($helptext)) {
- print $helptext;
- }
- print $_default_help_text;
- exit(0);
-}
-
-foreach ($options as $option) {
-
- switch ($option[0]) {
- case '--server':
- case 's':
- $server = $option[1];
- break;
-
- case '--path':
- case 'p':
- $path = $option[1];
- break;
-
- case '--conf':
- case 'c':
- $conffile = $option[1];
- break;
-
- case '--help':
- case 'h':
- show_help();
- }
-}
-
-require_once INSTALLDIR . '/lib/common.php';
-
-set_error_handler('common_error_handler');
-
-// Set up the language infrastructure so we can localize anything that
-// needs to be sent out to users, such as mail notifications.
-common_init_language();
-
-function _make_matches($opt, $alt)
-{
- $matches = array();
-
- if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
- $matches[] = '--'.$opt;
- } else {
- $matches[] = $opt;
- }
-
- if (!empty($alt)) {
- if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
- $matches[] = '--'.$alt;
- } else {
- $matches[] = $alt;
- }
- }
-
- return $matches;
-}
-
-function have_option($opt, $alt=null)
-{
- global $options;
-
- $matches = _make_matches($opt, $alt);
-
- foreach ($options as $option) {
- if (in_array($option[0], $matches)) {
- return true;
- }
- }
-
- return false;
-}
-
-function get_option_value($opt, $alt=null)
-{
- global $options;
-
- $matches = _make_matches($opt, $alt);
-
- foreach ($options as $option) {
- if (in_array($option[0], $matches)) {
- return $option[1];
- }
- }
-
- return null;
-}
-
-class NoUserArgumentException extends Exception
-{
-}
-
-function getUser()
-{
- $user = null;
-
- if (have_option('i', 'id')) {
- $id = get_option_value('i', 'id');
- $user = User::getKV('id', $id);
- if (empty($user)) {
- throw new Exception("Can't find user with id '$id'.");
- }
- } else if (have_option('n', 'nickname')) {
- $nickname = get_option_value('n', 'nickname');
- $user = User::getKV('nickname', $nickname);
- if (empty($user)) {
- throw new Exception("Can't find user with nickname '$nickname'");
- }
- } else {
- throw new NoUserArgumentException("No user argument specified.");
- }
-
- return $user;
-}
-
-/** "Printf not quiet" */
-
-function printfnq()
-{
- if (have_option('q', 'quiet')) {
- return null;
- }
-
- $cargs = func_num_args();
-
- if ($cargs == 0) {
- return 0;
- }
-
- $args = func_get_args();
- $format = array_shift($args);
-
- return vprintf($format, $args);
-}
-
-/** "Print when verbose" */
-
-function printfv()
-{
- if (!have_option('v', 'verbose')) {
- return null;
- }
-
- $cargs = func_num_args();
-
- if ($cargs == 0) {
- return 0;
- }
-
- $args = func_get_args();
- $format = array_shift($args);
-
- return vprintf($format, $args);
-}
--- /dev/null
+<?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/>.
+ */
+
+// -*- mode: php -*-
+
+# Abort if called from a web server
+
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+ print "This script must be run from the command line\n";
+ exit();
+}
+
+define('GNUSOCIAL', true);
+define('STATUSNET', true); //compatibility
+
+define('GNUSOCIAL_CLI', true); // to know we're in a CLI environment
+
+// Set various flags so we don't time out on long-running processes
+
+ini_set("max_execution_time", "0");
+ini_set("max_input_time", "0");
+set_time_limit(0);
+mb_internal_encoding('UTF-8');
+error_reporting(0);
+# DEBUG: error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
+
+// Add extlib to our path so we can get Console_Getopt
+
+$_extra_path = array(INSTALLDIR.'/extlib/');
+
+set_include_path(implode(PATH_SEPARATOR, $_extra_path) . PATH_SEPARATOR . get_include_path());
+
+require_once 'Console/Getopt.php';
+
+// Note: $shortoptions and $longoptions should be pre-defined!
+
+$_default_shortoptions = 'qvhc:s:p:';
+
+$_default_longoptions = array('quiet', 'verbose', 'help', 'conf=', 'server=', 'path=');
+
+if (isset($shortoptions)) {
+ $shortoptions .= $_default_shortoptions;
+} else {
+ $shortoptions = $_default_shortoptions;
+}
+
+if (isset($longoptions)) {
+ $longoptions = array_merge($longoptions, $_default_longoptions);
+} else {
+ $longoptions = $_default_longoptions;
+}
+
+$parser = new Console_Getopt();
+
+$result = $parser->getopt($argv, $shortoptions, $longoptions);
+
+if (PEAR::isError($result)) {
+ print $result->getMessage()."\n";
+ exit(1);
+} else {
+ list($options, $args) = $result;
+}
+
+function show_help()
+{
+ global $helptext;
+
+ $_default_help_text = <<<END_OF_DEFAULT
+ General options:
+
+ -q --quiet Quiet (little output)
+ -v --verbose Verbose (lots of output)
+ -c --conf=<filename> Use <filename> as config file
+ -s --server=<name> Use <name> as server name
+ -p --path=<path> Use <path> as path name
+ -h --help Show this message and quit.
+
+END_OF_DEFAULT;
+ if (isset($helptext)) {
+ print $helptext;
+ }
+ print $_default_help_text;
+ exit(0);
+}
+
+foreach ($options as $option) {
+
+ switch ($option[0]) {
+ case '--server':
+ case 's':
+ $server = $option[1];
+ break;
+
+ case '--path':
+ case 'p':
+ $path = $option[1];
+ break;
+
+ case '--conf':
+ case 'c':
+ $conffile = $option[1];
+ break;
+
+ case '--help':
+ case 'h':
+ show_help();
+ }
+}
+
+require_once INSTALLDIR . '/lib/common.php';
+
+set_error_handler('common_error_handler');
+
+// Set up the language infrastructure so we can localize anything that
+// needs to be sent out to users, such as mail notifications.
+common_init_language();
+
+function _make_matches($opt, $alt)
+{
+ $matches = array();
+
+ if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
+ $matches[] = '--'.$opt;
+ } else {
+ $matches[] = $opt;
+ }
+
+ if (!empty($alt)) {
+ if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
+ $matches[] = '--'.$alt;
+ } else {
+ $matches[] = $alt;
+ }
+ }
+
+ return $matches;
+}
+
+function have_option($opt, $alt=null)
+{
+ global $options;
+
+ $matches = _make_matches($opt, $alt);
+
+ foreach ($options as $option) {
+ if (in_array($option[0], $matches)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function get_option_value($opt, $alt=null)
+{
+ global $options;
+
+ $matches = _make_matches($opt, $alt);
+
+ foreach ($options as $option) {
+ if (in_array($option[0], $matches)) {
+ return $option[1];
+ }
+ }
+
+ return null;
+}
+
+class NoUserArgumentException extends Exception
+{
+}
+
+function getUser()
+{
+ $user = null;
+
+ if (have_option('i', 'id')) {
+ $id = get_option_value('i', 'id');
+ $user = User::getKV('id', $id);
+ if (empty($user)) {
+ throw new Exception("Can't find user with id '$id'.");
+ }
+ } else if (have_option('n', 'nickname')) {
+ $nickname = get_option_value('n', 'nickname');
+ $user = User::getKV('nickname', $nickname);
+ if (empty($user)) {
+ throw new Exception("Can't find user with nickname '$nickname'");
+ }
+ } else {
+ throw new NoUserArgumentException("No user argument specified.");
+ }
+
+ return $user;
+}
+
+/** "Printf not quiet" */
+
+function printfnq()
+{
+ if (have_option('q', 'quiet')) {
+ return null;
+ }
+
+ $cargs = func_num_args();
+
+ if ($cargs == 0) {
+ return 0;
+ }
+
+ $args = func_get_args();
+ $format = array_shift($args);
+
+ return vprintf($format, $args);
+}
+
+/** "Print when verbose" */
+
+function printfv()
+{
+ if (!have_option('v', 'verbose')) {
+ return null;
+ }
+
+ $cargs = func_num_args();
+
+ if ($cargs == 0) {
+ return 0;
+ }
+
+ $args = func_get_args();
+ $format = array_shift($args);
+
+ return vprintf($format, $args);
+}
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
// Assume we're on a terminal if on Windows, otherwise posix_isatty tells us.
define('CONSOLE_INTERACTIVE', !function_exists('posix_isatty') || posix_isatty(0));
END_OF_CREATESIM_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
// XXX: make these command-line options
// Pick a random user to be the admin
- $n = rand(0, max($j - 1, 0));
+ $n = mt_rand(0, max($j - 1, 0));
$user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
$group = User_group::register(array('nickname' => sprintf('%s%d', $groupprefix, $i),
$options = array('scope' => Notice::defaultScope());
- $n = rand(0, $i - 1);
+ $n = mt_rand(0, $i - 1);
$user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
- $is_reply = rand(0, 1);
+ $is_reply = mt_rand(0, 1);
$content = testNoticeContent();
$stream = new InboxNoticeStream($user->getProfile(), $user->getProfile());
$notices = $stream->getNotices(0, 20);
if ($notices->N > 0) {
- $nval = rand(0, $notices->N - 1);
+ $nval = mt_rand(0, $notices->N - 1);
$notices->fetch(); // go to 0th
for ($i = 0; $i < $nval; $i++) {
$notices->fetch();
}
$options['reply_to'] = $notices->id;
- $dont_use_nickname = rand(0, 2);
+ $dont_use_nickname = mt_rand(0, 2);
if ($dont_use_nickname != 0) {
$rprofile = $notices->getProfile();
$content = "@".$rprofile->nickname." ".$content;
}
- $private_to_addressees = rand(0, 4);
+ $private_to_addressees = mt_rand(0, 4);
if ($private_to_addressees == 0) {
$options['scope'] |= Notice::ADDRESSEE_SCOPE;
}
}
} else {
- $is_directed = rand(0, 4);
+ $is_directed = mt_rand(0, 4);
if ($is_directed == 0) {
$subs = $user->getSubscribed(0, 100)->fetchAll();
if (count($subs) > 0) {
$seen = array();
- $f = rand(0, 9);
+ $f = mt_rand(0, 9);
if ($f <= 6) {
$addrs = 1;
} else if ($f <= 8) {
$addrs = 3;
}
for ($m = 0; $m < $addrs; $m++) {
- $x = rand(0, count($subs) - 1);
+ $x = mt_rand(0, count($subs) - 1);
if ($seen[$x]) {
continue;
}
$rprofile = $subs[$x];
$content = "@".$rprofile->nickname." ".$content;
}
- $private_to_addressees = rand(0, 4);
+ $private_to_addressees = mt_rand(0, 4);
if ($private_to_addressees == 0) {
$options['scope'] |= Notice::ADDRESSEE_SCOPE;
}
}
}
- $has_hash = rand(0, 2);
+ $has_hash = mt_rand(0, 2);
if ($has_hash == 0) {
- $hashcount = rand(0, 2);
+ $hashcount = mt_rand(0, 2);
for ($j = 0; $j < $hashcount; $j++) {
- $h = rand(0, $tagmax);
+ $h = mt_rand(0, $tagmax);
$content .= " #tag{$h}";
}
}
- $in_group = rand(0, 5);
+ $in_group = mt_rand(0, 5);
if ($in_group == 0) {
$groups = $user->getGroups();
if ($groups instanceof User_group) {
- $gval = rand(0, $groups->N - 1);
+ $gval = mt_rand(0, $groups->N - 1);
$groups->fetch(); // go to 0th
for ($i = 0; $i < $gval; $i++) {
$groups->fetch();
}
$options['groups'] = array($groups->id);
$content = "!".$groups->nickname." ".$content;
- $private_to_group = rand(0, 2);
+ $private_to_group = mt_rand(0, 2);
if ($private_to_group == 0) {
$options['scope'] |= Notice::GROUP_SCOPE;
}
}
}
- $private_to_site = rand(0, 4);
+ $private_to_site = mt_rand(0, 4);
if ($private_to_site == 0) {
$options['scope'] |= Notice::SITE_SCOPE;
{
global $userprefix;
- $n = rand(0, $i - 1);
+ $n = mt_rand(0, $i - 1);
$user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
$content = testNoticeContent();
return;
}
- $j = rand(0, count($friends) - 1);
+ $j = mt_rand(0, count($friends) - 1);
$other = $friends[$j];
function newSub($i)
{
global $userprefix;
- $f = rand(0, $i - 1);
+ $f = mt_rand(0, $i - 1);
$fromnick = sprintf('%s%d', $userprefix, $f);
throw new Exception("Can't find user '$fromnick'.");
}
- $t = rand(0, $i - 1);
+ $t = mt_rand(0, $i - 1);
if ($t == $f) {
$t++;
global $userprefix;
global $groupprefix;
- $userNumber = rand(0, $u - 1);
+ $userNumber = mt_rand(0, $u - 1);
$userNick = sprintf('%s%d', $userprefix, $userNumber);
throw new Exception("Can't find user '$fromnick'.");
}
- $groupNumber = rand(0, $g - 1);
+ $groupNumber = mt_rand(0, $g - 1);
$groupNick = sprintf('%s%d', $groupprefix, $groupNumber);
global $userprefix;
global $groupprefix;
- $userNumber = rand(0, $u - 1);
+ $userNumber = mt_rand(0, $u - 1);
$userNick = sprintf('%s%d', $userprefix, $userNumber);
// NB: it's OK to like your own stuff!
- $otherNumber = rand(0, $u - 1);
+ $otherNumber = mt_rand(0, $u - 1);
$otherNick = sprintf('%s%d', $userprefix, $otherNumber);
return;
}
- $idx = rand(0, count($notices) - 1);
+ $idx = mt_rand(0, count($notices) - 1);
$notice = $notices[$idx];
return "test notice content";
}
- $cnt = rand(3, 8);
+ $cnt = mt_rand(3, 8);
$ids = array_rand($words, $cnt);
for ($i = 0; $i < $events; $i++)
{
- $e = rand(0, $events);
+ $e = mt_rand(0, $events);
if ($e >= 0 && $e <= $ut) {
printfv("$i Creating user $n\n");
END_OF_DELETEGROUP_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
END_OF_DELETEUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
$template = file_get_contents(dirname(__FILE__) . '/doxygen.tmpl');
$template = strtr($template, $replacements);
-$templateFile = tempnam(sys_get_temp_dir(), 'statusnet-doxygen');
+$templateFile = tempnam(common_get_temp_dir(), 'statusnet-doxygen');
file_put_contents($templateFile, $template);
$cmd = "doxygen " . escapeshellarg($templateFile);
END_OF_CHECKSCHEMA_HELP;
$longoptions = array('diff', 'all', 'create', 'update', 'raw', 'checksum');
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function indentOptions($indent)
{
}
} else {
show_help($helptext);
-}
\ No newline at end of file
+}
END_OF_USERROLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
/**
* Find the highest profile_id currently listed in the notice table;
--- /dev/null
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+// Abort if called from a web server
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+ print "This script must be run from the command line\n";
+ exit();
+}
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+require_once(INSTALLDIR . '/scripts/commandline.inc.php');
+error_reporting(E_ALL | E_STRICT);
+
+$relative = common_path('group/');
+print('Searching for profiles with relative=' . $relative . ' ...' . PHP_EOL);
+
+$profile = new Profile();
+$profile->whereAdd("`profileurl` LIKE '" . $relative . "%'");
+$cnt = $profile->find();
+
+print('Found ' . $cnt . ' profiles.' . PHP_EOL);
+
+if ($cnt == 0) {
+ // Nothing to do
+ print('All profiles are fixed. :-)' . PHP_EOL);
+ exit;
+}
+
+$profiles = array();
+
+while ($profile->fetch()) {
+ array_push($profiles, "'" . $profile->nickname . "'");
+}
+
+// Cleanup
+unset($profile);
+
+print('Have ' . count($profiles) . ' profiles found.' . PHP_EOL);
+
+// Make sure both are equal
+assert(count($profiles) == $cnt);
+
+print('Looking for matching user groups without local groups ...' . PHP_EOL);
+
+$group = new User_group();
+$group->whereAdd("`nickname` IN (" . implode(', ', $profiles) . ") AND `uri` NOT LIKE '" . $relative . "%'");
+$cnt = $group->find();
+
+print('Found ' . $cnt . ' groups.' . PHP_EOL);
+
+while ($group->fetch()) {
+ print('Fixing profile for group #' . $group->id . ',nickname=' . $group->nickname . ' to ' . $group->uri . ' ...' . PHP_EOL);
+
+ if ($group->profile_id < 1) {
+ print('INCONSISTENCY - Group ' . $group->nickname . ' has no profile_id set. Cannot fix!' . PHP_EOL);
+ }
+
+ $profile = new Profile();
+ $profile->id = $group->profile_id;
+ $cnt2 = $profile->find();
+
+ if ($cnt2 == 0) {
+ print('INCONSISTENCY - Cannot find profile ' . $group->nickname . ' - skipped!' . PHP_EOL);
+ continue;
+ } elseif ($cnt2 > 1) {
+ print('INCONSISTENCY - Group ' . $group->nickname . ' has more than one (' . $cnt2 . ') profiles - skipped!' . PHP_EOL);
+ continue;
+ } else {
+ // Dummy fetch
+ $profile->fetch();
+ }
+
+ $original = clone($profile);
+ $profile->profileurl = $group->uri;
+
+ $result = $profile->update($original);
+ if (!$result) {
+ common_log_db_error($profile, 'UPDATE', __FILE__);
+ }
+}
END_OF_FLUSHROUTER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$cache = Cache::instance();
$cache->delete(Router::cacheKey());
-print "OK.\n";
\ No newline at end of file
+print "OK.\n";
END_OF_FLUSHSITE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$nickname = common_config('site', 'nickname');
print "Flushing cache for {$nickname}...";
$sn->decache();
-print "OK.\n";
\ No newline at end of file
+print "OK.\n";
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
echo common_config('daemon', 'piddir');
// No unnecessary error reporting to avoid invalid daemon names
error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE);
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$daemons = array();
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
print GNUSOCIAL_VERSION."\n";
END_OF_QUEUE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) != 2) {
show_help();
END_OF_IM_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
class ImDaemon extends SpawningDaemon
{
END_OF_IMPORTTWITTERATOM_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
function getAtomFeedDocument()
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
$user = getUser();
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
$user = getUser();
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
require_once INSTALLDIR.'/lib/mailhandler.php';
if (common_config('emailpost', 'enabled')) {
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$base = INSTALLDIR;
$encBase = escapeshellarg($base);
END_OF_MAKEGROUPADMIN_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$nickname = get_option_value('n', 'nickname');
$groupname = get_option_value('g', 'group');
END_OF_MOVEUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
END_OF_QUEUECTL_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function doSendControl($message, $event, $param='')
{
END_OF_QUEUE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
require_once(INSTALLDIR.'/lib/daemon.php');
require_once(INSTALLDIR.'/classes/Queue_item.php');
END_OF_REGISTERUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$nickname = get_option_value('n', 'nickname');
$password = get_option_value('w', 'password');
END_OF_RESTOREUSER_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
END_OF_USEREMAIL_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
END_OF_GC_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$maxlifetime = ini_get('session.gc_maxlifetime');
END_OF_SETCONFIG_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (empty($args)) {
if (have_option('a', 'all')) {
END_OF_PASSWORD_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) < 2) {
show_help();
END_OF_SETTAG_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) < 1) {
show_help();
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$karg = get_option_value('k');
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
foreach (StatusNet::getActivePlugins() as $plugin=>$args) {
echo "$plugin: ";
END_OF_SHOWTABLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (count($args) != 1) {
show_help();
fi
DIR=`dirname $0`
-DAEMONS=`php $DIR/getvaliddaemons.php $ARGSG`
+DAEMONS=`$DIR/getvaliddaemons.php $ARGSG`
for f in $DAEMONS; do
fi
SDIR=`dirname $0`
-DIR=`php $SDIR/getpiddir.php $SITE`
+DIR=`$SDIR/getpiddir.php $SITE`
-DAEMONS=`php $SDIR/getvaliddaemons.php $ARGSG`
+DAEMONS=`$SDIR/getvaliddaemons.php $ARGSG`
for f in $DAEMONS; do
f=$(basename $f .php)
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
ENDOFHELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$id_file = (count($args) > 1) ? $args[0] : 'ids.txt';
END_OF_UPDATELOCATION_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
try {
$user = null;
END_OF_UPDATEURLS_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function main()
{
END_OF_UPGRADE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
function main()
{
END_OF_USEREMAIL_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
END_OF_USERROLE_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
--- /dev/null
+Subproject commit 441a38c20487faf6078e70f1055f20a5412a2fa1
function setUp()
{
$user = User::getKV('nickname', 'userrightstestuser');
- if ($user) {
+
+ if ($user instanceof User) {
// Leftover from a broken test run?
$profile = $user->getProfile();
$user->delete();
$profile->delete();
}
+
$this->user = User::register(array('nickname' => 'userrightstestuser'));
+
if (!$this->user) {
throw new Exception("Couldn't register userrightstestuser");
}
END_OF_HELP;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
$user = get_option_value('n', 'nickname');
$pass = get_option_value('p', 'password');
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
require_once INSTALLDIR . '/extlib/OAuth.php';
$ini = parse_ini_file("oauth.ini");
END_OF_ETOKENS_HELP;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
$token = $secret = $verifier = null;
$token_secret = null;
$update = null;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
if (have_option('t', 'oauth_token')) {
$token = get_option_value('t', 'oauth_token');
$token = null;
$token_secret = null;
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
if (have_option('t', 'oauth_token')) {
$token = get_option_value('t', 'oauth_token');