Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
95e45bbeac
@ -41,7 +41,6 @@ class Cron {
|
|||||||
require_once('include/sharedwithme.php');
|
require_once('include/sharedwithme.php');
|
||||||
apply_updates();
|
apply_updates();
|
||||||
|
|
||||||
|
|
||||||
// expire any expired mail
|
// expire any expired mail
|
||||||
|
|
||||||
q("delete from mail where expires != '%s' and expires < %s ",
|
q("delete from mail where expires != '%s' and expires < %s ",
|
||||||
@ -93,6 +92,18 @@ class Cron {
|
|||||||
intval($rr['id'])
|
intval($rr['id'])
|
||||||
);
|
);
|
||||||
if($x) {
|
if($x) {
|
||||||
|
$z = q("select * from item where id = %d",
|
||||||
|
intval($message_id)
|
||||||
|
);
|
||||||
|
if($z) {
|
||||||
|
xchan_query($z);
|
||||||
|
$sync_item = fetch_post_tags($z);
|
||||||
|
build_sync_packet($sync_item[0]['uid'],
|
||||||
|
[
|
||||||
|
'item' => [ encode_item($sync_item[0],true) ]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
Master::Summon(array('Notifier','wall-new',$rr['id']));
|
Master::Summon(array('Notifier','wall-new',$rr['id']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ class Cron_weekly {
|
|||||||
|
|
||||||
call_hooks('cron_weekly',datetime_convert());
|
call_hooks('cron_weekly',datetime_convert());
|
||||||
|
|
||||||
|
|
||||||
z_check_cert();
|
z_check_cert();
|
||||||
|
|
||||||
require_once('include/hubloc.php');
|
require_once('include/hubloc.php');
|
||||||
|
@ -33,8 +33,9 @@ class Apps {
|
|||||||
$files = glob('addon/*/*.apd');
|
$files = glob('addon/*/*.apd');
|
||||||
if($files) {
|
if($files) {
|
||||||
foreach($files as $f) {
|
foreach($files as $f) {
|
||||||
$n = basename($f,'.apd');
|
$path = explode('/',$f);
|
||||||
if(plugin_is_installed($n)) {
|
$plugin = $path[1];
|
||||||
|
if(plugin_is_installed($plugin)) {
|
||||||
$x = self::parse_app_description($f,$translate);
|
$x = self::parse_app_description($f,$translate);
|
||||||
if($x) {
|
if($x) {
|
||||||
$ret[] = $x;
|
$ret[] = $x;
|
||||||
|
@ -248,7 +248,7 @@ class ThreadItem {
|
|||||||
$has_bookmarks = false;
|
$has_bookmarks = false;
|
||||||
if(is_array($item['term'])) {
|
if(is_array($item['term'])) {
|
||||||
foreach($item['term'] as $t) {
|
foreach($item['term'] as $t) {
|
||||||
if(!UNO && $t['type'] == TERM_BOOKMARK)
|
if(!UNO && $t['ttype'] == TERM_BOOKMARK)
|
||||||
$has_bookmarks = true;
|
$has_bookmarks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,8 +668,10 @@ class Events extends \Zotlabs\Web\Controller {
|
|||||||
'$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''),
|
'$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''),
|
||||||
'$calendar' => cal($y,$m,$links, ' eventcal'),
|
'$calendar' => cal($y,$m,$links, ' eventcal'),
|
||||||
'$events' => $events,
|
'$events' => $events,
|
||||||
'$upload' => t('Import'),
|
'$view_label' => t('View'),
|
||||||
'$submit' => t('Submit'),
|
'$month' => t('Month'),
|
||||||
|
'$week' => t('Week'),
|
||||||
|
'$day' => t('Day'),
|
||||||
'$prev' => t('Previous'),
|
'$prev' => t('Previous'),
|
||||||
'$next' => t('Next'),
|
'$next' => t('Next'),
|
||||||
'$today' => t('Today'),
|
'$today' => t('Today'),
|
||||||
|
@ -78,6 +78,8 @@ class Import_items extends \Zotlabs\Web\Controller {
|
|||||||
// logger('import: data: ' . print_r($data,true));
|
// logger('import: data: ' . print_r($data,true));
|
||||||
// print_r($data);
|
// print_r($data);
|
||||||
|
|
||||||
|
if(! is_array($data))
|
||||||
|
return;
|
||||||
|
|
||||||
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
|
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
|
||||||
$v1 = substr($data['compatibility']['database'],-4);
|
$v1 = substr($data['compatibility']['database'],-4);
|
||||||
|
@ -125,9 +125,9 @@ class New_channel extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'));
|
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*");
|
||||||
$nickhub = '@' . \App::get_hostname();
|
$nickhub = '@' . \App::get_hostname();
|
||||||
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub));
|
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*");
|
||||||
$privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" );
|
$privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" );
|
||||||
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles());
|
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles());
|
||||||
|
|
||||||
|
@ -180,6 +180,8 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
dbesc(datetime_convert()),
|
dbesc(datetime_convert()),
|
||||||
dbesc($channel['xchan_hash'])
|
dbesc($channel['xchan_hash'])
|
||||||
);
|
);
|
||||||
|
// Similarly, tell the nav bar to bypass the cache and update the avater image.
|
||||||
|
$_SESSION['reload_avatar'] = true;
|
||||||
|
|
||||||
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||||
|
|
||||||
|
@ -31,6 +31,19 @@ class Starred extends \Zotlabs\Web\Controller {
|
|||||||
intval($message_id)
|
intval($message_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$r = q("select * from item where id = %d",
|
||||||
|
intval($message_id)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
xchan_query($r);
|
||||||
|
$sync_item = fetch_post_tags($r);
|
||||||
|
build_sync_packet(local_channel(),[
|
||||||
|
'item' => [
|
||||||
|
encode_item($sync_item[0],true)
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
header('Content-type: application/json');
|
header('Content-type: application/json');
|
||||||
echo json_encode(array('result' => $item_starred));
|
echo json_encode(array('result' => $item_starred));
|
||||||
killme();
|
killme();
|
||||||
|
@ -130,8 +130,13 @@ class Tagger extends \Zotlabs\Web\Controller {
|
|||||||
store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid);
|
store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid);
|
||||||
$ret = post_activity_item($arr);
|
$ret = post_activity_item($arr);
|
||||||
|
|
||||||
if($ret['success'])
|
if($ret['success']) {
|
||||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id']));
|
build_sync_packet(local_channel(),
|
||||||
|
[
|
||||||
|
'item' => [ encode_item($ret['activity'],true) ]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
killme();
|
killme();
|
||||||
|
|
||||||
|
@ -30,6 +30,11 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||||||
return login();
|
return login();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(! feature_enabled(\App::$profile_uid,'wiki')) {
|
||||||
|
notice( t('Not found') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$tab = 'wiki';
|
$tab = 'wiki';
|
||||||
|
|
||||||
|
|
||||||
@ -138,7 +143,8 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||||||
$content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
|
$content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
|
||||||
// Render the Markdown-formatted page content in HTML
|
// Render the Markdown-formatted page content in HTML
|
||||||
require_once('library/markdown.php');
|
require_once('library/markdown.php');
|
||||||
$renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
$html = wiki_generate_toc(purify_html(Markdown(json_decode($content))));
|
||||||
|
$renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
||||||
$hide_editor = false;
|
$hide_editor = false;
|
||||||
$showPageControls = $wiki_editor;
|
$showPageControls = $wiki_editor;
|
||||||
$showNewWikiButton = $wiki_owner;
|
$showNewWikiButton = $wiki_owner;
|
||||||
@ -215,7 +221,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||||||
$content = $_POST['content'];
|
$content = $_POST['content'];
|
||||||
$resource_id = $_POST['resource_id'];
|
$resource_id = $_POST['resource_id'];
|
||||||
require_once('library/markdown.php');
|
require_once('library/markdown.php');
|
||||||
$html = purify_html(Markdown($content));
|
$html = wiki_generate_toc(purify_html(Markdown($content)));
|
||||||
$w = wiki_get_wiki($resource_id);
|
$w = wiki_get_wiki($resource_id);
|
||||||
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
|
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
|
||||||
$html = wiki_convert_links($html,$wikiURL);
|
$html = wiki_convert_links($html,$wikiURL);
|
||||||
|
@ -91,7 +91,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$contents = RedCollectionData($this->red_path, $this->auth);
|
$contents = $this->CollectionData($this->red_path, $this->auth);
|
||||||
return $contents;
|
return $contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||||||
return new Directory('/' . $modulename, $this->auth);
|
return new Directory('/' . $modulename, $this->auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth);
|
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth);
|
||||||
if ($x) {
|
if ($x) {
|
||||||
return $x;
|
return $x;
|
||||||
}
|
}
|
||||||
@ -431,8 +431,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth, true);
|
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth, true);
|
||||||
//logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
|
//logger('FileData returns: ' . print_r($x, true), LOGGER_DATA);
|
||||||
if ($x)
|
if ($x)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -565,4 +565,280 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||||||
$free
|
$free
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array with all Directory and File DAV\Node items for the given path.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $file path to a directory
|
||||||
|
* @param \Zotlabs\Storage\BasicAuth &$auth
|
||||||
|
* @returns null|array \Sabre\DAV\INode[]
|
||||||
|
* @throw \Sabre\DAV\Exception\Forbidden
|
||||||
|
* @throw \Sabre\DAV\Exception\NotFound
|
||||||
|
*/
|
||||||
|
|
||||||
|
function CollectionData($file, &$auth) {
|
||||||
|
$ret = array();
|
||||||
|
|
||||||
|
$x = strpos($file, '/cloud');
|
||||||
|
if ($x === 0) {
|
||||||
|
$file = substr($file, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a list of channel if we are not inside a channel
|
||||||
|
if ((! $file) || ($file === '/')) {
|
||||||
|
return $this->ChannelList($auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = trim($file, '/');
|
||||||
|
$path_arr = explode('/', $file);
|
||||||
|
|
||||||
|
if (! $path_arr)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$channel_name = $path_arr[0];
|
||||||
|
|
||||||
|
$r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' LIMIT 1",
|
||||||
|
dbesc($channel_name)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! $r)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$channel_id = $r[0]['channel_id'];
|
||||||
|
$perms = permissions_sql($channel_id);
|
||||||
|
|
||||||
|
$auth->owner_id = $channel_id;
|
||||||
|
|
||||||
|
$path = '/' . $channel_name;
|
||||||
|
|
||||||
|
$folder = '';
|
||||||
|
$errors = false;
|
||||||
|
$permission_error = false;
|
||||||
|
|
||||||
|
for ($x = 1; $x < count($path_arr); $x++) {
|
||||||
|
$r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1",
|
||||||
|
dbesc($folder),
|
||||||
|
dbesc($path_arr[$x]),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
if (! $r) {
|
||||||
|
// path wasn't found. Try without permissions to see if it was the result of permissions.
|
||||||
|
$errors = true;
|
||||||
|
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1",
|
||||||
|
dbesc($folder),
|
||||||
|
basename($path_arr[$x]),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
if ($r) {
|
||||||
|
$permission_error = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($r && intval($r[0]['is_dir'])) {
|
||||||
|
$folder = $r[0]['hash'];
|
||||||
|
$path = $path . '/' . $r[0]['filename'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
if ($permission_error) {
|
||||||
|
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new DAV\Exception\NotFound('A component of the request file path could not be found.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should no longer be needed since we just returned errors for paths not found
|
||||||
|
if ($path !== '/' . $file) {
|
||||||
|
logger("Path mismatch: $path !== /$file");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||||
|
$prefix = 'DISTINCT ON (filename)';
|
||||||
|
$suffix = 'ORDER BY filename';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$prefix = '';
|
||||||
|
$suffix = 'GROUP BY filename';
|
||||||
|
}
|
||||||
|
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
|
||||||
|
dbesc($folder),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($r as $rr) {
|
||||||
|
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
|
||||||
|
if (intval($rr['is_dir'])) {
|
||||||
|
$ret[] = new Directory($path . '/' . $rr['filename'], $auth);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ret[] = new File($path . '/' . $rr['filename'], $rr, $auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns an array with viewable channels.
|
||||||
|
*
|
||||||
|
* Get a list of Directory objects with all the channels where the visitor
|
||||||
|
* has <b>view_storage</b> perms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param BasicAuth &$auth
|
||||||
|
* @return array Directory[]
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ChannelList(&$auth) {
|
||||||
|
$ret = array();
|
||||||
|
|
||||||
|
$r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0
|
||||||
|
AND channel_system = 0 AND NOT (channel_pageflags & %d)>0",
|
||||||
|
intval(PAGE_HIDDEN)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($r) {
|
||||||
|
foreach ($r as $rr) {
|
||||||
|
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
|
||||||
|
logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA);
|
||||||
|
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
|
||||||
|
$ret[] = new Directory('/cloud/' . $rr['channel_address'], $auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* path to file or directory
|
||||||
|
* @param BasicAuth &$auth
|
||||||
|
* @param boolean $test (optional) enable test mode
|
||||||
|
* @return File|Directory|boolean|null
|
||||||
|
* @throw \Sabre\DAV\Exception\Forbidden
|
||||||
|
*/
|
||||||
|
|
||||||
|
function FileData($file, &$auth, $test = false) {
|
||||||
|
logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA);
|
||||||
|
|
||||||
|
$x = strpos($file, '/cloud');
|
||||||
|
if ($x === 0) {
|
||||||
|
$file = substr($file, 6);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$x = strpos($file,'/dav');
|
||||||
|
if($x === 0)
|
||||||
|
$file = substr($file,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((! $file) || ($file === '/')) {
|
||||||
|
return new Directory('/', $auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = trim($file, '/');
|
||||||
|
|
||||||
|
$path_arr = explode('/', $file);
|
||||||
|
|
||||||
|
if (! $path_arr)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$channel_name = $path_arr[0];
|
||||||
|
|
||||||
|
$r = q("select channel_id from channel where channel_address = '%s' limit 1",
|
||||||
|
dbesc($channel_name)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! $r)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$channel_id = $r[0]['channel_id'];
|
||||||
|
|
||||||
|
$path = '/' . $channel_name;
|
||||||
|
|
||||||
|
$auth->owner_id = $channel_id;
|
||||||
|
|
||||||
|
$permission_error = false;
|
||||||
|
|
||||||
|
$folder = '';
|
||||||
|
|
||||||
|
require_once('include/security.php');
|
||||||
|
$perms = permissions_sql($channel_id);
|
||||||
|
|
||||||
|
$errors = false;
|
||||||
|
|
||||||
|
for ($x = 1; $x < count($path_arr); $x++) {
|
||||||
|
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms",
|
||||||
|
dbesc($folder),
|
||||||
|
dbesc($path_arr[$x]),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($r && intval($r[0]['is_dir'])) {
|
||||||
|
$folder = $r[0]['hash'];
|
||||||
|
$path = $path . '/' . $r[0]['filename'];
|
||||||
|
}
|
||||||
|
if (! $r) {
|
||||||
|
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
||||||
|
where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1",
|
||||||
|
dbesc($folder),
|
||||||
|
dbesc(basename($file)),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (! $r) {
|
||||||
|
$errors = true;
|
||||||
|
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
||||||
|
where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1",
|
||||||
|
dbesc($folder),
|
||||||
|
dbesc(basename($file)),
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
if ($r)
|
||||||
|
$permission_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($path === '/' . $file) {
|
||||||
|
if ($test)
|
||||||
|
return true;
|
||||||
|
// final component was a directory.
|
||||||
|
return new Directory($file, $auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
logger('not found ' . $file);
|
||||||
|
if ($test)
|
||||||
|
return false;
|
||||||
|
if ($permission_error) {
|
||||||
|
logger('permission error ' . $file);
|
||||||
|
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($r) {
|
||||||
|
if ($test)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (intval($r[0]['is_dir'])) {
|
||||||
|
return new Directory($path . '/' . $r[0]['filename'], $auth);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new File($path . '/' . $r[0]['filename'], $r[0], $auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
9
boot.php
9
boot.php
@ -2457,6 +2457,15 @@ function check_cron_broken() {
|
|||||||
set_config('system','lastcroncheck',datetime_convert());
|
set_config('system','lastcroncheck',datetime_convert());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$t = get_config('system','lastcroncheck');
|
||||||
|
if($t === false) {
|
||||||
|
// This is serious. Config storage isn't working.
|
||||||
|
// We just set lastcroncheck. The system is horked.
|
||||||
|
// However don't add insult to injury by sending an email
|
||||||
|
// to the admin every time a page is accessed.
|
||||||
|
// just quietly
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if($t > datetime_convert('UTC','UTC','now - 3 days')) {
|
if($t > datetime_convert('UTC','UTC','now - 3 days')) {
|
||||||
// Wait for 3 days before we do anything so as not to swamp the admin with messages
|
// Wait for 3 days before we do anything so as not to swamp the admin with messages
|
||||||
|
@ -302,11 +302,11 @@ function bb2diaspora_itemwallwall(&$item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_m']) {
|
if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_s']) {
|
||||||
logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG);
|
logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG);
|
||||||
// post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
|
// post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
|
||||||
$item['body'] = "\n\n"
|
$item['body'] = "\n\n"
|
||||||
. '[img]' . $item['author']['xchan_photo_m'] . '[/img]'
|
. '[img]' . $item['author']['xchan_photo_s'] . '[/img]'
|
||||||
. '[url=' . $item['author']['xchan_url'] . ']' . $item['author']['xchan_name'] . '[/url]' . "\n\n"
|
. '[url=' . $item['author']['xchan_url'] . ']' . $item['author']['xchan_name'] . '[/url]' . "\n\n"
|
||||||
. $item['body'];
|
. $item['body'];
|
||||||
}
|
}
|
||||||
|
@ -393,7 +393,7 @@ function get_atom_elements($feed, $item, &$author) {
|
|||||||
$terms = array();
|
$terms = array();
|
||||||
$terms[] = array(
|
$terms[] = array(
|
||||||
'otype' => TERM_OBJ_POST,
|
'otype' => TERM_OBJ_POST,
|
||||||
'type' => TERM_BOOKMARK,
|
'ttype' => TERM_BOOKMARK,
|
||||||
'url' => $res['plink'],
|
'url' => $res['plink'],
|
||||||
'term' => $res['title'],
|
'term' => $res['title'],
|
||||||
);
|
);
|
||||||
@ -403,7 +403,7 @@ function get_atom_elements($feed, $item, &$author) {
|
|||||||
$terms = array();
|
$terms = array();
|
||||||
$terms[] = array(
|
$terms[] = array(
|
||||||
'otype' => TERM_OBJ_POST,
|
'otype' => TERM_OBJ_POST,
|
||||||
'type' => TERM_BOOKMARK,
|
'ttype' => TERM_BOOKMARK,
|
||||||
'url' => $res['plink'],
|
'url' => $res['plink'],
|
||||||
'term' => $res['plink'],
|
'term' => $res['plink'],
|
||||||
);
|
);
|
||||||
|
@ -575,12 +575,20 @@ function import_items($channel,$items,$sync = false,$relocate = null) {
|
|||||||
if(! $item)
|
if(! $item)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if($relocate && $item['mid'] === $item['parent_mid']) {
|
||||||
|
item_url_replace($channel,$item,$relocate['url'],z_root(),$relocate['channel_address']);
|
||||||
|
}
|
||||||
|
|
||||||
$r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
|
$r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
|
||||||
dbesc($item['mid']),
|
dbesc($item['mid']),
|
||||||
intval($channel['channel_id'])
|
intval($channel['channel_id'])
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
if($item['edited'] > $r[0]['edited']) {
|
|
||||||
|
// flags may have changed and we are probably relocating the post,
|
||||||
|
// so force an update even if we have the same timestamp
|
||||||
|
|
||||||
|
if($item['edited'] >= $r[0]['edited']) {
|
||||||
$item['id'] = $r[0]['id'];
|
$item['id'] = $r[0]['id'];
|
||||||
$item['uid'] = $channel['channel_id'];
|
$item['uid'] = $channel['channel_id'];
|
||||||
$item_result = item_store_update($item,$allow_code,$deliver);
|
$item_result = item_store_update($item,$allow_code,$deliver);
|
||||||
@ -595,24 +603,7 @@ function import_items($channel,$items,$sync = false,$relocate = null) {
|
|||||||
if($sync && $item['item_wall']) {
|
if($sync && $item['item_wall']) {
|
||||||
// deliver singletons if we have any
|
// deliver singletons if we have any
|
||||||
if($item_result && $item_result['success']) {
|
if($item_result && $item_result['success']) {
|
||||||
Zotlabs\Daemon\Master::Summon(array('Notifier','single_activity',$item_result['item_id']));
|
Zotlabs\Daemon\Master::Summon( [ 'Notifier','single_activity',$item_result['item_id'] ]);
|
||||||
}
|
|
||||||
}
|
|
||||||
if($relocate && $item_result['item_id']) {
|
|
||||||
$item = $item_result['item'];
|
|
||||||
if($item['mid'] === $item['parent_mid']) {
|
|
||||||
item_url_replace($channel,$item,$relocate['url'],z_root(),$relocate['channel_address']);
|
|
||||||
dbesc_array($item);
|
|
||||||
$item_id = $item_result['item_id'];
|
|
||||||
unset($item['id']);
|
|
||||||
$str = '';
|
|
||||||
foreach($item as $k => $v) {
|
|
||||||
if($str)
|
|
||||||
$str .= ",";
|
|
||||||
$str .= " `" . $k . "` = '" . $v . "' ";
|
|
||||||
}
|
|
||||||
|
|
||||||
$r = dbq("update `item` set " . $str . " where id = " . $item_id );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,11 +449,7 @@ function post_activity_item($arr) {
|
|||||||
call_hooks('post_local_end', $arr);
|
call_hooks('post_local_end', $arr);
|
||||||
Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$post_id));
|
Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$post_id));
|
||||||
$ret['success'] = true;
|
$ret['success'] = true;
|
||||||
$r = q("select * from item where id = %d limit 1",
|
$ret['activity'] = $post['item'];
|
||||||
intval($post_id)
|
|
||||||
);
|
|
||||||
if($r)
|
|
||||||
$ret['activity'] = $r[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -255,6 +255,19 @@ $powered_by = '';
|
|||||||
'$pleasewait' => t('Please wait...')
|
'$pleasewait' => t('Please wait...')
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
if(x($_SESSION, 'reload_avatar') && $observer) {
|
||||||
|
// The avatar has been changed on the server but the browser doesn't know that,
|
||||||
|
// force the browser to reload the image from the server instead of its cache.
|
||||||
|
$tpl = get_markup_template('force_image_reload.tpl');
|
||||||
|
|
||||||
|
App::$page['nav'] .= replace_macros($tpl, array(
|
||||||
|
'$imgUrl' => $observer['xchan_photo_m']
|
||||||
|
));
|
||||||
|
unset($_SESSION['reload_avatar']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
call_hooks('page_header', App::$page['nav']);
|
call_hooks('page_header', App::$page['nav']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,299 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @file include/reddav.php
|
|
||||||
* @brief some DAV related functions for Hubzilla.
|
|
||||||
*
|
|
||||||
* This file contains some functions which did not fit into one of the RedDAV
|
|
||||||
* classes.
|
|
||||||
*
|
|
||||||
* The extended SabreDAV classes you will find in the RedDAV namespace under
|
|
||||||
* @ref includes/RedDAV/.
|
|
||||||
* The original SabreDAV classes you can find under @ref vendor/sabre/dav/.
|
|
||||||
* We need to use SabreDAV 1.8.x for PHP5.3 compatibility. SabreDAV >= 2.0
|
|
||||||
* requires PHP >= 5.4.
|
|
||||||
*
|
|
||||||
* @todo split up the classes into own files.
|
|
||||||
*
|
|
||||||
* @link http://github.com/friendica/red
|
|
||||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Sabre\DAV;
|
|
||||||
use Zotlabs\Storage;
|
|
||||||
|
|
||||||
require_once('vendor/autoload.php');
|
|
||||||
require_once('include/attach.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns an array with viewable channels.
|
|
||||||
*
|
|
||||||
* Get a list of RedDirectory objects with all the channels where the visitor
|
|
||||||
* has <b>view_storage</b> perms.
|
|
||||||
*
|
|
||||||
* @todo Is there any reason why this is not inside RedDirectory class?
|
|
||||||
* @fixme function name looks like a class name, should we rename it?
|
|
||||||
*
|
|
||||||
* @param RedBasicAuth &$auth
|
|
||||||
* @return array RedDirectory[]
|
|
||||||
*/
|
|
||||||
function RedChannelList(&$auth) {
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
$r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0 AND channel_system = 0 AND NOT (channel_pageflags & %d)>0",
|
|
||||||
intval(PAGE_HIDDEN)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($r) {
|
|
||||||
foreach ($r as $rr) {
|
|
||||||
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
|
|
||||||
logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA);
|
|
||||||
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
|
|
||||||
$ret[] = new Zotlabs\Storage\Directory('/cloud/' . $rr['channel_address'], $auth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO what exactly does this function?
|
|
||||||
*
|
|
||||||
* Array with all RedDirectory and RedFile DAV\Node items for the given path.
|
|
||||||
*
|
|
||||||
* @todo Is there any reason why this is not inside RedDirectory class? Seems
|
|
||||||
* only to be used there and we could simplify it a bit there.
|
|
||||||
* @fixme function name looks like a class name, should we rename it?
|
|
||||||
*
|
|
||||||
* @param string $file path to a directory
|
|
||||||
* @param RedBasicAuth &$auth
|
|
||||||
* @returns null|array \Sabre\DAV\INode[]
|
|
||||||
* @throw \Sabre\DAV\Exception\Forbidden
|
|
||||||
* @throw \Sabre\DAV\Exception\NotFound
|
|
||||||
*/
|
|
||||||
function RedCollectionData($file, &$auth) {
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
$x = strpos($file, '/cloud');
|
|
||||||
if ($x === 0) {
|
|
||||||
$file = substr($file, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return a list of channel if we are not inside a channel
|
|
||||||
if ((! $file) || ($file === '/')) {
|
|
||||||
return RedChannelList($auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = trim($file, '/');
|
|
||||||
$path_arr = explode('/', $file);
|
|
||||||
|
|
||||||
if (! $path_arr)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$channel_name = $path_arr[0];
|
|
||||||
|
|
||||||
$r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' LIMIT 1",
|
|
||||||
dbesc($channel_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! $r)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$channel_id = $r[0]['channel_id'];
|
|
||||||
$perms = permissions_sql($channel_id);
|
|
||||||
|
|
||||||
$auth->owner_id = $channel_id;
|
|
||||||
|
|
||||||
$path = '/' . $channel_name;
|
|
||||||
|
|
||||||
$folder = '';
|
|
||||||
$errors = false;
|
|
||||||
$permission_error = false;
|
|
||||||
|
|
||||||
for ($x = 1; $x < count($path_arr); $x++) {
|
|
||||||
$r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1",
|
|
||||||
dbesc($folder),
|
|
||||||
dbesc($path_arr[$x]),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
if (! $r) {
|
|
||||||
// path wasn't found. Try without permissions to see if it was the result of permissions.
|
|
||||||
$errors = true;
|
|
||||||
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1",
|
|
||||||
dbesc($folder),
|
|
||||||
basename($path_arr[$x]),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
if ($r) {
|
|
||||||
$permission_error = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($r && intval($r[0]['is_dir'])) {
|
|
||||||
$folder = $r[0]['hash'];
|
|
||||||
$path = $path . '/' . $r[0]['filename'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($errors) {
|
|
||||||
if ($permission_error) {
|
|
||||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
|
||||||
} else {
|
|
||||||
throw new DAV\Exception\NotFound('A component of the request file path could not be found.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should no longer be needed since we just returned errors for paths not found
|
|
||||||
if ($path !== '/' . $file) {
|
|
||||||
logger("Path mismatch: $path !== /$file");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
|
||||||
$prefix = 'DISTINCT ON (filename)';
|
|
||||||
$suffix = 'ORDER BY filename';
|
|
||||||
} else {
|
|
||||||
$prefix = '';
|
|
||||||
$suffix = 'GROUP BY filename';
|
|
||||||
}
|
|
||||||
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
|
|
||||||
dbesc($folder),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($r as $rr) {
|
|
||||||
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
|
|
||||||
if (intval($rr['is_dir'])) {
|
|
||||||
$ret[] = new Zotlabs\Storage\Directory($path . '/' . $rr['filename'], $auth);
|
|
||||||
} else {
|
|
||||||
$ret[] = new Zotlabs\Storage\File($path . '/' . $rr['filename'], $rr, $auth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO What exactly is this function for?
|
|
||||||
*
|
|
||||||
* @fixme function name looks like a class name, should we rename it?
|
|
||||||
*
|
|
||||||
* @param string $file
|
|
||||||
* path to file or directory
|
|
||||||
* @param RedBasicAuth &$auth
|
|
||||||
* @param boolean $test (optional) enable test mode
|
|
||||||
* @return RedFile|RedDirectory|boolean|null
|
|
||||||
* @throw \Sabre\DAV\Exception\Forbidden
|
|
||||||
*/
|
|
||||||
function RedFileData($file, &$auth, $test = false) {
|
|
||||||
logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA);
|
|
||||||
|
|
||||||
$x = strpos($file, '/cloud');
|
|
||||||
if ($x === 0) {
|
|
||||||
$file = substr($file, 6);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$x = strpos($file,'/dav');
|
|
||||||
if($x === 0)
|
|
||||||
$file = substr($file,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ((! $file) || ($file === '/')) {
|
|
||||||
return new Zotlabs\Storage\Directory('/', $auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = trim($file, '/');
|
|
||||||
|
|
||||||
$path_arr = explode('/', $file);
|
|
||||||
|
|
||||||
if (! $path_arr)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$channel_name = $path_arr[0];
|
|
||||||
|
|
||||||
$r = q("select channel_id from channel where channel_address = '%s' limit 1",
|
|
||||||
dbesc($channel_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! $r)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$channel_id = $r[0]['channel_id'];
|
|
||||||
|
|
||||||
$path = '/' . $channel_name;
|
|
||||||
|
|
||||||
$auth->owner_id = $channel_id;
|
|
||||||
|
|
||||||
$permission_error = false;
|
|
||||||
|
|
||||||
$folder = '';
|
|
||||||
|
|
||||||
require_once('include/security.php');
|
|
||||||
$perms = permissions_sql($channel_id);
|
|
||||||
|
|
||||||
$errors = false;
|
|
||||||
|
|
||||||
for ($x = 1; $x < count($path_arr); $x++) {
|
|
||||||
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms",
|
|
||||||
dbesc($folder),
|
|
||||||
dbesc($path_arr[$x]),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($r && intval($r[0]['is_dir'])) {
|
|
||||||
$folder = $r[0]['hash'];
|
|
||||||
$path = $path . '/' . $r[0]['filename'];
|
|
||||||
}
|
|
||||||
if (! $r) {
|
|
||||||
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
|
||||||
where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1",
|
|
||||||
dbesc($folder),
|
|
||||||
dbesc(basename($file)),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (! $r) {
|
|
||||||
$errors = true;
|
|
||||||
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
|
||||||
where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1",
|
|
||||||
dbesc($folder),
|
|
||||||
dbesc(basename($file)),
|
|
||||||
intval($channel_id)
|
|
||||||
);
|
|
||||||
if ($r)
|
|
||||||
$permission_error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($path === '/' . $file) {
|
|
||||||
if ($test)
|
|
||||||
return true;
|
|
||||||
// final component was a directory.
|
|
||||||
return new Zotlabs\Storage\Directory($file, $auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($errors) {
|
|
||||||
logger('not found ' . $file);
|
|
||||||
if ($test)
|
|
||||||
return false;
|
|
||||||
if ($permission_error) {
|
|
||||||
logger('permission error ' . $file);
|
|
||||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($r) {
|
|
||||||
if ($test)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (intval($r[0]['is_dir'])) {
|
|
||||||
return new Zotlabs\Storage\Directory($path . '/' . $r[0]['filename'], $auth);
|
|
||||||
} else {
|
|
||||||
return new Zotlabs\Storage\File($path . '/' . $r[0]['filename'], $r[0], $auth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<?php /** @file */
|
|
||||||
|
|
||||||
|
|
||||||
function string_splitter($s) {
|
|
||||||
|
|
||||||
if(! $s)
|
|
||||||
return array();
|
|
||||||
|
|
||||||
$s = preg_replace('/\pP+/','',$s);
|
|
||||||
|
|
||||||
$x = mb_split("\[|\]|\s",$s);
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
if($x) {
|
|
||||||
foreach($x as $y) {
|
|
||||||
if(mb_strlen($y) > 2)
|
|
||||||
$ret[] = substr($y,0,64);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function get_words($uid,$list) {
|
|
||||||
|
|
||||||
stringify($list,true);
|
|
||||||
|
|
||||||
$r = q("select * from spam where term in ( " . $list . ") and uid = %d",
|
|
||||||
intval($uid)
|
|
||||||
);
|
|
||||||
|
|
||||||
return $r;
|
|
||||||
}
|
|
||||||
|
|
@ -2354,7 +2354,13 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
|
|||||||
|
|
||||||
$str_tags .= $newtag;
|
$str_tags .= $newtag;
|
||||||
}
|
}
|
||||||
return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $basetag, 'url' => $url, 'contact' => $r[0]);
|
return [
|
||||||
|
'replaced' => $replaced,
|
||||||
|
'termtype' => $termtype,
|
||||||
|
'term' => $basetag,
|
||||||
|
'url' => $url,
|
||||||
|
'contact' => $r[0]
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
//is it a person tag?
|
//is it a person tag?
|
||||||
@ -2545,7 +2551,13 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]);
|
return [
|
||||||
|
'replaced' => $replaced,
|
||||||
|
'termtype' => $termtype,
|
||||||
|
'term' => $newname,
|
||||||
|
'url' => $url,
|
||||||
|
'contact' => $r[0]
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function linkify_tags($a, &$body, $uid, $diaspora = false) {
|
function linkify_tags($a, &$body, $uid, $diaspora = false) {
|
||||||
|
@ -743,21 +743,6 @@ function widget_conversations($arr) {
|
|||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
function widget_eventsmenu($arr) {
|
|
||||||
if (! local_channel())
|
|
||||||
return;
|
|
||||||
|
|
||||||
return replace_macros(get_markup_template('events_menu_side.tpl'), array(
|
|
||||||
'$title' => t('Events Menu'),
|
|
||||||
'$day' => t('Day View'),
|
|
||||||
'$week' => t('Week View'),
|
|
||||||
'$month' => t('Month View'),
|
|
||||||
'$export' => t('Export'),
|
|
||||||
'$upload' => t('Import'),
|
|
||||||
'$submit' => t('Submit')
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
function widget_eventstools($arr) {
|
function widget_eventstools($arr) {
|
||||||
if (! local_channel())
|
if (! local_channel())
|
||||||
return;
|
return;
|
||||||
|
@ -494,3 +494,78 @@ function wiki_convert_links($s, $wikiURL) {
|
|||||||
}
|
}
|
||||||
return $s;
|
return $s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wiki_generate_toc($s) {
|
||||||
|
|
||||||
|
if (strpos($s,'[toc]') !== false) {
|
||||||
|
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
|
||||||
|
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
|
||||||
|
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
|
||||||
|
}
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is derived from
|
||||||
|
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
|
||||||
|
function wiki_toc($content) {
|
||||||
|
// ensure using only "\n" as line-break
|
||||||
|
$source = str_replace(["\r\n", "\r"], "\n", $content);
|
||||||
|
|
||||||
|
// look for markdown TOC items
|
||||||
|
preg_match_all(
|
||||||
|
'/^(?:=|-|#).*$/m',
|
||||||
|
$source,
|
||||||
|
$matches,
|
||||||
|
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
|
||||||
|
);
|
||||||
|
|
||||||
|
// preprocess: iterate matched lines to create an array of items
|
||||||
|
// where each item is an array(level, text)
|
||||||
|
$file_size = strlen($source);
|
||||||
|
foreach ($matches[0] as $item) {
|
||||||
|
$found_mark = substr($item[0], 0, 1);
|
||||||
|
if ($found_mark == '#') {
|
||||||
|
// text is the found item
|
||||||
|
$item_text = $item[0];
|
||||||
|
$item_level = strrpos($item_text, '#') + 1;
|
||||||
|
$item_text = substr($item_text, $item_level);
|
||||||
|
} else {
|
||||||
|
// text is the previous line (empty if <hr>)
|
||||||
|
$item_offset = $item[1];
|
||||||
|
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
|
||||||
|
$item_text =
|
||||||
|
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
|
||||||
|
$item_text = trim($item_text);
|
||||||
|
$item_level = $found_mark == '=' ? 1 : 2;
|
||||||
|
}
|
||||||
|
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
|
||||||
|
// item is an horizontal separator or a table header, don't mind
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
|
||||||
|
}
|
||||||
|
$o = '';
|
||||||
|
foreach($raw_toc as $t) {
|
||||||
|
$level = intval($t['level']);
|
||||||
|
$text = $t['text'];
|
||||||
|
switch ($level) {
|
||||||
|
case 1:
|
||||||
|
$li = '* ';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$li = ' * ';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$li = ' * ';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
$li = ' * ';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$li = '* ';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$o .= $li . $text . "\n";
|
||||||
|
}
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,27 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)
|
||||||
|
|
||||||
|
## Enhancements:
|
||||||
|
* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().
|
||||||
|
* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601
|
||||||
|
* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals
|
||||||
|
* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers
|
||||||
|
* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.
|
||||||
|
* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters
|
||||||
|
* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))
|
||||||
|
* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations
|
||||||
|
* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs
|
||||||
|
* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token
|
||||||
|
* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion
|
||||||
|
* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes
|
||||||
|
|
||||||
|
Plus 3 new locales and locale fixes.
|
||||||
|
|
||||||
### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)
|
### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)
|
||||||
|
|
||||||
## Enhancements:
|
## Enhancements:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
|
A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
|
||||||
|
|
||||||
## [Documentation](http://momentjs.com/docs/)
|
**[Documentation](http://momentjs.com/docs/)**
|
||||||
|
|
||||||
## Port to ECMAScript 6 (version 2.10.0)
|
## Port to ECMAScript 6 (version 2.10.0)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! moment.js
|
//! moment.js
|
||||||
//! version : 2.12.0
|
//! version : 2.13.0
|
||||||
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
||||||
//! license : MIT
|
//! license : MIT
|
||||||
//! momentjs.com
|
//! momentjs.com
|
||||||
@ -76,7 +76,9 @@
|
|||||||
invalidMonth : null,
|
invalidMonth : null,
|
||||||
invalidFormat : false,
|
invalidFormat : false,
|
||||||
userInvalidated : false,
|
userInvalidated : false,
|
||||||
iso : false
|
iso : false,
|
||||||
|
parsedDateParts : [],
|
||||||
|
meridiem : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +89,30 @@
|
|||||||
return m._pf;
|
return m._pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var some;
|
||||||
|
if (Array.prototype.some) {
|
||||||
|
some = Array.prototype.some;
|
||||||
|
} else {
|
||||||
|
some = function (fun) {
|
||||||
|
var t = Object(this);
|
||||||
|
var len = t.length >>> 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
if (i in t && fun.call(this, t[i], i, t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function valid__isValid(m) {
|
function valid__isValid(m) {
|
||||||
if (m._isValid == null) {
|
if (m._isValid == null) {
|
||||||
var flags = getParsingFlags(m);
|
var flags = getParsingFlags(m);
|
||||||
|
var parsedParts = some.call(flags.parsedDateParts, function (i) {
|
||||||
|
return i != null;
|
||||||
|
});
|
||||||
m._isValid = !isNaN(m._d.getTime()) &&
|
m._isValid = !isNaN(m._d.getTime()) &&
|
||||||
flags.overflow < 0 &&
|
flags.overflow < 0 &&
|
||||||
!flags.empty &&
|
!flags.empty &&
|
||||||
@ -97,7 +120,8 @@
|
|||||||
!flags.invalidWeekday &&
|
!flags.invalidWeekday &&
|
||||||
!flags.nullInput &&
|
!flags.nullInput &&
|
||||||
!flags.invalidFormat &&
|
!flags.invalidFormat &&
|
||||||
!flags.userInvalidated;
|
!flags.userInvalidated &&
|
||||||
|
(!flags.meridiem || (flags.meridiem && parsedParts));
|
||||||
|
|
||||||
if (m._strict) {
|
if (m._strict) {
|
||||||
m._isValid = m._isValid &&
|
m._isValid = m._isValid &&
|
||||||
@ -240,6 +264,9 @@
|
|||||||
var firstTime = true;
|
var firstTime = true;
|
||||||
|
|
||||||
return extend(function () {
|
return extend(function () {
|
||||||
|
if (utils_hooks__hooks.deprecationHandler != null) {
|
||||||
|
utils_hooks__hooks.deprecationHandler(null, msg);
|
||||||
|
}
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
|
warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
@ -251,6 +278,9 @@
|
|||||||
var deprecations = {};
|
var deprecations = {};
|
||||||
|
|
||||||
function deprecateSimple(name, msg) {
|
function deprecateSimple(name, msg) {
|
||||||
|
if (utils_hooks__hooks.deprecationHandler != null) {
|
||||||
|
utils_hooks__hooks.deprecationHandler(name, msg);
|
||||||
|
}
|
||||||
if (!deprecations[name]) {
|
if (!deprecations[name]) {
|
||||||
warn(msg);
|
warn(msg);
|
||||||
deprecations[name] = true;
|
deprecations[name] = true;
|
||||||
@ -258,6 +288,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
utils_hooks__hooks.suppressDeprecationWarnings = false;
|
utils_hooks__hooks.suppressDeprecationWarnings = false;
|
||||||
|
utils_hooks__hooks.deprecationHandler = null;
|
||||||
|
|
||||||
function isFunction(input) {
|
function isFunction(input) {
|
||||||
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
|
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
|
||||||
@ -307,6 +338,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var keys;
|
||||||
|
|
||||||
|
if (Object.keys) {
|
||||||
|
keys = Object.keys;
|
||||||
|
} else {
|
||||||
|
keys = function (obj) {
|
||||||
|
var i, res = [];
|
||||||
|
for (i in obj) {
|
||||||
|
if (hasOwnProp(obj, i)) {
|
||||||
|
res.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// internal storage for locale config files
|
// internal storage for locale config files
|
||||||
var locales = {};
|
var locales = {};
|
||||||
var globalLocale;
|
var globalLocale;
|
||||||
@ -461,7 +508,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function locale_locales__listLocales() {
|
function locale_locales__listLocales() {
|
||||||
return Object.keys(locales);
|
return keys(locales);
|
||||||
}
|
}
|
||||||
|
|
||||||
var aliases = {};
|
var aliases = {};
|
||||||
@ -540,7 +587,7 @@
|
|||||||
Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
|
Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
|
var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
|
||||||
|
|
||||||
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
|
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
|
||||||
|
|
||||||
@ -593,7 +640,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return function (mom) {
|
return function (mom) {
|
||||||
var output = '';
|
var output = '', i;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
|
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
|
||||||
}
|
}
|
||||||
@ -722,6 +769,23 @@
|
|||||||
var WEEK = 7;
|
var WEEK = 7;
|
||||||
var WEEKDAY = 8;
|
var WEEKDAY = 8;
|
||||||
|
|
||||||
|
var indexOf;
|
||||||
|
|
||||||
|
if (Array.prototype.indexOf) {
|
||||||
|
indexOf = Array.prototype.indexOf;
|
||||||
|
} else {
|
||||||
|
indexOf = function (o) {
|
||||||
|
// I know
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < this.length; ++i) {
|
||||||
|
if (this[i] === o) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function daysInMonth(year, month) {
|
function daysInMonth(year, month) {
|
||||||
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
||||||
}
|
}
|
||||||
@ -784,15 +848,63 @@
|
|||||||
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
|
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function units_month__handleStrictParse(monthName, format, strict) {
|
||||||
|
var i, ii, mom, llc = monthName.toLocaleLowerCase();
|
||||||
|
if (!this._monthsParse) {
|
||||||
|
// this is not used
|
||||||
|
this._monthsParse = [];
|
||||||
|
this._longMonthsParse = [];
|
||||||
|
this._shortMonthsParse = [];
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
mom = create_utc__createUTC([2000, i]);
|
||||||
|
this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
|
||||||
|
this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strict) {
|
||||||
|
if (format === 'MMM') {
|
||||||
|
ii = indexOf.call(this._shortMonthsParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else {
|
||||||
|
ii = indexOf.call(this._longMonthsParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (format === 'MMM') {
|
||||||
|
ii = indexOf.call(this._shortMonthsParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._longMonthsParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else {
|
||||||
|
ii = indexOf.call(this._longMonthsParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._shortMonthsParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function localeMonthsParse (monthName, format, strict) {
|
function localeMonthsParse (monthName, format, strict) {
|
||||||
var i, mom, regex;
|
var i, mom, regex;
|
||||||
|
|
||||||
|
if (this._monthsParseExact) {
|
||||||
|
return units_month__handleStrictParse.call(this, monthName, format, strict);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._monthsParse) {
|
if (!this._monthsParse) {
|
||||||
this._monthsParse = [];
|
this._monthsParse = [];
|
||||||
this._longMonthsParse = [];
|
this._longMonthsParse = [];
|
||||||
this._shortMonthsParse = [];
|
this._shortMonthsParse = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add sorting
|
||||||
|
// Sorting makes sure if one month (or abbr) is a prefix of another
|
||||||
|
// see sorting in computeMonthsParse
|
||||||
for (i = 0; i < 12; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
// make the regex if we don't have it already
|
// make the regex if we don't have it already
|
||||||
mom = create_utc__createUTC([2000, i]);
|
mom = create_utc__createUTC([2000, i]);
|
||||||
@ -918,8 +1030,8 @@
|
|||||||
|
|
||||||
this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
|
this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
|
||||||
this._monthsShortRegex = this._monthsRegex;
|
this._monthsShortRegex = this._monthsRegex;
|
||||||
this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i');
|
this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
|
||||||
this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i');
|
this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOverflow (m) {
|
function checkOverflow (m) {
|
||||||
@ -1146,7 +1258,7 @@
|
|||||||
|
|
||||||
// MOMENTS
|
// MOMENTS
|
||||||
|
|
||||||
var getSetYear = makeGetSet('FullYear', false);
|
var getSetYear = makeGetSet('FullYear', true);
|
||||||
|
|
||||||
function getIsLeapYear () {
|
function getIsLeapYear () {
|
||||||
return isLeapYear(this.year());
|
return isLeapYear(this.year());
|
||||||
@ -1415,6 +1527,9 @@
|
|||||||
config._a[HOUR] > 0) {
|
config._a[HOUR] > 0) {
|
||||||
getParsingFlags(config).bigHour = undefined;
|
getParsingFlags(config).bigHour = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getParsingFlags(config).parsedDateParts = config._a.slice(0);
|
||||||
|
getParsingFlags(config).meridiem = config._meridiem;
|
||||||
// handle meridiem
|
// handle meridiem
|
||||||
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
|
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
|
||||||
|
|
||||||
@ -1555,7 +1670,7 @@
|
|||||||
if (input === undefined) {
|
if (input === undefined) {
|
||||||
config._d = new Date(utils_hooks__hooks.now());
|
config._d = new Date(utils_hooks__hooks.now());
|
||||||
} else if (isDate(input)) {
|
} else if (isDate(input)) {
|
||||||
config._d = new Date(+input);
|
config._d = new Date(input.valueOf());
|
||||||
} else if (typeof input === 'string') {
|
} else if (typeof input === 'string') {
|
||||||
configFromString(config);
|
configFromString(config);
|
||||||
} else if (isArray(input)) {
|
} else if (isArray(input)) {
|
||||||
@ -1675,7 +1790,7 @@
|
|||||||
this._milliseconds = +milliseconds +
|
this._milliseconds = +milliseconds +
|
||||||
seconds * 1e3 + // 1000
|
seconds * 1e3 + // 1000
|
||||||
minutes * 6e4 + // 1000 * 60
|
minutes * 6e4 + // 1000 * 60
|
||||||
hours * 36e5; // 1000 * 60 * 60
|
hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
|
||||||
// Because of dateAddRemove treats 24 hours as different from a
|
// Because of dateAddRemove treats 24 hours as different from a
|
||||||
// day when working around DST, we need to store them separately
|
// day when working around DST, we need to store them separately
|
||||||
this._days = +days +
|
this._days = +days +
|
||||||
@ -1745,9 +1860,9 @@
|
|||||||
var res, diff;
|
var res, diff;
|
||||||
if (model._isUTC) {
|
if (model._isUTC) {
|
||||||
res = model.clone();
|
res = model.clone();
|
||||||
diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);
|
diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
|
||||||
// Use low-level api, because this fn is low-level api.
|
// Use low-level api, because this fn is low-level api.
|
||||||
res._d.setTime(+res._d + diff);
|
res._d.setTime(res._d.valueOf() + diff);
|
||||||
utils_hooks__hooks.updateOffset(res, false);
|
utils_hooks__hooks.updateOffset(res, false);
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
@ -1908,7 +2023,7 @@
|
|||||||
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
|
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
|
||||||
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
|
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
|
||||||
// and further modified to allow for strings containing both week and day
|
// and further modified to allow for strings containing both week and day
|
||||||
var isoRegex = /^(-)?P(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)W)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?$/;
|
var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
|
||||||
|
|
||||||
function create__createDuration (input, key) {
|
function create__createDuration (input, key) {
|
||||||
var duration = input,
|
var duration = input,
|
||||||
@ -2052,7 +2167,7 @@
|
|||||||
updateOffset = updateOffset == null ? true : updateOffset;
|
updateOffset = updateOffset == null ? true : updateOffset;
|
||||||
|
|
||||||
if (milliseconds) {
|
if (milliseconds) {
|
||||||
mom._d.setTime(+mom._d + milliseconds * isAdding);
|
mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
|
||||||
}
|
}
|
||||||
if (days) {
|
if (days) {
|
||||||
get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
|
get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
|
||||||
@ -2097,9 +2212,9 @@
|
|||||||
}
|
}
|
||||||
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
||||||
if (units === 'millisecond') {
|
if (units === 'millisecond') {
|
||||||
return +this > +localInput;
|
return this.valueOf() > localInput.valueOf();
|
||||||
} else {
|
} else {
|
||||||
return +localInput < +this.clone().startOf(units);
|
return localInput.valueOf() < this.clone().startOf(units).valueOf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,14 +2225,16 @@
|
|||||||
}
|
}
|
||||||
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
||||||
if (units === 'millisecond') {
|
if (units === 'millisecond') {
|
||||||
return +this < +localInput;
|
return this.valueOf() < localInput.valueOf();
|
||||||
} else {
|
} else {
|
||||||
return +this.clone().endOf(units) < +localInput;
|
return this.clone().endOf(units).valueOf() < localInput.valueOf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBetween (from, to, units) {
|
function isBetween (from, to, units, inclusivity) {
|
||||||
return this.isAfter(from, units) && this.isBefore(to, units);
|
inclusivity = inclusivity || '()';
|
||||||
|
return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
|
||||||
|
(inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSame (input, units) {
|
function isSame (input, units) {
|
||||||
@ -2128,10 +2245,10 @@
|
|||||||
}
|
}
|
||||||
units = normalizeUnits(units || 'millisecond');
|
units = normalizeUnits(units || 'millisecond');
|
||||||
if (units === 'millisecond') {
|
if (units === 'millisecond') {
|
||||||
return +this === +localInput;
|
return this.valueOf() === localInput.valueOf();
|
||||||
} else {
|
} else {
|
||||||
inputMs = +localInput;
|
inputMs = localInput.valueOf();
|
||||||
return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
|
return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2198,10 +2315,12 @@
|
|||||||
adjust = (b - anchor) / (anchor2 - anchor);
|
adjust = (b - anchor) / (anchor2 - anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -(wholeMonthDiff + adjust);
|
//check for negative zero, return zero if negative zero
|
||||||
|
return -(wholeMonthDiff + adjust) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
|
utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
|
||||||
|
utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
|
||||||
|
|
||||||
function toString () {
|
function toString () {
|
||||||
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
|
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
|
||||||
@ -2222,7 +2341,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function format (inputString) {
|
function format (inputString) {
|
||||||
var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);
|
if (!inputString) {
|
||||||
|
inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
|
||||||
|
}
|
||||||
|
var output = formatMoment(this, inputString);
|
||||||
return this.localeData().postformat(output);
|
return this.localeData().postformat(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2301,6 +2423,7 @@
|
|||||||
case 'week':
|
case 'week':
|
||||||
case 'isoWeek':
|
case 'isoWeek':
|
||||||
case 'day':
|
case 'day':
|
||||||
|
case 'date':
|
||||||
this.hours(0);
|
this.hours(0);
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case 'hour':
|
case 'hour':
|
||||||
@ -2334,19 +2457,25 @@
|
|||||||
if (units === undefined || units === 'millisecond') {
|
if (units === undefined || units === 'millisecond') {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'date' is an alias for 'day', so it should be considered as such.
|
||||||
|
if (units === 'date') {
|
||||||
|
units = 'day';
|
||||||
|
}
|
||||||
|
|
||||||
return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
|
return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
|
||||||
}
|
}
|
||||||
|
|
||||||
function to_type__valueOf () {
|
function to_type__valueOf () {
|
||||||
return +this._d - ((this._offset || 0) * 60000);
|
return this._d.valueOf() - ((this._offset || 0) * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unix () {
|
function unix () {
|
||||||
return Math.floor(+this / 1000);
|
return Math.floor(this.valueOf() / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toDate () {
|
function toDate () {
|
||||||
return this._offset ? new Date(+this) : this._d;
|
return this._offset ? new Date(this.valueOf()) : this._d;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toArray () {
|
function toArray () {
|
||||||
@ -2615,9 +2744,15 @@
|
|||||||
addRegexToken('d', match1to2);
|
addRegexToken('d', match1to2);
|
||||||
addRegexToken('e', match1to2);
|
addRegexToken('e', match1to2);
|
||||||
addRegexToken('E', match1to2);
|
addRegexToken('E', match1to2);
|
||||||
addRegexToken('dd', matchWord);
|
addRegexToken('dd', function (isStrict, locale) {
|
||||||
addRegexToken('ddd', matchWord);
|
return locale.weekdaysMinRegex(isStrict);
|
||||||
addRegexToken('dddd', matchWord);
|
});
|
||||||
|
addRegexToken('ddd', function (isStrict, locale) {
|
||||||
|
return locale.weekdaysShortRegex(isStrict);
|
||||||
|
});
|
||||||
|
addRegexToken('dddd', function (isStrict, locale) {
|
||||||
|
return locale.weekdaysRegex(isStrict);
|
||||||
|
});
|
||||||
|
|
||||||
addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
|
addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
|
||||||
var weekday = config._locale.weekdaysParse(input, token, config._strict);
|
var weekday = config._locale.weekdaysParse(input, token, config._strict);
|
||||||
@ -2670,9 +2805,77 @@
|
|||||||
return this._weekdaysMin[m.day()];
|
return this._weekdaysMin[m.day()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function day_of_week__handleStrictParse(weekdayName, format, strict) {
|
||||||
|
var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
|
||||||
|
if (!this._weekdaysParse) {
|
||||||
|
this._weekdaysParse = [];
|
||||||
|
this._shortWeekdaysParse = [];
|
||||||
|
this._minWeekdaysParse = [];
|
||||||
|
|
||||||
|
for (i = 0; i < 7; ++i) {
|
||||||
|
mom = create_utc__createUTC([2000, 1]).day(i);
|
||||||
|
this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
|
||||||
|
this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
|
||||||
|
this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strict) {
|
||||||
|
if (format === 'dddd') {
|
||||||
|
ii = indexOf.call(this._weekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else if (format === 'ddd') {
|
||||||
|
ii = indexOf.call(this._shortWeekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else {
|
||||||
|
ii = indexOf.call(this._minWeekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (format === 'dddd') {
|
||||||
|
ii = indexOf.call(this._weekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._shortWeekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._minWeekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else if (format === 'ddd') {
|
||||||
|
ii = indexOf.call(this._shortWeekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._weekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._minWeekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
} else {
|
||||||
|
ii = indexOf.call(this._minWeekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._weekdaysParse, llc);
|
||||||
|
if (ii !== -1) {
|
||||||
|
return ii;
|
||||||
|
}
|
||||||
|
ii = indexOf.call(this._shortWeekdaysParse, llc);
|
||||||
|
return ii !== -1 ? ii : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function localeWeekdaysParse (weekdayName, format, strict) {
|
function localeWeekdaysParse (weekdayName, format, strict) {
|
||||||
var i, mom, regex;
|
var i, mom, regex;
|
||||||
|
|
||||||
|
if (this._weekdaysParseExact) {
|
||||||
|
return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._weekdaysParse) {
|
if (!this._weekdaysParse) {
|
||||||
this._weekdaysParse = [];
|
this._weekdaysParse = [];
|
||||||
this._minWeekdaysParse = [];
|
this._minWeekdaysParse = [];
|
||||||
@ -2683,7 +2886,7 @@
|
|||||||
for (i = 0; i < 7; i++) {
|
for (i = 0; i < 7; i++) {
|
||||||
// make the regex if we don't have it already
|
// make the regex if we don't have it already
|
||||||
|
|
||||||
mom = local__createLocal([2000, 1]).day(i);
|
mom = create_utc__createUTC([2000, 1]).day(i);
|
||||||
if (strict && !this._fullWeekdaysParse[i]) {
|
if (strict && !this._fullWeekdaysParse[i]) {
|
||||||
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
|
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
|
||||||
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
|
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
|
||||||
@ -2739,6 +2942,99 @@
|
|||||||
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
|
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultWeekdaysRegex = matchWord;
|
||||||
|
function weekdaysRegex (isStrict) {
|
||||||
|
if (this._weekdaysParseExact) {
|
||||||
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
||||||
|
computeWeekdaysParse.call(this);
|
||||||
|
}
|
||||||
|
if (isStrict) {
|
||||||
|
return this._weekdaysStrictRegex;
|
||||||
|
} else {
|
||||||
|
return this._weekdaysRegex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this._weekdaysStrictRegex && isStrict ?
|
||||||
|
this._weekdaysStrictRegex : this._weekdaysRegex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultWeekdaysShortRegex = matchWord;
|
||||||
|
function weekdaysShortRegex (isStrict) {
|
||||||
|
if (this._weekdaysParseExact) {
|
||||||
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
||||||
|
computeWeekdaysParse.call(this);
|
||||||
|
}
|
||||||
|
if (isStrict) {
|
||||||
|
return this._weekdaysShortStrictRegex;
|
||||||
|
} else {
|
||||||
|
return this._weekdaysShortRegex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this._weekdaysShortStrictRegex && isStrict ?
|
||||||
|
this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultWeekdaysMinRegex = matchWord;
|
||||||
|
function weekdaysMinRegex (isStrict) {
|
||||||
|
if (this._weekdaysParseExact) {
|
||||||
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
||||||
|
computeWeekdaysParse.call(this);
|
||||||
|
}
|
||||||
|
if (isStrict) {
|
||||||
|
return this._weekdaysMinStrictRegex;
|
||||||
|
} else {
|
||||||
|
return this._weekdaysMinRegex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this._weekdaysMinStrictRegex && isStrict ?
|
||||||
|
this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function computeWeekdaysParse () {
|
||||||
|
function cmpLenRev(a, b) {
|
||||||
|
return b.length - a.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
|
||||||
|
i, mom, minp, shortp, longp;
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
// make the regex if we don't have it already
|
||||||
|
mom = create_utc__createUTC([2000, 1]).day(i);
|
||||||
|
minp = this.weekdaysMin(mom, '');
|
||||||
|
shortp = this.weekdaysShort(mom, '');
|
||||||
|
longp = this.weekdays(mom, '');
|
||||||
|
minPieces.push(minp);
|
||||||
|
shortPieces.push(shortp);
|
||||||
|
longPieces.push(longp);
|
||||||
|
mixedPieces.push(minp);
|
||||||
|
mixedPieces.push(shortp);
|
||||||
|
mixedPieces.push(longp);
|
||||||
|
}
|
||||||
|
// Sorting makes sure if one weekday (or abbr) is a prefix of another it
|
||||||
|
// will match the longer piece.
|
||||||
|
minPieces.sort(cmpLenRev);
|
||||||
|
shortPieces.sort(cmpLenRev);
|
||||||
|
longPieces.sort(cmpLenRev);
|
||||||
|
mixedPieces.sort(cmpLenRev);
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
shortPieces[i] = regexEscape(shortPieces[i]);
|
||||||
|
longPieces[i] = regexEscape(longPieces[i]);
|
||||||
|
mixedPieces[i] = regexEscape(mixedPieces[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
|
||||||
|
this._weekdaysShortRegex = this._weekdaysRegex;
|
||||||
|
this._weekdaysMinRegex = this._weekdaysRegex;
|
||||||
|
|
||||||
|
this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
|
||||||
|
this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
|
||||||
|
this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
|
||||||
|
}
|
||||||
|
|
||||||
// FORMATTING
|
// FORMATTING
|
||||||
|
|
||||||
addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
|
addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
|
||||||
@ -2770,8 +3066,13 @@
|
|||||||
return this.hours() % 12 || 12;
|
return this.hours() % 12 || 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function kFormat() {
|
||||||
|
return this.hours() || 24;
|
||||||
|
}
|
||||||
|
|
||||||
addFormatToken('H', ['HH', 2], 0, 'hour');
|
addFormatToken('H', ['HH', 2], 0, 'hour');
|
||||||
addFormatToken('h', ['hh', 2], 0, hFormat);
|
addFormatToken('h', ['hh', 2], 0, hFormat);
|
||||||
|
addFormatToken('k', ['kk', 2], 0, kFormat);
|
||||||
|
|
||||||
addFormatToken('hmm', 0, 0, function () {
|
addFormatToken('hmm', 0, 0, function () {
|
||||||
return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
|
return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
|
||||||
@ -3232,6 +3533,13 @@
|
|||||||
prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
|
prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
|
||||||
prototype__proto.weekdaysParse = localeWeekdaysParse;
|
prototype__proto.weekdaysParse = localeWeekdaysParse;
|
||||||
|
|
||||||
|
prototype__proto._weekdaysRegex = defaultWeekdaysRegex;
|
||||||
|
prototype__proto.weekdaysRegex = weekdaysRegex;
|
||||||
|
prototype__proto._weekdaysShortRegex = defaultWeekdaysShortRegex;
|
||||||
|
prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
|
||||||
|
prototype__proto._weekdaysMinRegex = defaultWeekdaysMinRegex;
|
||||||
|
prototype__proto.weekdaysMinRegex = weekdaysMinRegex;
|
||||||
|
|
||||||
// Hours
|
// Hours
|
||||||
prototype__proto.isPM = localeIsPM;
|
prototype__proto.isPM = localeIsPM;
|
||||||
prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
|
prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
|
||||||
@ -3243,7 +3551,7 @@
|
|||||||
return locale[field](utc, format);
|
return locale[field](utc, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
function list (format, index, field, count, setter) {
|
function listMonthsImpl (format, index, field) {
|
||||||
if (typeof format === 'number') {
|
if (typeof format === 'number') {
|
||||||
index = format;
|
index = format;
|
||||||
format = undefined;
|
format = undefined;
|
||||||
@ -3252,35 +3560,79 @@
|
|||||||
format = format || '';
|
format = format || '';
|
||||||
|
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
return lists__get(format, index, field, setter);
|
return lists__get(format, index, field, 'month');
|
||||||
}
|
}
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
var out = [];
|
var out = [];
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
out[i] = lists__get(format, i, field, setter);
|
out[i] = lists__get(format, i, field, 'month');
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ()
|
||||||
|
// (5)
|
||||||
|
// (fmt, 5)
|
||||||
|
// (fmt)
|
||||||
|
// (true)
|
||||||
|
// (true, 5)
|
||||||
|
// (true, fmt, 5)
|
||||||
|
// (true, fmt)
|
||||||
|
function listWeekdaysImpl (localeSorted, format, index, field) {
|
||||||
|
if (typeof localeSorted === 'boolean') {
|
||||||
|
if (typeof format === 'number') {
|
||||||
|
index = format;
|
||||||
|
format = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
format = format || '';
|
||||||
|
} else {
|
||||||
|
format = localeSorted;
|
||||||
|
index = format;
|
||||||
|
localeSorted = false;
|
||||||
|
|
||||||
|
if (typeof format === 'number') {
|
||||||
|
index = format;
|
||||||
|
format = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
format = format || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var locale = locale_locales__getLocale(),
|
||||||
|
shift = localeSorted ? locale._week.dow : 0;
|
||||||
|
|
||||||
|
if (index != null) {
|
||||||
|
return lists__get(format, (index + shift) % 7, field, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
|
var out = [];
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
out[i] = lists__get(format, (i + shift) % 7, field, 'day');
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
function lists__listMonths (format, index) {
|
function lists__listMonths (format, index) {
|
||||||
return list(format, index, 'months', 12, 'month');
|
return listMonthsImpl(format, index, 'months');
|
||||||
}
|
}
|
||||||
|
|
||||||
function lists__listMonthsShort (format, index) {
|
function lists__listMonthsShort (format, index) {
|
||||||
return list(format, index, 'monthsShort', 12, 'month');
|
return listMonthsImpl(format, index, 'monthsShort');
|
||||||
}
|
}
|
||||||
|
|
||||||
function lists__listWeekdays (format, index) {
|
function lists__listWeekdays (localeSorted, format, index) {
|
||||||
return list(format, index, 'weekdays', 7, 'day');
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
|
||||||
}
|
}
|
||||||
|
|
||||||
function lists__listWeekdaysShort (format, index) {
|
function lists__listWeekdaysShort (localeSorted, format, index) {
|
||||||
return list(format, index, 'weekdaysShort', 7, 'day');
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
|
||||||
}
|
}
|
||||||
|
|
||||||
function lists__listWeekdaysMin (format, index) {
|
function lists__listWeekdaysMin (localeSorted, format, index) {
|
||||||
return list(format, index, 'weekdaysMin', 7, 'day');
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
|
||||||
}
|
}
|
||||||
|
|
||||||
locale_locales__getSetGlobalLocale('en', {
|
locale_locales__getSetGlobalLocale('en', {
|
||||||
@ -3651,7 +4003,7 @@
|
|||||||
// Side effect imports
|
// Side effect imports
|
||||||
|
|
||||||
|
|
||||||
utils_hooks__hooks.version = '2.12.0';
|
utils_hooks__hooks.version = '2.13.0';
|
||||||
|
|
||||||
setHookCallback(local__createLocal);
|
setHookCallback(local__createLocal);
|
||||||
|
|
||||||
|
6
library/moment/moment.min.js
vendored
6
library/moment/moment.min.js
vendored
File diff suppressed because one or more lines are too long
8878
util/hmessages.po
8878
util/hmessages.po
File diff suppressed because it is too large
Load Diff
@ -19,15 +19,10 @@ function enableDisableFinishDate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function on_fullscreen() {
|
function on_fullscreen() {
|
||||||
var view = $('#events-calendar').fullCalendar('getView');
|
$('#events-calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (.generic-content-wrapper top and bottom) of .generic-content-wrapper
|
||||||
if(view.type === 'month') {
|
|
||||||
$('#events-calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (top and bottom) of .generic-content-wrapper
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function on_inline() {
|
function on_inline() {
|
||||||
var view = $('#events-calendar').fullCalendar('getView');
|
var view = $('#events-calendar').fullCalendar('getView');
|
||||||
if(view.type === 'month') {
|
((view.type === 'month') ? $('#events-calendar').fullCalendar('option', 'height', '') : $('#events-calendar').fullCalendar('option', 'height', 'auto'));
|
||||||
$('#events-calendar').fullCalendar('option', 'height', '');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
[region=aside]
|
[region=aside]
|
||||||
[widget=eventsmenu][/widget]
|
|
||||||
[widget=eventstools][/widget]
|
[widget=eventstools][/widget]
|
||||||
[widget=tasklist][/widget]
|
[widget=tasklist][/widget]
|
||||||
[/region]
|
[/region]
|
||||||
|
@ -56,13 +56,13 @@ $(document).ready(function() {
|
|||||||
function makeFullScreen(full) {
|
function makeFullScreen(full) {
|
||||||
if(typeof full=='undefined' || full == true) {
|
if(typeof full=='undefined' || full == true) {
|
||||||
$('main').css({'transition': 'none'}).addClass('fullscreen');
|
$('main').css({'transition': 'none'}).addClass('fullscreen');
|
||||||
$('#fullscreen-btn, header, nav, aside').css({'display': 'none'});
|
$('#fullscreen-btn, header, nav, aside, #tabs-collapse-1').css({'visibility': 'hidden'});
|
||||||
$('#inline-btn').show();
|
$('#inline-btn').show();
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('main').removeClass('fullscreen');
|
$('main').removeClass('fullscreen');
|
||||||
$('#fullscreen-btn, header, nav, aside').css({'display': ''});
|
$('#fullscreen-btn, header, nav, aside, #tabs-collapse-1').css({'visibility': ''});
|
||||||
$('#inline-btn').hide();
|
$('#inline-btn').hide();
|
||||||
$('main').css({'transition': ''});
|
$('main').css({'transition': ''});
|
||||||
}
|
}
|
||||||
|
@ -30,18 +30,18 @@
|
|||||||
function changeView(action, viewName) {
|
function changeView(action, viewName) {
|
||||||
$('#events-calendar').fullCalendar(action, viewName);
|
$('#events-calendar').fullCalendar(action, viewName);
|
||||||
var view = $('#events-calendar').fullCalendar('getView');
|
var view = $('#events-calendar').fullCalendar('getView');
|
||||||
if(view.type === 'agendaDay' || view.type === 'agendaWeek') {
|
|
||||||
|
if(view.type !== 'month' && !$('main').hasClass('fullscreen')) {
|
||||||
$('#events-calendar').fullCalendar('option', 'height', 'auto');
|
$('#events-calendar').fullCalendar('option', 'height', 'auto');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if($('main').hasClass('fullscreen')) {
|
$('#events-calendar').fullCalendar('option', 'height', '');
|
||||||
$('#calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (.generic-content-wrapper top and bottom) of .generic-content-wrapper
|
}
|
||||||
|
|
||||||
|
if($('main').hasClass('fullscreen')) {
|
||||||
|
$('#events-calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (.generic-content-wrapper top and bottom) of .generic-content-wrapper
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$('#calendar').fullCalendar('option', 'height', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$('#title').text(view.title);
|
$('#title').text(view.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
<div class="generic-content-wrapper">
|
<div class="generic-content-wrapper">
|
||||||
<div class="section-title-wrapper">
|
<div class="section-title-wrapper">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
<div class="dropdown">
|
||||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||||
|
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><i class="fa fa-caret-down"></i> {{$view_label}}</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="#" onclick="changeView('changeView', 'month'); return false;">{{$month}}</a></li>
|
||||||
|
<li><a href="#" onclick="changeView('changeView', 'agendaWeek'); return false;">{{$week}}</a></li>
|
||||||
|
<li><a href="#" onclick="changeView('changeView', 'agendaDay'); return false;">{{$day}}</a></li>
|
||||||
|
</ul>
|
||||||
<button class="btn btn-success btn-xs" onclick="openClose('form');">{{$new_event.1}}</button>
|
<button class="btn btn-success btn-xs" onclick="openClose('form');">{{$new_event.1}}</button>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-default btn-xs" onclick="changeView('prev', false);" title="{{$prev}}"><i class="fa fa-backward"></i></button>
|
<button class="btn btn-default btn-xs" onclick="changeView('prev', false);" title="{{$prev}}"><i class="fa fa-backward"></i></button>
|
||||||
@ -10,6 +17,7 @@
|
|||||||
<button class="btn btn-default btn-xs" onclick="changeView('next', false);" title="{{$next}}"><i class="fa fa-forward"></i></button>
|
<button class="btn btn-default btn-xs" onclick="changeView('next', false);" title="{{$next}}"><i class="fa fa-forward"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<h2 id="title"></h2>
|
<h2 id="title"></h2>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
|
72
view/tpl/force_image_reload.tpl
Normal file
72
view/tpl/force_image_reload.tpl
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{{*
|
||||||
|
Force the browser to reload an image from the server instead of the cache.
|
||||||
|
based on an answer from http://stackoverflow.com/a/22429796/3343347
|
||||||
|
|
||||||
|
Usage: Set $imgUrl to the src url you want to be re-fetched from the server
|
||||||
|
|
||||||
|
*}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(
|
||||||
|
function() {
|
||||||
|
forceImgReload("{{$imgUrl}}");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
{{*
|
||||||
|
* find and return any existing img tags with a matching src url, and set them to an intermediate
|
||||||
|
* src url so they can later be reverted back once the cached version has been updated.
|
||||||
|
*}}
|
||||||
|
function prepareImagesForReload(srcUrl) {
|
||||||
|
|
||||||
|
var result = $("img[src='" + srcUrl + "']").get();
|
||||||
|
|
||||||
|
for (i = 0; i < result.length; i++) {
|
||||||
|
{{*
|
||||||
|
* Set the image to a reloading image, in this case an animated "reloading" svg
|
||||||
|
* Ideally this wont be displayed long enough to matter.
|
||||||
|
*}}
|
||||||
|
result[i].src = "data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='xMidYMid' class='uil-reload'%3E%3Cpath fill='none' class='bk' d='M0 0h100v100H0z'/%3E%3Cg%3E%3Cpath d='M50 15a35 35 0 1 0 24.787 10.213' fill='none' stroke='%23777' stroke-width='12'/%3E%3Cpath d='M50 0v30l16-15L50 0' fill='%23777'/%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 50 50' to='360 50 50' dur='1s' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreImages(srcUrl, imgList) {
|
||||||
|
|
||||||
|
for (i = 0; i < imgList.length; i++) {
|
||||||
|
imgList[i].src = srcUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceImgReload(srcUrl) {
|
||||||
|
var imgList;
|
||||||
|
var step = 0;
|
||||||
|
var iframe = window.document.createElement("iframe"); // Hidden iframe, in which to perform the load+reload.
|
||||||
|
|
||||||
|
{{* Callback function, called after iframe load+reload completes (or fails).
|
||||||
|
Will be called TWICE unless twostage-mode process is cancelled. (Once after load, once after reload). *}}
|
||||||
|
var iframeLoadCallback = function(e) {
|
||||||
|
|
||||||
|
if (step === 0) {
|
||||||
|
// initial load just completed. Note that it doesn't actually matter if this load succeeded or not.
|
||||||
|
|
||||||
|
step = 1;
|
||||||
|
imgList = prepareImagesForReload(srcUrl);
|
||||||
|
iframe.contentWindow.location.reload(true); // initiate forced-reload!
|
||||||
|
|
||||||
|
} else if (step === 1) {
|
||||||
|
// forced re-load is done
|
||||||
|
|
||||||
|
restoreImages(srcUrl, imgList);
|
||||||
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe.style.display = "none";
|
||||||
|
window.parent.document.body.appendChild(iframe); {{* NOTE: if this is done AFTER setting src, Firefox MAY fail to fire the load event! *}}
|
||||||
|
iframe.addEventListener("load", iframeLoadCallback, false);
|
||||||
|
iframe.addEventListener("error", iframeLoadCallback, false);
|
||||||
|
iframe.src = srcUrl;
|
||||||
|
}
|
||||||
|
</script>
|
@ -190,6 +190,7 @@
|
|||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
wiki_refresh_page_list();
|
wiki_refresh_page_list();
|
||||||
|
$("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"});
|
||||||
// Show Edit tab first. Otherwise the Ace editor does not load.
|
// Show Edit tab first. Otherwise the Ace editor does not load.
|
||||||
$("#wiki-nav-tabs li:eq(1) a").tab('show');
|
$("#wiki-nav-tabs li:eq(1) a").tab('show');
|
||||||
});
|
});
|
||||||
@ -203,6 +204,7 @@
|
|||||||
$.post("wiki/{{$channel}}/preview", {content: editor.getValue(), resource_id: window.wiki_resource_id}, function (data) {
|
$.post("wiki/{{$channel}}/preview", {content: editor.getValue(), resource_id: window.wiki_resource_id}, function (data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
$('#wiki-preview').html(data.html);
|
$('#wiki-preview').html(data.html);
|
||||||
|
$("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"});
|
||||||
} else {
|
} else {
|
||||||
window.console.log('Error previewing page.');
|
window.console.log('Error previewing page.');
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user