Browse Source

- Huge refactoring of the code structure

- Also removing old files
pull/16/head
Jaussoin Timothée 13 years ago
parent
commit
cd7cec588c
  1. 0
      app/assets/documents/Doxyfile
  2. 0
      app/assets/documents/Makefile
  3. 0
      app/assets/documents/fdl.texi
  4. 0
      app/assets/documents/movim.png
  5. 0
      app/assets/documents/movim.texi
  6. 0
      app/assets/documents/texi.css
  7. 0
      app/assets/documents/texi2htmlrc
  8. 0
      app/assets/js/events.js
  9. 0
      app/assets/js/hash.js
  10. 0
      app/assets/js/images/marker-icon.png
  11. 0
      app/assets/js/leaflet.css
  12. 0
      app/assets/js/leaflet.js
  13. 0
      app/assets/js/movim.js
  14. 0
      app/assets/js/movimrpc.js
  15. 18
      build.sh
  16. 145
      image.php
  17. 2
      jajax.php
  18. 0
      lib/Markdown.php
  19. 0
      lib/XMPPtoForm.php
  20. 57
      loader.php
  21. 0
      locales/ar.po
  22. 0
      locales/be.po
  23. 0
      locales/br.po
  24. 0
      locales/da.po
  25. 0
      locales/de.po
  26. 0
      locales/el.po
  27. 0
      locales/eo.po
  28. 0
      locales/es.po
  29. 0
      locales/fi.po
  30. 0
      locales/fr.po
  31. 0
      locales/gl.po
  32. 0
      locales/he.po
  33. 0
      locales/it.po
  34. 0
      locales/ja.po
  35. 0
      locales/messages.pot
  36. 0
      locales/nl.po
  37. 0
      locales/no.po
  38. 0
      locales/oc.po
  39. 0
      locales/pt.po
  40. 0
      locales/ro.po
  41. 0
      locales/ru.po
  42. 0
      locales/uk.po
  43. 0
      locales/update_po.sh
  44. 0
      locales/update_trans.sh
  45. 0
      locales/zh.po
  46. 71
      system/Controller/ControllerAjax.php
  47. 147
      system/Controller/ControllerBase.php
  48. 392
      system/Controller/ControllerMain.php
  49. 165
      system/LGPLv3
  50. 1
      system/RPC.php
  51. 1
      system/Route.php
  52. 2
      system/Tpl/TplPageBuilder.php
  53. 70
      system/Utils.php
  54. 227
      system/Widget/WidgetBase.php
  55. 585
      system/Widget/WidgetCommon.php
  56. 228
      system/Widget/WidgetWrapper.php
  57. 4
      system/Widget/widgets/.dir-locals.el
  58. 123
      system/Widget/widgets/About/About.php
  59. 466
      system/Widget/widgets/Account/Account.php
  60. 10
      system/Widget/widgets/Account/account.css
  61. 3
      system/Widget/widgets/Account/account.js
  62. 246
      system/Widget/widgets/Account/server-vcards.xml
  63. 484
      system/Widget/widgets/Admin/Admin.php
  64. 29
      system/Widget/widgets/Blog/Blog.php
  65. 280
      system/Widget/widgets/Bookmark/Bookmark.php
  66. 7
      system/Widget/widgets/Bookmark/bookmark.css
  67. 438
      system/Widget/widgets/Chat/Chat.php
  68. 192
      system/Widget/widgets/Chat/chat.css
  69. 102
      system/Widget/widgets/Chat/chat.js
  70. BIN
      system/Widget/widgets/Chat/img/arrow.png
  71. BIN
      system/Widget/widgets/Chat/img/cross.png
  72. BIN
      system/Widget/widgets/Chat/sound/notif.ogg
  73. 150
      system/Widget/widgets/ChatExt/ChatExt.php
  74. 0
      system/Widget/widgets/ChatExt/chatext.css
  75. 31
      system/Widget/widgets/ChatExt/chatext.js
  76. 45
      system/Widget/widgets/ChatPop/ChatPop.php
  77. 161
      system/Widget/widgets/ChatPop/chatpop.css
  78. 46
      system/Widget/widgets/ChatPop/chatpop.js
  79. BIN
      system/Widget/widgets/ChatPop/img/cross.png
  80. 196
      system/Widget/widgets/Config/Config.php
  81. BIN
      system/Widget/widgets/Config/color/arrow.gif
  82. BIN
      system/Widget/widgets/Config/color/cross.gif
  83. 12
      system/Widget/widgets/Config/color/demo.html
  84. BIN
      system/Widget/widgets/Config/color/hs.png
  85. BIN
      system/Widget/widgets/Config/color/hv.png
  86. 953
      system/Widget/widgets/Config/color/jscolor.js
  87. 0
      system/Widget/widgets/Config/config.css
  88. 104
      system/Widget/widgets/ConfigData/ConfigData.php
  89. 0
      system/Widget/widgets/ConfigData/configdata.css
  90. 143
      system/Widget/widgets/ContactCard/ContactCard.php
  91. 8
      system/Widget/widgets/ContactCard/contactcard.css
  92. 212
      system/Widget/widgets/ContactInfo/ContactInfo.php
  93. 83
      system/Widget/widgets/ContactManage/ContactManage.php
  94. 75
      system/Widget/widgets/ContactPubsubSubscription/ContactPubsubSubscription.php
  95. 121
      system/Widget/widgets/ContactSummary/ContactSummary.php
  96. 1
      system/Widget/widgets/ContactSummary/contactsummary.css
  97. 160
      system/Widget/widgets/Explore/Explore.php
  98. 4
      system/Widget/widgets/Explore/explore.css
  99. 213
      system/Widget/widgets/Feed/Feed.php
  100. 1
      system/Widget/widgets/Feed/feed.css

0
documentation/Doxyfile → app/assets/documents/Doxyfile

0
documentation/Makefile → app/assets/documents/Makefile

0
documentation/fdl.texi → app/assets/documents/fdl.texi

0
documentation/movim.png → app/assets/documents/movim.png

Before

Width: 650  |  Height: 650  |  Size: 51 KiB

After

Width: 650  |  Height: 650  |  Size: 51 KiB

0
documentation/movim.texi → app/assets/documents/movim.texi

0
documentation/texi.css → app/assets/documents/texi.css

0
documentation/texi2htmlrc → app/assets/documents/texi2htmlrc

0
system/js/events.js → app/assets/js/events.js

0
system/js/hash.js → app/assets/js/hash.js

0
system/js/images/marker-icon.png → app/assets/js/images/marker-icon.png

Before

Width: 25  |  Height: 41  |  Size: 1.7 KiB

After

Width: 25  |  Height: 41  |  Size: 1.7 KiB

0
system/js/leaflet.css → app/assets/js/leaflet.css

0
system/js/leaflet.js → app/assets/js/leaflet.js

0
system/js/movim.js → app/assets/js/movim.js

0
system/js/movimrpc.js → app/assets/js/movimrpc.js

18
build.sh

@ -1,6 +1,6 @@
#!/bin/bash
SYSTEM_PATH=system
LIB_PATH=lib
MOXL_REPO="lp:moxl"
MODL_REPO="lp:modl"
VERSION=`cat VERSION`
@ -15,9 +15,9 @@ package() {
cd $PACKAGENAME
moxl
rm -rf "$SYSTEM_PATH/Moxl/.bzr"
rm -rf "$LIB_PATH/Moxl/.bzr"
modl
rm -rf "$SYSTEM_PATH/Modl/.bzr"
rm -rf "$LIB_PATH/Modl/.bzr"
# Compressing
cd ..
@ -34,8 +34,8 @@ moxl() {
moxl_temp="Moxl"
# Checking out Moxl.
bzr branch $MOXL_REPO $moxl_temp
rm -rf "$SYSTEM_PATH/Moxl"
cp -r "$moxl_temp/" $SYSTEM_PATH
rm -rf "$LIB_PATH/Moxl"
cp -r "$moxl_temp/" $LIB_PATH
rm -rf $moxl_temp
}
@ -43,14 +43,14 @@ modl() {
modl_temp="Modl"
# Checking out Modl.
bzr branch $MODL_REPO $modl_temp
rm -rf "$SYSTEM_PATH/Modl"
cp -r "$modl_temp/" $SYSTEM_PATH
rm -rf "$LIB_PATH/Modl"
cp -r "$modl_temp/" $LIB_PATH
rm -rf $modl_temp
}
clean() {
rm -rf "${SYSTEM_PATH}/Moxl"
rm -rf "${SYSTEM_PATH}/Modl"
rm -rf "${LIB_PATH}/Moxl"
rm -rf "${LIB_PATH}/Modl"
rm -rf Modl
rm -rf Moxl
}

145
image.php

@ -1,145 +0,0 @@
<?php
/**
* @file images.php
* This file is part of MOVIM.
*
* @brief The movim's images handler.
*
* @author Edhelas <edhelas@gmail.com>
*
* @version 1.0
* @date 22 November 2011
*
* Copyright (C)2010 MOVIM team
*
* See the file `COPYING' for licensing information.
*/
/*
ini_set('log_errors', 1);
ini_set('display_errors', 0);
ini_set('error_reporting', E_ALL ^ E_DEPRECATED ^ E_NOTICE);
ini_set('error_log', 'log/php.log');
require("init.php");
global $sdb;
function display_image($hash, $type) {
ob_clean();
ob_start();
header("ETag: \"{$hash}\"");
header("Accept-Ranges: bytes");
header("Content-type: ".$type);
//header("Cache-Control: max-age=".rand(1, 5)*3600);
header('Date: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+24*60*60) . ' GMT');
}
function display_default() {
ob_clean();
ob_start();
$content = file_get_contents('themes/movim/img/default.svg');
display_image($hash, "image/svg+xml");
echo $content;
exit;
}
if (!function_exists('getallheaders')) {
function getallheaders() {
foreach($_SERVER as $key=>$value) {
if (substr($key,0,5)=="HTTP_") {
$key=str_replace(" ","-",ucwords(strtolower(str_replace("_"," ",substr($key,5)))));
$out[$key]=$value;
}else{
$out[$key]=$value;
}
}
return $out;
}
}
// We load the avatar from the database and we display it
$hash = md5($_GET['c'].$_GET['size']);
$headers = getallheaders();
ob_clean();
ob_start();
if (ereg($hash, $headers['If-None-Match']))
{
header('HTTP/1.1 304 Not Modified');
exit;
} elseif($_GET['c'] == '' || $_GET['c'] == 'default') {
display_default();
} else {
$user = new User();
if($user->isLogged())
$where = array('jid' => $_GET['c']);
else
$where = array('jid' => $_GET['c']);
$c = new Contact();
$query = Contact::query()->select()
->where($where);
$contact = Contact::run_query($query);
if(isset($contact[0]) &&
$contact[0]->getData('phototype') != '' &&
$contact[0]->getData('photobin') != '' &&
$contact[0]->getData('phototype') != 'f' &&
$contact[0]->getData('photobin') != 'f') {
if(isset($_GET['size']) && $_GET['size'] != 'normal') {
switch ($_GET['size']) {
case 'l':
$size = 150;
break;
case 'm':
$size = 120;
break;
case 's':
$size = 50;
break;
case 'xs':
$size = 24;
break;
}
$thumb = imagecreatetruecolor($size, $size);
$white = imagecolorallocate($thumb, 255, 255, 255);
imagefill($thumb, 0, 0, $white);
$source = imagecreatefromstring(base64_decode($contact[0]->getData('photobin')));
$width = imagesx($source);
$height = imagesy($source);
if($width >= $height) {
// For landscape images
$x_offset = ($width - $height) / 2;
$y_offset = 0;
$square_size = $width - ($x_offset * 2);
} else {
// For portrait and square images
$x_offset = 0;
$y_offset = ($height - $width) / 2;
$square_size = $height - ($y_offset * 2);
}
if($source) {
imagecopyresampled($thumb, $source, 0, 0, $x_offset, $y_offset, $size, $size, $square_size, $square_size);
display_image($hash, "image/jpeg");
imagejpeg($thumb, NULL, 95);
}
} elseif(isset($_GET['size']) && $_GET['size'] == 'normal') { // The original picture
display_image($hash, $contact[0]->getData('phototype'));
echo base64_decode($contact[0]->getData('photobin'));
}
} else {
display_default();
}
}
*/

2
jajax.php

@ -21,7 +21,7 @@ ini_set('display_errors', 0);
ini_set('error_reporting', E_ALL ^ E_DEPRECATED ^ E_NOTICE);
ini_set('error_log', 'log/php.log');
require("init.php");
require('init.php');
set_time_limit(200);

0
system/Markdown.php → lib/Markdown.php

0
system/XMPPtoForm.php → lib/XMPPtoForm.php

57
loader.php

@ -3,25 +3,32 @@
// A few constants...
define('BASE_PATH', dirname(__FILE__) . '/');
define('APP_NAME', 'movim');
define('LIB_PATH', BASE_PATH.'system/');
define('PROPERTIES_PATH', BASE_PATH.'page/properties/');
define('THEMES_PATH', BASE_PATH . 'themes/');
define('USERS_PATH', BASE_PATH . 'users/');
#define('LIB_PATH', BASE_PATH.'system/');
define('THEMES_PATH', BASE_PATH . 'themes/');
define('USERS_PATH', BASE_PATH . 'users/');
define('APP_PATH', BASE_PATH . 'app/');
define('SYSTEM_PATH', BASE_PATH . 'system/');
define('LIB_PATH', BASE_PATH . 'lib/');
define('LOCALES_PATH', BASE_PATH . 'locales/');
// Loads up all system libraries.
require_once(LIB_PATH . "Lang/i18n.php");
require_once(LIB_PATH . "Session.php");
require_once(LIB_PATH . "Utils.php");
require_once(LIB_PATH . "UtilsString.php");
require_once(LIB_PATH . "UtilsPicture.php");
require_once(LIB_PATH . "Cache.php");
require_once(LIB_PATH . "Conf.php");
require_once(LIB_PATH . "Event.php");
require_once(LIB_PATH . "Logger.php");
require_once(LIB_PATH . "MovimException.php");
require_once(LIB_PATH . "RPC.php");
require_once(LIB_PATH . "User.php");
require_once(SYSTEM_PATH . "i18n/i18n.php");
require_once(SYSTEM_PATH . "Session.php");
require_once(SYSTEM_PATH . "Utils.php");
require_once(SYSTEM_PATH . "UtilsString.php");
require_once(SYSTEM_PATH . "UtilsPicture.php");
require_once(SYSTEM_PATH . "Cache.php");
require_once(SYSTEM_PATH . "Conf.php");
require_once(SYSTEM_PATH . "Event.php");
require_once(SYSTEM_PATH . "Logger.php");
require_once(SYSTEM_PATH . "MovimException.php");
require_once(SYSTEM_PATH . "RPC.php");
require_once(SYSTEM_PATH . "User.php");
// LIBRARIES
// XMPPtoForm lib
require_once(LIB_PATH . "XMPPtoForm.php");
// Markdown lib
@ -36,17 +43,17 @@ $db->setConnection(Conf::getServerConfElement('db'));
// We load Movim XMPP Library
require_once(LIB_PATH . 'Moxl/loader.php');
require_once(LIB_PATH . "Controller/ControllerBase.php");
require_once(LIB_PATH . "Controller/ControllerMain.php");
require_once(LIB_PATH . "Controller/ControllerAjax.php");
require_once(APP_PATH . "controllers/ControllerBase.php");
require_once(APP_PATH . "controllers/ControllerMain.php");
require_once(APP_PATH . "controllers/ControllerAjax.php");
require_once(LIB_PATH . "Route.php");
require_once(SYSTEM_PATH . "Route.php");
require_once(LIB_PATH . "Tpl/TplPageBuilder.php");
require_once(SYSTEM_PATH . "Tpl/TplPageBuilder.php");
require_once(LIB_PATH . "Widget/WidgetBase.php");
require_once(LIB_PATH . "Widget/WidgetCommon.php");
require_once(LIB_PATH . "Widget/WidgetWrapper.php");
require_once(APP_PATH . "widget/WidgetBase.php");
require_once(APP_PATH . "widget/WidgetCommon.php");
require_once(APP_PATH . "widget/WidgetWrapper.php");
// We set the default timezone to the server timezone

0
i18n/ar.po → locales/ar.po

0
i18n/be.po → locales/be.po

0
i18n/br.po → locales/br.po

0
i18n/da.po → locales/da.po

0
i18n/de.po → locales/de.po

0
i18n/el.po → locales/el.po

0
i18n/eo.po → locales/eo.po

0
i18n/es.po → locales/es.po

0
i18n/fi.po → locales/fi.po

0
i18n/fr.po → locales/fr.po

0
i18n/gl.po → locales/gl.po

0
i18n/he.po → locales/he.po

0
i18n/it.po → locales/it.po

0
i18n/ja.po → locales/ja.po

0
i18n/messages.pot → locales/messages.pot

0
i18n/nl.po → locales/nl.po

0
i18n/no.po → locales/no.po

0
i18n/oc.po → locales/oc.po

0
i18n/pt.po → locales/pt.po

0
i18n/ro.po → locales/ro.po

0
i18n/ru.po → locales/ru.po

0
i18n/uk.po → locales/uk.po

0
i18n/update_po.sh → locales/update_po.sh

0
i18n/update_trans.sh → locales/update_trans.sh

0
i18n/zh.po → locales/zh.po

71
system/Controller/ControllerAjax.php

@ -1,71 +0,0 @@
<?php
/**
* @file ControllerAjax.php
* This file is part of PROJECT.
*
* @brief Description
*
* @author Guillaume Pasquet <email@addre.ss>
*
* @version 1.0
* @date 8 November 2010
*
* Copyright (C)2010 PROPRIETOR
*
* OTHER T&C IF ANY
*/
class ControllerAjax extends ControllerBase
{
protected $funclist = array();
protected static $instance;
public function __construct()
{
parent::__construct();
}
public static function getInstance()
{
if(!is_object(self::$instance)) {
self::$instance = new ControllerAjax();
}
return self::$instance;
}
/**
* Generates the javascript part of the ajax.
*/
public function genJs()
{
if(empty($this->funclist)) {
return '';
}
$buffer = '<script type="text/javascript">';
foreach($this->funclist as $funcdef) {
$parlist = implode(', ', $funcdef['params']);
$buffer .= "function " . $funcdef['object'] . '_'
. $funcdef['funcname'] . "(${parlist}) {";
$buffer .= "movim_ajaxSend('".$funcdef['object']."', '".$funcdef['funcname']."', [${parlist}]);}\n";
}
return $buffer . "</script>\n";
}
/**
* Defines a new function.
*/
public function defun($widget, $funcname, array $params)
{
$this->funclist[] = array(
'object' => $widget,
'funcname' => $funcname,
'params' => $params,
);
}
}
?>

147
system/Controller/ControllerBase.php

@ -1,147 +0,0 @@
<?php
/**
* @file Controller.php
* This file is part of MOVIM.
*
* @brief Implements a request handler that ensures application worklfow.
*
* @author Movim Project <movim@movim.eu>
*
* @version 1.0
* @date 13 October 2010
*
* Copyright (C)2010 Movim Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
class ControllerBase
{
protected $default_handler = 'index';
protected $token;
public function __construct($token = 'q')
{
$this->load_language();
$this->token = $token;
}
public function handle()
{
$r = new Route();
// Note that the request is always specified by 'q'.
$request;
if($request = $this->fetch_get('q')) {
$this->run_req($request);
} else {
$this->run_req($this->default_handler);
}
}
/**
* Loads up the language, either from the User or default.
*/
function load_language() {
$user = new user();
if($user->isLogged()) {
try{
$lang = $user->getConfig('language');
load_language($lang);
}
catch(MovimException $e) {
// Load default language.
load_language(Conf::getServerConfElement('defLang'));
}
}
else if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
load_language_auto();
}
else {
load_language(Conf::getServerConfElement('defLang'));
}
}
/**
* Attempts to call back the given function.
*/
protected function run_req($request)
{
if(is_callable(array($this, $request))) {
call_user_func(array($this, $request));
} else {
$this->error404();
}
}
/**
* Returns the value of a $_GET variable. Mainly used to avoid getting
* notices from PHP when attempting to fetch an empty variable.
* @param name is the desired variable's name.
* @return the value of the requested variable, or FALSE.
*/
protected function fetch_get($name)
{
if(isset($_GET[$name])) {
return htmlentities($_GET[$name]);
} else {
return false;
}
}
/**
* Returns the value of a $_POST variable. Mainly used to avoid getting
* notices from PHP when attempting to fetch an empty variable.
* @param name is the desired variable's name.
* @return the value of the requested variable, or FALSE.
*/
protected function fetch_post($name)
{
if(isset($_POST[$name])) {
return htmlentities($_POST[$name]);
} else {
return false;
}
}
/**
* Return a basic auth page for the administration area
*/
protected function authenticate(){
header('WWW-Authenticate: Basic realm="Enter admin username/password"');
header('HTTP/1.0 401 Unauthorized');
echo 'Why are you hitting cancel?';
exit;
}
/**
* Makes an error 404 page.
*/
protected function error404()
{
//echo 'Error 404 - Page not found';
$page = new TplPageBuilder();
$page->setTitle(t('%s - 404', APP_TITLE));
$page->menuAddLink(t('Home'), 'main', true);
$content = new TplPageBuilder();
$page->setContent($content->build('404.tpl'));
echo $page->build('page.tpl');
}
}
?>

392
system/Controller/ControllerMain.php

@ -1,392 +0,0 @@
<?php
/**
* @file ControllerMain.php
* This file is part of MOVIM.
*
* @brief Handles incoming static pages requests.
*
* @author Etenil <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 21 October 2010
*
* Copyright (C)2010 MOVIM Project
*
* See COPYING for licensing deatils.
*/
class ControllerMain extends ControllerBase
{
protected $default_handler = 'main';
private $page;
function __construct()
{
parent::__construct();
$this->page = new TplPageBuilder();
$this->page->addScript('movim.js');
$this->page->addScript('hash.js');
$this->page->addScript('movimrpc.js');
}
function main()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Welcome to Movim', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main', true);
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('main.tpl'));
echo $this->page->build('page.tpl');
}
}
function friend()
{
$user = new User();
$cd = new \modl\ContactDAO();
$contact = $cd->get($_GET['f']);
if(isset($contact))
$name = $contact->getTrueName();
else
$name = $_GET['f'];
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['f']) && $_GET['f'] != "" ) {
$this->page->setTitle(APP_TITLE.' - '.$name);
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('friend.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function server()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['s']) && $_GET['s'] != "" ) {
$this->page->setTitle(APP_TITLE.' - Server');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('server.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function node()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['n']) && $_GET['n'] != "" ) {
$this->page->setTitle(APP_TITLE.' - Node');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('node.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function media()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(APP_TITLE.' - Node');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media', true);
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('media.tpl'));
echo $this->page->build('page.tpl');
}
}
function conf()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Configuration', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf', true);
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('conf.tpl'));
echo $this->page->build('page.tpl');
}
}
function profile()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Profile', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile', true);
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('profile.tpl'));
echo $this->page->build('page.tpl');
}
}
function account()
{
$this->page->setTitle(t('%s - Account', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Account Creation'), 'account', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('account.tpl'));
echo $this->page->build('page.tpl');
}
function blog()
{
$this->page->setTitle(t('%s - Account', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Blog'), 'blog', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('blog.tpl'));
echo $this->page->build('page.tpl');
}
function about()
{
$this->page->setTitle(t('%s - About', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('About'), 'about', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('about.tpl'));
echo $this->page->build('page.tpl');
}
function chatpop()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
echo $this->page->build('chatpop.tpl');
}
}
function post()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Post View', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('post.tpl'));
echo $this->page->build('page.tpl');
}
}
/**
* Show login interface
*/
function login()
{
$this->page->setTitle(t('%s - Login to Movim', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main', true);
$this->page->menuAddLink(t('About'), 'about');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('login.tpl'));
echo $this->page->build('page.tpl');
}
/**
* Create the Atom feed of a user
*/
function feed()
{
$content = new TplPageBuilder();
echo $content->build('feed.tpl');
}
/**
* Explore the XMPP network
*/
function explore()
{
$user = new User();
$this->page->setTitle(t('%s - Explore', APP_TITLE));
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore', true);
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
}
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('explore.tpl'));
echo $this->page->build('page.tpl');
}
/*
* Show help page
*/
function help()
{
$user = new User();
$this->page->setTitle(t('%s - Help Page', APP_TITLE));
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help', true);
$this->page->menuAddLink(t('Logout'), 'disconnect');
}
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('help.tpl'));
echo $this->page->build('page.tpl');
}
/*
* Show admin page
*/
function admin()
{
error_reporting(0);
if(!isset($_SERVER['PHP_AUTH_USER'])) {
$this->authenticate();
} else {
$conf = Conf::getServerConf();
if($_SERVER['PHP_AUTH_USER'] == (string)$conf['user'] && sha1($_SERVER['PHP_AUTH_PW']) == (string)$conf['pass']){
$this->page->setTitle(t('%s - Administration Panel', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Administration'), 'admin', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('admin.tpl'));
echo $this->page->build('page.tpl');
} else {
$this->authenticate();
}
}
}
function disconnect()
{
$user = new User();
$user->desauth();
$this->login();
}
}

165
system/LGPLv3

@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

1
system/RPC.php

@ -31,7 +31,6 @@ class RPC
array_shift($args);
$args = array_map('trim', $args);
//$args = array_map('cleanString', $args);
if(self::filter($funcname, $args)) {
$funcall = array(

1
system/Route.php

@ -5,6 +5,7 @@ class Route extends ControllerBase {
public function __construct() {
$this->_routes = array(
'account' => false,
'main' => false,
'admin' => false,
'explore' => false,

2
system/Tpl/TplPageBuilder.php

@ -162,7 +162,7 @@ class TplPageBuilder
function addScript($script)
{
$this->scripts[] = BASE_URI . 'system/js/' . $script;
$this->scripts[] = BASE_URI . 'app/assets/js/' . $script;
}
/**

70
system/Utils.php

@ -29,51 +29,6 @@ function sprintln($string)
return call_user_func_array('sprintf', $args) . PHP_EOL;
}
/*
* Return the current microtime
*/
function getTime()
{
$a = explode (' ',microtime());
return(double) $a[0] + $a[1];
}
/**
* Replaces anchor tags with text
* - Will search string and replace all anchor tags with text (case insensitive)
*
* How it works:
* - Searches string for an anchor tag, checks to make sure it matches the criteria
* Anchor search criteria:
* - 1 - <a (must have the start of the anchor tag )
* - 2 - Can have any number of spaces or other attributes before and after the href attribute
* - 3 - Must close the anchor tag
*
* - Once the check has passed it will then replace the anchor tag with the string replacement
* - The string replacement can be customized
*
* Know issue:
* - This will not work for anchors that do not use a ' or " to contain the attributes.
* (i.e.- <a href=http: //php.net>PHP.net</a> will not be replaced)
*/
function replaceAnchorsWithText($data) {
/**
* Had to modify $regex so it could post to the site... so I broke it into 6 parts.
*/
$regex = '/(<a\s*'; // Start of anchor tag
$regex .= '(.*?)\s*'; // Any attributes or spaces that may or may not exist
$regex .= 'href=[\'"]+?\s*(?P<link>\S+)\s*[\'"]+?'; // Grab the link
$regex .= '\s*(.*?)\s*>\s*'; // Any attributes or spaces that may or may not exist before closing tag
$regex .= '(?P<name>\S+)'; // Grab the name
$regex .= '\s*<\/a>)/i'; // Any number of spaces between the closing anchor tag (case insensitive)
if (is_array($data)) {
// This is what will replace the link (modify to you liking)
$data = "{$data['name']} {$data['link']} ";
}
return preg_replace_callback($regex, 'replaceAnchorsWithText', $data);
}
/**
* Prepare the string (add the a to the links and show the smileys)
*
@ -215,7 +170,7 @@ function prepareDate($time, $hours = true) {
*
* @return string
*/
function generateHash(){
/*function generateHash(){
$result = "";
$charPool = '0123456789abcdefghijklmnopqrstuvwxyz';
@ -223,7 +178,7 @@ function generateHash(){
$result .= $charPool[mt_rand(0,strlen($charPool)-1)];
return sha1($result);
}
}*/
/**
* Return the list of gender
@ -650,24 +605,6 @@ function echapJid($jid)
return str_replace(' ', '\40', $jid);
}
/**
* Check the current Jid
*
* @param string $jid
* @return bool
*/
function checkJid($jid)
{
return filter_var($jid, FILTER_VALIDATE_EMAIL);
}
/**
* Remove the tabulations, carriage return and multiple whitespaces
*/
function cleanString($s) {
return preg_replace('/(\s\s+|\t|\n)/', ' ', $s);
}
/**
* Return a URIfied string
* @param string
@ -701,9 +638,6 @@ function movim_log($log) {
// var_dump($log);
print_r($log);
$dump = ob_get_clean();
/*$fh = fopen(BASE_PATH . 'log/movim.log', 'w');
fwrite($fh, $dump);
fclose($fh);*/
openlog('movim', LOG_NDELAY, LOG_USER);
$errlines = explode("\n",$dump);

227
system/Widget/WidgetBase.php

@ -1,227 +0,0 @@
<?php
/**
* @file Widget.php
* This file is part of MOVIM.
*
* @brief A widget interface.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM Project
*
* See COPYING for licensing information.
*/
class WidgetBase
{
protected $js = array(); /*< Contains javascripts. */
protected $css = array(); /*< Contains CSS files. */
protected $external; /*< Boolean: TRUE if not a system widget. */
protected $ajax; /*< Contains ajax client code. */
protected $xmpp; /*< Jabber instance. */
protected $user;
protected $name;
protected $events;
protected $cached;
/**
* Initialises Widget stuff.
* @param external is optional, true if the widget is external (an add-on) to Movim.
*/
function __construct($external = true)
{
// Put default widget init here.
$this->external = $external;
$this->ajax = ControllerAjax::getInstance();
$this->user = new User();
$db = modl\Modl::getInstance();
$db->setUser(new User());
// Generating ajax calls.
$refl = new ReflectionClass(get_class($this));
$meths = $refl->getMethods();
foreach($meths as $method) {
if(preg_match('#^ajax#', $method->name)) {
$pars = $method->getParameters();
$params = array();
foreach($pars as $param) {
$params[] = $param->name;
}
$this->ajax->defun(get_class($this), $method->name, $params);
}
}
$this->name = get_class($this);
$this->WidgetLoad();
}
function WidgetLoad()
{
}
/**
* Generates the widget's HTML code.
*/
function build()
{
}
/**
* Returns the path to the specified widget file.
* @param file is the file's name to make up the path for.
* @param fspath is optional, returns the OS path if true, the URL by default.
*/
protected function respath($file, $fspath = false)
{
$path = "";
if(!$this->external) {
$path = 'system/';
}
$path .= 'Widget/widgets/' . get_class($this) . '/' . $file;
if($fspath) {
$path = BASE_PATH . $path;
} else {
$path = BASE_URI . $path;
}
return $path;
}
public function getName()
{
return $this->name;
}
/**
* Generates and print an ajax call.
*/
protected function callAjax($funcname)
{
echo $this->makeCallAjax(func_get_args());
}
/**
* Calls an the ajax function of another widget.
*/
protected function callWidget($widgetname, $funcname)
{
$params = func_get_args();
echo $this->makeCallAjax(array_slice($params, 1), $widgetname);
}
/**
* Returns the javascript ajax call.
*/
protected function genCallAjax($funcname)
{
return $this->makeCallAjax(func_get_args());
}
/**
* Returns the javascript call to another widget's ajax function.
*/
protected function genCallWidget($widgetname, $funcname)
{
$params = func_get_args();
return $this->makeCallAjax(array_slice($params, 1), $widgetname);
}
protected function makeCallAjax($params, $widget=false)
{
if(!$widget) {
$widget = get_class($this);
}
$funcname = array_shift($params);
$args = implode(', ', $params);
return $widget . '_' . $funcname . "(" . $args . ");";
}
/**
* Adds a javascript file to this widget.
*/
protected function addjs($filename)
{
$this->js[] = $this->respath($filename);
}
/**
* returns the list of javascript files to be loaded for the widget.
*/
public function loadjs()
{
return $this->js;
}
/**
* Adds a javascript file to this widget.
*/
protected function addcss($filename)
{
$this->css[] = $this->respath($filename);
}
/**
* Registers an event handler.
*/
protected function registerEvent($type, $function)
{
if(!is_array($this->events)
|| !array_key_exists($type, $this->events)) {
$this->events[$type] = array($function);
} else {
$this->events[$type][] = $function;
}
}
/**
* Runs all events of a given type.
*/
public function runEvents($proto)
{
if(is_array($this->events) && array_key_exists($proto['type'], $this->events)) {
// If a new event came to the widget, we update the cache
//$this->setCacheCall();
$returns = array();
foreach($this->events[$proto['type']] as $handler) {
$returns[] = call_user_func(array($this, $handler), $proto['data']);
}
return $returns;
}
}
public function isEvents($proto)
{
if(is_array($this->events) &&
array_key_exists($proto['type'], $this->events) &&
$this->cached == true) {
return true;
}
}
/**
* returns the list of javascript files to be loaded for the widget.
*/
public function loadcss()
{
return $this->css;
}
}
?>

585
system/Widget/WidgetCommon.php

@ -1,585 +0,0 @@
<?php
/**
* @file WidgetCommon.php
* This file is part of MOVIM.
*
* @brief The widgets commons methods.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @date 08 march 2012
*
* Copyright (C)2010 MOVIM Project
*
* See COPYING for licensing information.
*/
class WidgetCommon extends WidgetBase {
protected function printPost($post, $comments = false, $public = false) {
if($post->title)
$title = '
<span>
'.$post->title.'
</span><br />';
if($this->user->getLogin() == $post->jid) {
$class = 'me ';
if($post->privacy == 1)
$access .= 'protect black';
else
$access .= 'protect orange';
$avatar = $post->getContact()->getPhoto('s');
} elseif($post->public == 2)
$avatar = $post->getContact()->getPhoto('xs');
else
$avatar = $post->getContact()->getPhoto('s');
if(!filter_var($post->from, FILTER_VALIDATE_EMAIL) && $post->node != '')
$group = '
<span class="group">
<a href="'.Route::urlize('node', array($post->from, $post->node)).'">'.$post->node.' ('.$post->from.')</a>
</span>';
elseif($post->from != $post->aid)
$recycle .= '
<span class="recycle">
<a href="'.Route::urlize('friend', $post->from).'">'.$post->from.'</a>
</span>';
if($post->getPlace() != false)
$place .= '
<span class="place">
<a
target="_blank"
href="http://www.openstreetmap.org/?lat='.$post->lat.'&lon='.$post->lon.'&zoom=10"
>'.t('Place').'</a>
</span>';
if($post->jid != '')
$c = '
<span>
<a href="'.Route::urlize('friend', $post->jid).'">'.$post->getContact()->getTrueName().'</a>
</span>';
elseif($post->aid != '')
$c = '
<span>
<a href="'.Route::urlize('friend', $post->aid).'">'.$post->aid.'</a>
</span>';
if($post->links)
$enc = $this->printEnclosures($post->links);
if($enc)
$enc = '
<div class="enclosure">'.
$enc.
'</div>';
$content = prepareString(html_entity_decode($post->content));
if($post->node == 'urn:xmpp:microblog:0')
$comments = $this->printComments($post, $comments, $public);
else
$comments = '';
if($this->user->getLogin() == $post->jid)
$toolbox = $this->getToolbox($post);
$html = '
<div class="post '.$class.'" id="'.$post->nodeid.'">
<a href="'.Route::urlize('friend', $post->jid).'">
<img class="avatar" src="'.$avatar.'">
</a>
<div id="'.$post->nodeid.'bubble" class="postbubble '.$access.'">
<div class="header">
<span class="title">'.$title.'</span>
'.$c.'
<span class="date">
'.prepareDate(strtotime($post->published)).'
</span>
</div>
<div class="content">
'.$content.'
</div>
'.$toolbox.'
'.$enc.'
'.$comments.'
'.$place.'
'.$recycle.'
'.$group.'
</div>
<div class="clear"></div>
</div>
';
return $html;
}
private function printEnclosures($links) {
$enc = '';
$links = unserialize($links);
foreach($links as $l) {
if($l['rel'] == 'enclosure') {
if(isset($l['thumb']))
$enc .= '
<a href="'.$l['href'].'" class="imglink" target="_blank">
<img src="'.$l['thumb']['href'].'"/>
</a>
';
else
$enc .= '
<a href="'.$l['href'].'" class="imglink" target="_blank">
<img src="'.$l['href'].'"/>
</a>';
} elseif($l['rel'] == 'alternate' && isset($l['title'])) {
$enc .= '
<a href="'.$l['href'].'" class="imglink" target="_blank">
'.$l['title'].'
</a>';
}
}
return $enc;
}
private function getToolbox($post) {
$html = '
<div class="tools">
'.t("Share with").' :
<a
title="'.t("your post will appear in your Movim public feed").'"
onclick="'.
$this->genCallAjax(
'ajaxPrivacyPost',
"'".$post->nodeid."'",
"'black'").
'" >
'.t("Everyone").'</a>,
<a
onclick="'.
$this->genCallAjax(
'ajaxPrivacyPost',
"'".$post->nodeid."'",
"'orange'").
'" >
'.t("Your contacts").'</a><br />
<a
style="padding-right: 1em;";
onclick="
this.parentNode.querySelector(\'#deleteyes\').style.display = \'inline\';
this.parentNode.querySelector(\'#deleteno\').style.display = \'inline\';
"
title="'.t("Delete this post").'">
'.t("Delete this post").'
</a>
<a
style="padding-right: 1em; display: none;";
id="deleteyes"
onclick="'.
$this->genCallAjax(
'ajaxDeletePost',
"'".$this->user->getLogin()."'",
"'".$post->node."'",
"'".$post->nodeid."'").'" >
'.t("Yes").'
</a>
<a
style="display: none;";
id="deleteno"
onclick="
this.parentNode.querySelector(\'#deleteyes\').style.display = \'none\';
this.style.display = \'none\';
"
onclick="">
'.t("No").'
</a>
</div>';
return $html;
}
protected function printComments($post, $comments, $public = false) {
$tmp .= '
<div class="comments" id="'.$post->nodeid.'comments">';
$commentshtml = $this->prepareComments($comments);
if($commentshtml != false)
$tmp .= $commentshtml;
if($public == false) {
$tmp .= '
<div class="comment">
<a
class="getcomments icon bubble"
style="margin-left: 0px;"
onclick="'.$this->genCallAjax('ajaxGetComments', "'".$post->commentplace."'", "'".$post->nodeid."'").'; this.innerHTML = \''.t('Loading comments ...').'\'">'.
t('Get the comments').'
</a>
</div></div>';
$tmp .= '<div class="comments">
<div
class="comment"
style="border-bottom: none;"
onclick="this.parentNode.querySelector(\'#commentsubmit\').style.display = \'table\'; this.style.display =\'none\'">
<a class="getcomments icon bubbleadd">'.t('Add a comment').'</a>
</div>
<table id="commentsubmit">
<tr>
<td>
<textarea id="'.$post->nodeid.'commentcontent" onkeyup="movim_textarea_autoheight(this);"></textarea>
</td>
</tr>
<tr class="commentsubmitrow">
<td style="width: 100%;"></td>
<td>
<a
onclick="
if(document.getElementById(\''.$post->nodeid.'commentcontent\').value != \'\') {
'.$this->genCallAjax(
'ajaxPublishComment',
"'".$post->commentplace."'",
"'".$post->nodeid."'",
"encodeURIComponent(document.getElementById('".$post->nodeid."commentcontent').value)").
'document.getElementById(\''.$post->nodeid.'commentcontent\').value = \'\';
}"
class="button tiny icon submit"
style="padding-left: 28px;"
>'.
t("Submit").'
</a>
</td>
</tr>
</table>';
}
$tmp .= '</div>';
return $tmp;
}
/*
* @desc Prepare a group of messages
* @param array of messages
* @return generated HTML
*/
protected function preparePosts($posts, $public = false) {
if($posts == false || empty($posts)) {
$html = '<div style="padding: 1.5em; text-align: center;">Ain\'t Nobody Here But Us Chickens...</div>';
} else {
$html = '';
$pd = new \modl\PostnDAO();
$comments = $pd->getComments($posts);
foreach($posts as $post) {
// We split the interesting comments for each messages
$i = 0;
$messagecomment = array();
foreach($comments as $comment) {
if('urn:xmpp:microblog:0:comments/'.$post->nodeid == $comments[$i]->node) {
array_push($messagecomment, $comment);
unset($comment);
}
$i++;
}
$html .= $this->printPost($post, $messagecomment, $public);
}
}
return $html;
}
protected function testIsSet($element)
{
if(isset($element) && $element != '')
return true;
else
return false;
}
protected function prepareComments($comments) {
$tmp = false;
$size = sizeof($comments);
$i = 0;
while($i < $size-1) {
if($comments[$i]->nodeid == $comments[$i+1]->nodeid)
unset($comments[$i]);
$i++;
}
$size = sizeof($comments);
$comcounter = 0;
if($size > 3) {
$tmp = '<div
class="comment"
onclick="
com = this.parentNode.querySelectorAll(\'.comment\');
for(i = 0; i < com.length; i++) { com.item(i).style.display = \'block\';};
this.style.display = \'none\';">
<a class="getcomments icon bubbleold">'.t('Show the older comments').'</a>
</div>';
$comcounter = $size - 3;
}
if($comments) {
foreach($comments as $comment) {
$photo = $comment->getContact()->getPhoto('xs');
$name = $comment->getContact()->getTrueName();
$tmp .= '
<div class="comment" ';
if($comcounter > 0) {
$tmp .= 'style="display:none;"';
$comcounter--;
}
$tmp .='>
<img class="avatar tiny" src="'.$photo.'">
<span><a href="'.Route::urlize('friend', $comment->jid).'">'.$name.'</a></span>
<span class="date">'.prepareDate(strtotime($comment->published)).'</span><br />
<div class="content tiny">'.prepareString($comment->content).'</div>
</div>';
}
}
return $tmp;
}
protected function prepareSubmitForm($server = '', $node = '') {
$html = '
<script type="text/javascript">
function showPosition(poss) {
'.$this->genCallAjax('ajaxShowPosition', "poss").'
}
</script>
<div class="popup post" id="postpreview">
<h2>'.t('Preview').'</h2>
<div class="content" id="postpreviewcontent">
</div>
<a
class="button tiny black"
onclick="
movim_toggle_display(\'#postpreview\');"
>'.t('Close').'</a>
</div>
<table id="feedsubmitform">
<tbody>
<form name="postpublish" id="postpublish">
<tr>
<td>
<textarea
name="content"
id="postpublishcontent"
onkeyup="movim_textarea_autoheight(this);"
placeholder="'.t("What's new ?").'" ></textarea>
</td>
</tr>
<tr id="feedsubmitrow">
<td>
<input type="hidden" id="latlonpos" name="latlonpos"/>
<a
title="'.t("Submit").'"
href="#"
id="feedmessagesubmit"
onclick="'.$this->genCallAjax('ajaxPublishItem', "'".$server."'", "'".$node."'","movim_parse_form('postpublish')").';
document.querySelector(\'#postpublish\').reset();
movim_textarea_autoheight(document.querySelector(\'#postpublishcontent\'));"
class="button tiny icon yes">'.
t("Submit").'
</a>
<a
class="button tiny icon alone merged left preview"
style="float: left;"
title="'.t('Preview').'"
onclick="
movim_toggle_display(\'#postpreview\');
'.$this->genCallAjax('ajaxPostPreview', "document.querySelector('#postpublishcontent').value").'"
></a>
<a
title="Plus"
href="#"
id="postpublishsize"
onclick="frameHeight(this, document.querySelector(\'#postpublishcontent\'));"
style="float: left;"
class="button tiny icon alone add merged"></a><a
class="button tiny icon alone help merged"
style="float: left;"
href="http://daringfireball.net/projects/markdown/basics"
target="_blank"
></a><a title="'.t("Geolocalisation").'"
onclick="setPosition(document.querySelector(\'#latlonpos\'));"
style="float: left;"
class="button tiny icon alone geo merged right"></a>
<span id="postpublishlocation"></span>
</td>
</tr>
</form>
</tbody>
</table>';
return $html;
}
function ajaxShowPosition($pos)
{
list($lat,$lon) = explode(',', $pos);
$pos = json_decode(
file_get_contents('http://nominatim.openstreetmap.org/reverse?format=json&lat='.$lat.'&lon='.$lon.'&zoom=27&addressdetails=1')
);
RPC::call('movim_fill', 'postpublishlocation' , (string)$pos->display_name);
RPC::commit();
}
function ajaxPostPreview($content)
{
if($content != '') {
$content = Michelf\Markdown::defaultTransform($content);
RPC::call('movim_fill', 'postpreviewcontent' , $content);
} else
RPC::call('movim_fill', 'postpreviewcontent' , t('No content'));
RPC::commit();
}
function ajaxPublishItem($server, $node, $form)
{
$content = $form['content'];
list($lat,$lon) = explode(',', $form['latlonpos']);
$pos = json_decode(
file_get_contents('http://nominatim.openstreetmap.org/reverse?format=json&lat='.$lat.'&lon='.$lon.'&zoom=27&addressdetails=1')
);
$geo = array(
'latitude' => (string)$pos->lat,
'longitude' => (string)$pos->lon,
'altitude' => (string)$pos->alt,
'country' => (string)$pos->address->country,
'countrycode' => (string)$pos->address->country_code,
'region' => (string)$pos->address->county,
'postalcode' => (string)$pos->address->postcode,
'locality' => (string)$pos->address->city,
'street' => (string)$pos->address->path,
'building' => (string)$pos->address->building,
'text' => (string)$pos->display_name,
'uri' => ''//'http://www.openstreetmap.org/'.urlencode('?lat='.(string)$pos->lat.'&lon='.(string)$pos->lon.'&zoom=10')
);
if($content != '') {
$content = Michelf\Markdown::defaultTransform($content);
$p = new moxl\PubsubPostPublish();
$p->setFrom($this->user->getLogin())
->setTo($server)
->setNode($node)
->setLocation($geo)
->setContentHtml(rawurldecode($content))
->enableComments()
->request();
}
}
function onComment($parent) {
$p = new \modl\ContactPostn();
$p->nodeid = $parent;
$pd = new \modl\PostnDAO();
$comments = $pd->getComments($p);
$html = $this->prepareComments($comments);
RPC::call('movim_fill', $parent.'comments', $html);
}
function onNoComment($parent) {
$html = '
<div class="comment">
<a
class="getcomments icon bubble"
style="margin-left: 0px;">'.
t('No comments').
'</a>
</div>';
RPC::call('movim_fill', $parent.'comments', $html);
}
function onNoCommentStream($parent) {
$html = '
<div class="comment">
<a
class="getcomments icon bubble"
style="margin-left: 0px;">'.
t('No comments stream').
'</a>
</div>';
RPC::call('movim_fill', $parent.'comments', $html);
}
function ajaxGetComments($jid, $id) {
$c = new moxl\MicroblogCommentsGet();
$c->setTo($jid)
->setId($id)
->request();
}
function ajaxPublishComment($to, $id, $content) {
if($content != '') {
$p = new moxl\MicroblogCommentPublish();
$p->setTo($to)
->setFrom($this->user->getLogin())
->setParentId($id)
->setContent(htmlspecialchars(rawurldecode($content)))
->request();
}
}
function ajaxDeletePost($to, $node, $id) {
$p = new moxl\PubsubPostDelete();
$p->setTo($to)
->setNode($node)
->setId($id)
->request();
}
function ajaxPrivacyPost($nodeid, $privacy) {
$pd = new \modl\PrivacyDAO();
$p = $pd->get($nodeid);
if($privacy == 'orange') {
\modl\Privacy::set($nodeid, 0);
} elseif($privacy == 'black') {
\modl\Privacy::set($nodeid, 1);
}
RPC::call('movim_change_class', $nodeid.'bubble' , 'postbubble me protect '.$privacy);
RPC::commit();
}
/*function onPostDelete($id) {
RPC::call('movim_delete', $id);
}
function onPostDeleteError($params) {
$html .=
'<div class="message error">'.t('An error occured : ').$params[1].'</div>';
RPC::call('movim_fill', $params[0] , $html);
}*/
}

228
system/Widget/WidgetWrapper.php

@ -1,228 +0,0 @@
<?php
/**
* @file WidgetWrapper.php
* This file is part of PROJECT.
*
* @brief Description
*
* @author Guillaume Pasquet <gpasquet@lewisday.co.uk>
*
* @version 1.0
* @date 20 January 2011
*
* Copyright (C)2011 Lewis Day Transport Plc.
*
* All rights reserved.
*/
/**
* A container that abstracts the communication between
* widgets and the core of Movim.
*/
class WidgetWrapper
{
private $register_widgets;
private $all_widgets = array();
private $loaded_widgets = array();
private $loaded_widgets_old;
private static $instance;
private $css = array(); // All the css loaded by the widgets so far.
private $js = array(); // All the js loaded by the widgets so far.
/**
* Constructor. The parameter instructs the wrapper about whether
* it should save $_SESSION or not.
* @param $register set to false not to save the widgets in SESSION.
*/
private function __construct($register)
{
$this->register_widgets = $register;
$sess = Session::start(APP_NAME);
$widgets = $sess->get('loaded_widgets');
if(is_array($widgets)) {
$this->loaded_widgets_old = $widgets;
}
$this->all_widgets = array();
$widgets_dir = scandir(LIB_PATH ."Widget/widgets/");
foreach($widgets_dir as $widget_dir) {
if(is_dir(LIB_PATH ."Widget/widgets/".$widget_dir) &&
$widget_dir != '..' &&
$widget_dir != '.')
array_push($this->all_widgets, $widget_dir);
}
}
static function getInstance($register = true)
{
if(!is_object(self::$instance)) {
self::$instance = new WidgetWrapper($register);
}
return self::$instance;
}
static function destroyInstance()
{
if(isset(self::$instance)) {
self::$instance->destroy();
self::$instance = null;
}
}
/**
* Saves the list of loaded widgets if necessary.
*/
function __destruct()
{
$this->destroy();
}
protected function destroy()
{
if($this->register_widgets) {
$sess = Session::start(APP_NAME);
$sess->set('loaded_widgets', $this->loaded_widgets);
$this->register_widgets = false;
}
}
/**
* Retrieves the list of loaded widgets.
*/
function get_loaded_widgets()
{
if(count($this->loaded_widgets) > 0) {
return $this->loaded_widgets;
} else {
return $this->loaded_widgets_old;
}
}
function get_all_widgets()
{
return $this->all_widgets;
}
/*function get_cached_widgets()
{
return $this->cached_widgets;
}*/
/**
* Loads a widget and returns it.
*/
public function load_widget($widget_name)
{
// Attempting to load the user's widgets in priority
$widget_path = "";
$extern = null;
if(file_exists(BASE_PATH . "Widget/widgets/$widget_name/$widget_name.php")) {
$widget_path = BASE_PATH . "Widget/widgets/$widget_name/$widget_name.php";
// Custom widgets have their own translations.
load_extra_lang(BASE_PATH . 'Widget/widgets/$widget_name/i18n');
$extern = true;
}
else if(file_exists(LIB_PATH . "Widget/widgets/$widget_name/$widget_name.php")) {
$widget_path = LIB_PATH . "Widget/widgets/$widget_name/$widget_name.php";
$extern = false;
}
else {
throw new MovimException(
t("Requested widget '%s' doesn't exist.", $widget_name));
}
require_once($widget_path);
$widget = new $widget_name($extern);
return $widget;
}
/**
* Loads a widget and runs a particular function on it.
*
* @param $widget_name is the name of the widget.
* @param $method is the function to be run.
* @param $params is an array containing the parameters to
* be passed along to the method.
* @return what the widget's method returns.
*/
function run_widget($widget_name, $method, array $params = NULL)
{
if($this->register_widgets &&
!in_array($widget_name, $this->loaded_widgets)) {
$this->loaded_widgets[] = $widget_name;
}
$widget = $this->load_widget($widget_name);
if(!is_array($params)) {
$params = array();
}
$result = call_user_func_array(array($widget, $method), $params);
// Collecting stuff generated by the widgets.
$this->css = array_merge($this->css, $widget->loadcss());
$this->js = array_merge($this->js, $widget->loadjs());
return $result;
}
/**
* Calls a particular function with the given parameters on
* all loaded widgets.
*
* @param $method is the method to be called on all widgets.
* @param $params is an array of parameters passed to the method.
*/
function iterate($method, array $params = NULL)
{
$buff = array();
$widgets = $this->get_loaded_widgets();
foreach($widgets as $widget) {
$buff[] = $this->run_widget($widget, $method, $params);
}
return $buff;
}
function iterateAll($method, array $params = NULL) {
$widgets = $this->get_all_widgets();
$isevent = array();
foreach($widgets as $widget) {
if($this->run_widget($widget, $method, $params))
$isevent[$widget] = true;
}
if(!empty($isevent))
$this->cached_widgets = $isevent;
return $isevent;
}
/**
* Returns the list of loaded CSS.
*/
function loadcss()
{
if(!is_array($this->css)) // Just being prudent
return array();
else
return $this->css;
}
/**
* Returns the list of loaded javascripts.
*/
function loadjs()
{
if(!is_array($this->js)) // Avoids annoying errors.
return array();
else
return $this->js;
}
}
?>

4
system/Widget/widgets/.dir-locals.el

@ -1,4 +0,0 @@
((nil . ((indent-tabs-mode . nil)
(tab-width . 4)
(fill-column . 80)))
(c-mode . ((c-file-style . "stroustrup"))))

123
system/Widget/widgets/About/About.php

@ -1,123 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Vcard.php
* This file is part of MOVIM.
*
* @brief A widget which display some help
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 3 may 2012
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class About extends WidgetBase
{
function WidgetLoad() {
}
function build()
{
?>
<div class="tabelem padded" title="<?php echo t('About'); ?>" id="about">
<p>Movim is an XMPP-based communication platform. All the project, except the following software and resources, is under
<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License v3</a>.
</p>
<h2><?php echo t('Thanks'); ?></h2>
<dl>
<dt>Developers</dt><dd><a href="http://edhelas.mov.im/">Jaussoin Timothée aka edhelas</a></dd>
<dt></dt><dd><a href="https://launchpad.net/~nodpounod">Ho Christine aka nodpounod</a></dd>
<dt></dt><dd><a href="https://etenil.net/">Pasquet Guillaume aka Etenil</a></dd>
<dt>Translators</dt><dd>Arabic - <a href="https://launchpad.net/~gharbeia">Ahmad Gharbeia أحمد غربية</a></dd>
<dt></dt><dd>Brazilian - <a href="https://launchpad.net/~dnieper650">millemiglia</a></dd>
<dt></dt><dd>Chinese - <a href="https://launchpad.net/~dudumomo">dudumomo</a></dd>
<dt></dt><dd>Danish - <a href="https://launchpad.net/~ole-carlsen-web">Ole Carlsen</a></dd>
<dt></dt><dd>Dutch - <a href="https://launchpad.net/~laurens-debackere">Laurens Debackere</a></dd>
<dt></dt><dd>English UK - <a href="https://launchpad.net/~kevinbeynon">Kevin Beynon</a>, <a href="https://launchpad.net/~influence-pc">Vincent</a></dd>
<dt></dt><dd>Esperanto - <a href="https://launchpad.net/~eliovir">Eliovir</a></dd>
<dt></dt><dd>Finish - <a href="https://launchpad.net/~e1484180">Timo</a></dd>
<dt></dt><dd>French -
<a href="https://launchpad.net/~hyogapag">Hyogapag</a>,
<a href="https://launchpad.net/~e1484180">Hélion du Mas des Bourboux</a>,
<a href="https://launchpad.net/~jonathanmm">JonathanMM</a>,
<a href="https://launchpad.net/~grossard-o">Ludovic Grossard</a>,
<a href="https://launchpad.net/~schoewilliam">Schoewilliam</a>,
<a href="https://launchpad.net/~influence-pc">Vincent</a>,
<a href="https://launchpad.net/~edhelas">edhelas</a>,
<a href="https://launchpad.net/~nodpounod">pou</a>
</dd>
<dt></dt><dd>German -
<a href="https://launchpad.net/~q-d">Daniel Winzen</a>,
<a href="https://launchpad.net/~jonas-ehrhard">Jonas Ehrhard</a>,
<a href="https://launchpad.net/~jonatan-zeidler-gmx">Jonatan Zeidler</a>,
<a href="https://launchpad.net/~kili4n">Kilian Holzinger</a>,
</dd>
<dt></dt><dd>Greek -
<a href="https://launchpad.net/~d-rotarou">Rotaru Dorin</a>,
<a href="https://launchpad.net/~yang-hellug">aitolos</a>
</dd>
<dt></dt><dd>Hebrew - <a href="https://launchpad.net/~genghiskhan">GenghisKhan</a></dd>
<dt></dt><dd>Hungarian - <a href="https://launchpad.net/~batisteo">Baptiste Darthenay</a></dd>
<dt></dt><dd>Italian -
<a href="https://launchpad.net/~andrea-caratti-phys">Andrea Caratti</a>,
<a href="https://launchpad.net/~giacomo-alzetta">Giacomo Alzetta</a>,
<a href="https://launchpad.net/~emailadhoc">kimj</a>
</dd>
<dt></dt><dd>Japanese - <a href="https://launchpad.net/~fdelbrayelle">Franky</a></dd>
<dt></dt><dd>Occitan (post 1500) -
<a href="https://launchpad.net/~cvalmary">Cédric VALMARY (Tot en òc)</a>,
<a href="https://launchpad.net/~caillonm">Maime</a>
</dd>
<dt></dt><dd>Portuguese -
<a href="https://launchpad.net/~jonathanmm">JonathanMM</a>,
<a href="https://launchpad.net/~dnieper650">millemiglia</a>
</dd>
<dt></dt><dd>Russian -
<a href="https://launchpad.net/~ak099">Aleksey Kabanov</a>,
<a href="https://launchpad.net/~vsharmanov">Vyacheslav Sharmanov</a>,
<a href="https://launchpad.net/~hailaga">hailaga</a>,
<a href="https://launchpad.net/~salnsg">Сергей Сальников</a>,
<a href="https://launchpad.net/~mr-filinkov">DeforaD</a>
</dd>
<dt></dt><dd>Spanish -
<a href="https://launchpad.net/~alejandrosg">Alejandro Serrano González</a>,
<a href="https://launchpad.net/~edu5800">Eduardo Alberto Calvo</a>,
<a href="https://launchpad.net/~estebanmainieri">Esteban Mainieri</a>,
<a href="https://launchpad.net/~victormezio">Oizem Mushroom</a>,
<a href="https://launchpad.net/~kaiser-715-deactivatedaccount">Ricardo Sánchez Baamonde</a>,
<a href="https://launchpad.net/~invrom">Ubuntu</a>,
<a href="https://launchpad.net/~orochiforja">orochiforja</a>
</dd>
<dt></dt><dd>Turkish -
<a href="https://launchpad.net/~basaran-caner">Caner Başaran</a>,
<a href="https://launchpad.net/~emreakca">emre akça</a>
</dd>
</dl>
<h2><?php echo t('Software'); ?></h2>
<dl>
<dt>Database Library</dt><dd>Modl - Movim DB Layer <a href="https://launchpad.net/modl">launchpad.net/modl</a> under AGPLv3</dd>
<dt>XMPP Library</dt><dd>Moxl - Movim XMPP Library <a href="https://launchpad.net/moxl">launchpad.net/moxl</a> under AGPLv3</dd>
</dl>
<br />
<dl>
<dt>Map Library</dt><dd>Leaflet <a href="http://leafletjs.com/">leafletjs.com</a> under BSD</dd>
<dt>Markdown</dt><dd>Michel Fortin <a href="http://michelf.ca/projects/php-markdown/">michelf.ca</a> ©Michel Fortin</dd>
<dt>HTML Fixer</dt><dd> Giulio Pons <a href="http://www.barattalo.it">barattalo.it</a></dd>
</dl>
<h2><?php echo t('Ressources'); ?></h2>
<dl>
<dt>Icons</dt><dd>Famfamfam <a href="http://www.famfamfam.com/">www.famfamfam.com</a> under CC BY 3.0</dd>
<dt></dt><dd>Icomoon <a href="http://keyamoon.com/">by Keyamoon</a> under CC BY 3.0</dd>
</dl>
</div>
<?php
}
}

466
system/Widget/widgets/Account/Account.php

@ -1,466 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Account.php
* This file is part of MOVIM.
*
* @brief The account creation widget.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 25 November 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Account extends WidgetBase {
function WidgetLoad()
{
$this->addcss('account.css');
$this->addjs('account.js');
}
function ajaxDiscoverServer($ndd) {
if($ndd['ndd'] == '') {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=datamissing");
RPC::commit();
exit;
}
try {
$dns = dns_get_record('_xmpp-client._tcp.'.$ndd['ndd']);
if(isset($dns[0]['target']) && $dns[0]['target'] != null)
$domain = $dns[0]['target'];
$f = fsockopen($domain, 5222, $errno, $errstr, 10);
if(!$f) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppconnect");
RPC::commit();
exit;
}
$stream = simplexml_load_string('<?xml version="1.0"?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0"><iq type="get" id="reg1"><query xmlns="jabber:iq:register"/></iq></stream:stream>');
$stream->addAttribute('to', $ndd['ndd']);
fwrite($f, $stream->asXML());
unset($stream);
$response = stream_get_contents($f);
if(!$response) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppcomm");
RPC::commit();
exit;
}
fclose($f); unset($f);
$response = simplexml_load_string($response);
$id = (string)$response->attributes()->id;
$elements = (array)$response->iq->query;
if(!empty($elements)) {
$html .= '
<form name="data">
<fieldset>
<legend>'.t('Step 2 - Fill in your informations').'</legend><br /><br /><br />';
if($response->iq->query->instructions && $response->iq->query->x) {
$instr = '
<div class="element simple large">
<label>'.(string)$response->iq->query->instructions.'</label>';
if($response->iq->query->x->url)
$instr .= '
<a href="'.(string)$response->iq->query->x->url.'" target="_blank">'.
(string)$response->iq->query->x->url.'
</a>';
$instr .= '
</div>';
}
$form = new XMPPtoForm();
if(!empty($response->iq->query->x)){
$formh .= $form->getHTML($response->iq->query->x->asXML());
}
else{/*no <x> element in the XML*/
$formh .= $form->getHTML($response->iq->query->asXML());
}
if($formh == '')
$html .= $instr;
else
$html .= $formh;
$html .= '
<input
type="hidden"
value="'.$domain.'"
name="ndd"
id="ndd"
/>
';
$html .= '
<input
type="hidden"
value="'.$ndd['ndd'].'"
name="to"
id="to"
/>
';
$html .= '
<input
type="hidden"
value="'.$id.'"
name="id"
id="id"
/>
';
if(isset($elements['data'])) {
$html .= '<img src="data:image/jpg;base64,'.$elements['data'].'"/>';
}
$submit = $this->genCallAjax('ajaxSubmitData', "movim_parse_form('data')");
$html .= '
<a
class="button icon yes"
style="float: right;"
onclick="'.$submit.'"
>
'.t('Validate').'
</a>';
$html .= '
</fieldset>
</form>';
RPC::call('movim_fill', 'fillform', $html);
RPC::commit();
}
else {
$html = '
<div class="message warning">
'.t('No account creation form founded on the server').'
</div>';
RPC::call('movim_fill', 'fillform', $html);
RPC::commit();
}
} catch(Exception $e) {
header(sprintf('HTTP/1.1 %d %s', $e->getCode(), $e->getMessage()));
header('Content-Type: text/plain; charset=utf-8');
echo $e->getMessage(),"\n";
}
}
function ajaxSubmitData($datas) {
define(XMPP_HOST, $datas['to']);
define(XMPP_CONN, $datas['ndd']);
define(XMPP_PORT, 5222);
try {
// We try to connect to the XMPP Server
$f = fsockopen(XMPP_CONN, XMPP_PORT, $errno, $errstr, 10);
if(!$f) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppconnect");
RPC::commit();
exit;
}
// We create the XML Stanza
$stream = simplexml_load_string('<?xml version="1.0"?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0"><iq id="register" type="set"><query xmlns="jabber:iq:register"></query></iq></stream:stream>');
$stream->addAttribute('to', XMPP_HOST);
$xmpp = new FormtoXMPP();
$stream = $xmpp->getXMPP($stream->asXML(), $datas);
fwrite($f, $stream->asXML());
unset($stream);
$response = stream_get_contents($f);
if(!$response) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppcomm");
RPC::commit();
exit;
}
fclose($f); unset($f);
$response = simplexml_load_string($response);
if(!$response) throw new Exception('The XMPP server sent an invalid response', 500);
if($stream_error = $response->xpath('/stream:stream/stream:error')) {
list($stream_error) = $stream_error;
list($cond) = $stream_error->children();
throw new Exception($stream_error->text ? $stream_error->text : $cond->getName(), 500);
}
$iq = $response->iq;
if($iq->error) {
list($cond) = $iq->error->children();
if($cond->getName() == 'conflict') {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=userconflict");
RPC::commit();
exit;
}
throw new Exception($iq->error->text ? $iq->error->text : $cond->getName(), 400);
}
if($iq = $response->iq and $iq->attributes()->type == 'result') {
RPC::call('movim_reload', BASE_URI."index.php?q=login&err=acccreated");
RPC::commit();
exit;
} else {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=unknown");
RPC::commit();
exit;
}
} catch(Exception $e) {
header(sprintf('HTTP/1.1 %d %s', $e->getCode(), $e->getMessage()));
header('Content-Type: text/plain; charset=utf-8');
echo $e->getMessage(),"\n";
}
}
function printServerList() {
$file = dirname(__FILE__).DIRECTORY_SEPARATOR.'server-vcards.xml';
$html = '';
if(file_exists($file)) {
$vcards = simplexml_load_file($file);
$html .= '
<div class="clear"></div>
<table id="list">
<thead>
<tr>
<td>
'.t('Name').'
</td>
<td>
'.t('Description').'
</td>
<td>
'.t('URL').'
</td>
<td>
'.t('Software').'
</td>
<td>
</td>
</tr>
</thead>
<tbody>';
$markers = array();
foreach($vcards as $vcard) {
$name = (string)$vcard->fn->text;
$html .='
<tr onclick="selectServer(\''.$name.'\');">
<td>
<a href="#nddlink">'.$name.'</a>
</td>
<td>
'.(string)$vcard->note->text.'
</td>
<td>
<a target="_blank" href="'.(string)$vcard->url->uri.'">
'.(string)$vcard->url->uri.'
</a>
</td>
<td>
'.(string)$vcard->name.'
</td>
<td>
<img
title="'.(string)$vcard->adr->country.'"
alt="'.(string)$vcard->adr->country.'"
src="'.BASE_URI.'themes/movim/img/flags/'.strtolower((string)$vcard->adr->country).'.png"/>
</td>
</tr>
';
$coord = explode("geo:", $vcard->geo->uri);
if(isset($coord[1])){
$split = explode(",", $coord[1]);
$newkey = round(floatval($split[0]),1).",".round(floatval($split[1]),1);
if(!isset($markers[$newkey])){
$markers[$newkey] = array($name);
}
else{
array_push($markers[$newkey], $name);
}
}
}
$html .= '
</tbody>
</table>';
$javascript = '<script type="text/javascript">
var map = L.map("map").setView([40,0], 2);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "Map data &copy; <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors, <a href=\"http://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA</a>, Mapnik ©",
maxZoom: 18
}).addTo(map);';
$id = 0;
foreach($markers as $coord => $arrayOfNames){
$javascript .= "
var marker".$id." = L.marker([".$coord."]).addTo(map);
marker".$id.".bindPopup('";
foreach($arrayOfNames as $name){
$action = 'selectServer("'.$name.'");';
$javascript .= "<span onclick=\'".$action."\' ><a href=\'#nddlink\'>".$name."</a></span><br />";
}
$javascript .= "');
";
$id++;
}
$javascript .= '</script>';
}
return $javascript.$html;
}
function build()
{
switch ($_GET['err']) {
case 'datamissing':
$warning = '
<div class="message error">
'.t('Some data are missing !').'
</div> ';
break;
case 'jiderror':
$warning = '
<div class="message error">
'.t('Wrong ID').'
</div> ';
break;
case 'passworddiff':
$warning = '
<div class="message error">
'.t('You entered different passwords').'
</div> ';
break;
case 'nameerr':
$warning = '
<div class="message error">
'.t('Invalid name').'
</div> ';
break;
case 'userconflict':
$warning = '
<div class="message error">
'.t('Username already taken').'
</div> ';
break;
case 'xmppconnect':
$warning = '
<div class="message error">
'.t('Could not connect to the XMPP server').'
</div> ';
break;
case 'xmppcomm':
$warning = '
<div class="message error">
'.t('Could not communicate with the XMPP server').'
</div> ';
break;
case 'unknown':
$warning = '
<div class="message error">
'.t('Unknown error').'
</div> ';
break;
}
$submit = $this->genCallAjax('ajaxDiscoverServer', "movim_parse_form('account')");
?>
<div id="main">
<div id="left">
<?php echo $warning; ?>
</div>
<div id="center">
<h1><?php echo t('Create a new account'); ?></h1>
<div style="margin: 15px 20px;">
<p>
<?php echo t('Movim is a decentralized social network, before creating a new account you need to choose a server to register.'); ?>
<?php echo t('Keep in mind that this server will handle all your personnal data.'); ?>
</p>
<br />
<form name="account">
<fieldset>
<legend><?php echo t('Step 1 - Search the server'); ?></legend>
<div class="clear"></div>
<p>
<?php echo t('You can%s enter your server domain name%s. ', '<a href="#nddlink">', '</a>');
echo t('Or you can choose a server from this list.'); ?>
</p>
<br />
<div style="height: 300px;" id="map"></div>
<br />
<?php echo $this->printServerList(); ?>
<br />
<div class="element">
<label for="ndd"><?php echo t("Server"); ?></label>
<input
pattern="^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$"
placeholder="<?php echo t("Enter the server domain (ex: movim.eu)"); ?>"
name="ndd"
id="ndd"
/>
</div>
<div class="clear"></div>
<a
name="nddlink"
class="button icon next"
style="float: right;"
onclick="<?php echo $submit;?>; document.getElementById('fillform').innerHTML ='<?php echo t('Searching...');?>'"
>
<?php echo t('Search'); ?>
</a>
</form>
<div class="clear"></div>
<div id="fillform"></div>
</div>
</div>
</div>
<?php
}
}

10
system/Widget/widgets/Account/account.css

@ -1,10 +0,0 @@
#nav .menu li:last-child {
background-image: none;
padding-right: 0px;
position: relative;
}
table#list {
border-spacing:0;
border-collapse:collapse;
}

3
system/Widget/widgets/Account/account.js

@ -1,3 +0,0 @@
function selectServer(ndd) {
document.querySelector('input[name="ndd"]').value = ndd;
}

246
system/Widget/widgets/Account/server-vcards.xml

@ -1,246 +0,0 @@
<vcards>
<vcard>
<fn>
<text>movim.eu</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://movim.eu/</uri>
</url>
<note>
<text>The Movim XMPP service.</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:movim.eu</uri>
</registration>
<bday>
<date>2013</date>
</bday>
<adr>
<country>IE</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">Metronome</name>
<impp>
<uri>xmpp:edhelas@movim.eu</uri>
</impp>
<geo>
<uri>geo:53.06,-7.29</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jappix.com</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://jappix.com/</uri>
</url>
<note>
<text>The Jappix XMPP service.</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jappix.com</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>FR</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">Metronome</name>
<impp>
<uri>xmpp:vanaryon@jappix.com</uri>
</impp>
<geo>
<uri>geo:50.67,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>tigase.im</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.tigase.im/</uri>
</url>
<note>
<text>The public Tigase service. - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:tigase.im</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>lightwitch.org</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.lightwitch.org/</uri>
</url>
<note>
<text>LW.Org XMPP Public Service.</text>
</note>
<registration>
<uri>xmpp:lightwitch.org</uri>
</registration>
<bday>
<date>2009</date>
</bday>
<adr>
<country>USA</country>
</adr>
<ca>
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name>Metronome</name>
<impp>
<uri>xmpp:maranda@lightwitch.org</uri>
</impp>
<geo>
<uri>geo:40.73,-74.17</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jabber.me</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.jabber.me/</uri>
</url>
<note>
<text>Just Jabber Me! - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jabber.me</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>sure.im</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.sure.im/</uri>
</url>
<note>
<text>Just Sure Im! - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:sure.im</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jabbim.cz</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.jabbim.cz/</uri>
</url>
<note>
<text>Stable ejabberd clustered server with good support and many transports and services: ICQ, AIM, MSN, Facebook, Weather, Yahoo, Notes, bots, MUCs, proxy65, STUN server for voice support, and more</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jabbim.cz</uri>
</registration>
<bday>
<date>2005</date>
</bday>
<adr>
<country>CZ</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">ejabberd</name>
<impp>
<uri>xmpp:pinky@njs.netlab.cz</uri>
</impp>
</vcard>
<vcard><fn><text>njs.netlab.cz</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:njs.netlab.cz</uri></registration><bday><date>2001</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.pl</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.pl</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.sk</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.sk</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.com</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.com</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>forumanalogue.fr</text></fn><kind><text>application</text></kind><url><uri>http://www.forumanalogue.fr/</uri></url><note><text>A public self-hosted Jabber server located in France.</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:forumanalogue.fr</uri></registration><bday><date>2010</date></bday><adr><country>FR</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>StartSSL</name><uri>http://www.startssl.com/</uri></ca><name xmlns="jabber:iq:version">Openfire</name><impp><uri>xmpp:clement@forumanalogue.fr</uri></impp><geo><uri>geo:45.8,4.84</uri></geo><lang><parameters><pref>1</pref></parameters><language-tag>fr</language-tag></lang></vcard>
</vcards>

484
system/Widget/widgets/Admin/Admin.php

@ -1,484 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Admin.php
* This file is part of MOVIM.
*
* @brief The administration widget.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 25 November 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Admin extends WidgetBase {
private $_conf;
function WidgetLoad()
{
$this->_conf = Conf::getServerConf();
}
private function isValid($what)
{
if($what)
return "message success";
else
return "message error";
}
private function testDir($dir){
return (file_exists($dir) && is_dir($dir) && is_writable($dir));
}
private function testFile($file) {
return (file_exists($file) && is_writable($file));
}
/*
* Create the dirs
*/
function createDirs(){
if(!file_exists(BASE_PATH.'cache') && !@mkdir(BASE_PATH.'cache')) {
echo t("Couldn't create directory '%s'.", 'cache');
return false;
}
if(!file_exists(BASE_PATH.'log') && !@mkdir(BASE_PATH.'log')) {
echo t("Couldn't create directory '%s'.", 'log');
return false;
}
if(!file_exists(BASE_PATH.'config') && !@mkdir(BASE_PATH.'config')) {
echo t("Couldn't create directory '%s'.", 'config');
return false;
}
}
private function listThemes()
{
$dir = opendir(BASE_PATH.'themes');
$themes = array();
while($theme = readdir($dir)) {
if(preg_match('/^\.+$/', $theme)
|| !is_dir(BASE_PATH.'themes/'.$theme)) {
continue;
}
$themes[$theme] = $theme;
}
return $themes;
}
private function listLangs()
{
$dir = opendir(BASE_PATH.'i18n');
$langs = array('en' => 'English');
$languages = get_lang_list();
while($lang = readdir($dir)) {
if(!preg_match('/\.po$/', $lang)) {
continue;
}
$lang = substr($lang, 0, strlen($lang) - 3);
$langs[$lang] = $languages[$lang];
}
return $langs;
}
function testBosh($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Fire !
$rs = array();
$rs['content'] = curl_exec($ch);
$rs['errno'] = curl_errno($ch);
$rs['errmsg'] = curl_error($ch);
$rs['header'] = curl_getinfo($ch);
if($rs['content'] != false && $rs['content'] != '') {
return true;
}
elseif($rs['errno'] != 0 || $rs['content'] == '') {
return false;
}
curl_close($ch);
}
public function ajaxAdminSubmit($form)
{
unset($form['']);
$empty = false;
if($form['pass'] == '' || !isset($form['pass'])) {
$form['pass'] = $this->_conf['pass'];
$form['repass'] = $this->_conf['pass'];
$empty = true;
}
if($form['pass'] == $form['repass']) {
unset($form['repass']);
if(!$empty)
$form['pass'] = sha1($form['pass']);
foreach($this->_conf as $key => $value) {
if(isset($form[$key]))
$this->_conf[$key] = $form[$key];
}
Conf::saveConfFile($this->_conf);
}
}
public function ajaxRecreateDatabase()
{
$pd = new \modl\PostnDAO();
$pd->create();
$nd = new \modl\NodeDAO();
$nd->create();
$cd = new \modl\ContactDAO();
$cd->create();
$cad = new \modl\CapsDAO();
$cad->create();
$prd = new \modl\PresenceDAO();
$prd->create();
$rd = new \modl\RosterLinkDAO();
$rd->create();
$sd = new \modl\SessionDAO();
$sd->create();
$cd = new \modl\CacheDAO();
$cd->create();
$md = new \modl\MessageDAO();
$md->create();
$cd = new \modl\SubscriptionDAO();
$cd->create();
$pr = new \modl\PrivacyDAO();
$pr->create();
}
private function prepareAdmin()
{
$submit = $this->genCallAjax('ajaxAdminSubmit', "movim_parse_form('admin')")
."this.className='button icon loading'; setTimeout(function() {location.reload(false)}, 2000);";
if($this->testDir(BASE_PATH))
$this->createDirs();
$html = '
<form name="admin" id="adminform">';
/*$html .= '
<fieldset>
<legend>'.t('General Informations').'</legend>';
$file = BASE_PATH.'VERSION';
if($f = fopen($file, 'r')){
$html .= '
<div class="element simple">
<label for="fn">'.t('Version').'</label>
<span>'.trim(fgets($f)).'</span>
</div>';
}
$html .= '
</fieldset>';*/
$html .= '
<fieldset>
<legend>'.t("Compatibility Check").'</legend>
<div class="clear"></div>';
$html .=
'<p>'.
t('Movim requires certain external components. Please install them before you can succeed:').
'</p><br />';
$html .= '
<div class="'.$this->isValid((version_compare(PHP_VERSION, '5.3.0') >= 0)).'">
'.t('Your PHP-Version: %s <br>Required: 5.3.0', PHP_VERSION).'
</div>
<div class="'.$this->isValid(extension_loaded('curl')).'">
'.t('CURL-Library').'
</div>
<div class="'.$this->isValid(extension_loaded('gd')).'">
'.t('GD').'
</div>
<div class="'.$this->isValid(extension_loaded('SimpleXml')).'">
'.t('SimpleXML').'
</div>
<div class="'.$this->isValid($this->testDir(BASE_PATH)).'">
'.t('Read and write rights for the webserver in Movim\'s root directory').'
</div>
<div class="'.$this->isValid($_SERVER['HTTP_MOD_REWRITE']).'">
'.t('URL Rewriting support').'
</div>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t('General Settings').'</legend>
<div class="element">
<label for="movim" >'.t('Theme').'</label>
<div class="select">
<select id="theme" name="theme">';
foreach($this->listThemes() as $key => $value) {
if((string)$this->_conf['theme'] == $key)
$sel = 'selected="selected"';
else
$sel = '';
$html .= '
<option value="'.$key.'" '.$sel.'>'.$value.'</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="element">
<label for="da">'.t('Default language').'</label>
<div class="select">
<select id="defLang" name="defLang">';
foreach($this->listLangs() as $key => $value) {
if((string)$this->_conf['defLang'] == $key)
$sel = 'selected="selected"';
else
$sel = '';
$html .= '
<option value="'.$key.'" '.$sel.'>'.$value.'</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="element">
<label for="maxUsers">'.t('Maximum population').'</label>
<input type="text" name="maxUsers" id="maxUsers" value="'.$this->_conf['maxUsers'].'" />
</div>';
$html .= '
<div class="element">
<label for="sizeLimit">'.t('User folder size limit (in bytes)').'</label>
<input type="text" name="sizeLimit" id="sizeLimit" value="'.$this->_conf['sizeLimit'].'" />
</div>';
$logopts = array(
0 => t('empty'),
2 => t('terse'),
4 => t('normal'),
6 => t('talkative'),
7 => t('ultimate'),
);
$default_log = 4;
$html .= '
<div class="element">
<label for="7">'.t("Log verbosity").'</label>
<div class="select">
<select id="logLevel" name="logLevel">';
foreach($logopts as $lognum => $text) {
if($this->_conf['logLevel'] == $lognum)
$sel = 'selected="selected"';
$html .= '
<option value="'.$lognum.'" '.$sel.'>'.
$text.'
</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Database Settings").'</legend>
<div class="clear"></div>';
$md = new \modl\ModlDAO();
if(isset($md->_dao->_error)) {
$html .= '
<div class="message error">'.
t("Modl wasn't able to connect to the database").'<br />
'.$md->_dao->_error.'
</div>
';
} else {
$dbrecreate = $this->genCallAjax('ajaxRecreateDatabase');
$html .= '
<div class="element">
<label for="db">'.t('Recreate the database').'</label>
<a class="button icon yes" onclick="'.$dbrecreate.'">'.t('Recreate').'</a>
</div>
<div class="message warning">
'.t('This button will clear and recreate the Movim database.').'
</div>
';
}
$html .= '
<div class="element large">
<label for="db">'.t('Dabase String').'</label>
<input type="text" name="db" id="db" value="'.$this->_conf['db'].'" />
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Bosh Configuration").'</legend>
<div class="clear"></div>';
$html .= '<p>'.
t("Enter here the BOSH-URL in the form: http(s)://domain:port/path.").' '.
t('If you enter an open BOSH-Server, you can connect to many XMPP-Servers.').' '.
t('If it is closed, you have to specify the corresponding Server on the next page.').' '.
t('If you are unsure about this config option visit the wiki');
'</p>';
if(!$this->testBosh($this->_conf['boshUrl'])) {
$html .= '
<div class="message error">'.
t('Your Bosh URL is not reachable').'
</div>';
}
$html .= '
<div class="element">
<label for="boshUrl">'.t("Bosh URL").'</label>
<input type="text" id="boshUrl" name="boshUrl" value="'.$this->_conf['boshUrl'].'"/>
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Whitelist - XMPP Server").'</legend>
<div class="clear"></div>';
$html .= '<p>'.
t("If you want to specify a list of authorized XMPP servers on your Movim pod and forbid the connection on all the others please put their domain name here, with comma (ex: movim.eu,jabber.fr)").
'</p>'.
'<p>'.
t("Leave this field blank if you allow the access to all the XMPP accounts.").
'</p>';
$html .= '
<div class="element large">
<label for="xmppWhiteList">'.t("List of whitelisted XMPP servers").'</label>
<input type="text" name="xmppWhiteList" id="xmppWhiteList" value="'.$this->_conf['xmppWhiteList'].'" />
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Administration Credential").'</legend>';
if($this->_conf['user'] == 'admin' && $this->_conf['pass'] == sha1('password')) {
$html .= '
<div class="message error">'.
t('Change the default username/password').'
</div>';
}
$html .= '
<div class="element" >
<label for="username">'.t("Username").'</label>
<input type="text" id="user" name="user" value="'.$this->_conf['user'].'"/>
</div>
<div class="clear"></div>
<div class="element">
<label for="pass">'.t("Password").'</label>
<input type="password" id="pass" name="pass" value=""/>
</div>
<div class="element">
<label for="repass">'.t("Retype password").'</label>
<input type="password" id="repass" name="repass" value=""/>
</div> ';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
</form>';
return $html;
}
function build()
{
?>
<div id="admin" style="margin: 1.5em;">
<?php echo $this->prepareAdmin(); ?>
</div>
<?php
}
}

29
system/Widget/widgets/Blog/Blog.php

@ -1,29 +0,0 @@
<?php
class Blog extends WidgetCommon {
function WidgetLoad()
{
}
function build()
{
$from = $_GET['f'];
$pd = new \modl\PostnDAO();
$messages = $pd->getPublic($from);
echo '
<div class="posthead" style="border-top: 0px;">
<a
class="button tiny icon feed merged left"
href="'.Route::urlize('feed',$from).'"
target="_blank"
>
'.t('Feed').' (Atom)
</a>
</div>';
echo $this->preparePosts($messages, true);
}
}

280
system/Widget/widgets/Bookmark/Bookmark.php

@ -1,280 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Bookmark extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('bookmark.css');
$this->registerEvent('bookmark', 'onBookmark');
$this->registerEvent('bookmarkerror', 'onBookmarkError');
$this->registerEvent('groupsubscribed', 'onGroupSubscribed');
$this->registerEvent('groupunsubscribed', 'onGroupUnsubscribed');
}
function onGroupSubscribed()
{
$arr = Cache::c('bookmark');
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
RPC::call('setBookmark');
}
function onGroupUnsubscribed()
{
$arr = Cache::c('bookmark');
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
RPC::call('setBookmark');
}
function onBookmark($arr)
{
$i = 0;
foreach($arr as $b) {
if($b['type'] == 'subscription') {
$su = new \modl\Subscription();
$su->jid = $this->user->getLogin();
$su->server = $b['server'];
$su->node = $b['node'];
$su->subscription = 'subscribed';
$su->subid = $b['subid'];
$su->timestamp = date('Y-m-d H:i:s', rand(1111111111, 8888888888));
$sd = new \modl\SubscriptionDAO();
$sd->set($su);
unset($arr[$i]);
}
$i++;
}
Cache::c('bookmark', $arr);
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
Notification::appendNotification(t('Bookmarks updated'), 'info');
}
function onBookmarkError($error)
{
Notification::appendNotification(t('An error occured : ').$error, 'error');
}
function ajaxGetBookmark()
{
$b = new moxl\BookmarkGet();
$b->request();
}
function ajaxSetBookmark($arr = null)
{
if($arr == null || $arr == '')
$arr = Cache::c('bookmark');
if($arr == null)
$arr = array();
$sd = new \modl\SubscriptionDAO();
if($sd != null) {
foreach($sd->getSubscribed() as $s) {
array_push($arr,
array(
'type' => 'subscription',
'server' => $s->server,
'title' => $s->title,
'subid' => $s->subid,
'node' => $s->node));
}
}
$b = new moxl\BookmarkSet();
$b->setArr($arr)
->request();
}
function ajaxBookmarkAdd($form)
{
if(!filter_var($form['url'], FILTER_VALIDATE_URL)) {
$html = '<div class="message error">'.t('Bad URL').'</div>' ;
RPC::call('movim_fill', 'bookmarkadderror', $html);
RPC::commit();
} elseif(trim($form['name']) == '') {
$html = '<div class="message error">'.t('Empty name').'</div>' ;
RPC::call('movim_fill', 'bookmarkadderror', $html);
RPC::commit();
} else {
$bookmarks = Cache::c('bookmark');
if($bookmarks == null)
$bookmarks = array();
array_push($bookmarks,
array(
'type' => 'url',
'name' => $form['name'],
'url' => $form['url']));
$this->ajaxSetBookmark($bookmarks);
}
}
function ajaxBookmarkUrlRemove($url)
{
$arr = Cache::c('bookmark');
foreach($arr as $key => $b) {
if($b['type'] == 'url' && $b['url'] == $url)
unset($arr[$key]);
}
$b = new moxl\BookmarkSet();
$b->setArr($arr)
->request();
}
function prepareBookmark($bookmarks)
{
$html = '';
$url = '';
$conference = '';
$subscription = '';
$sd = new \modl\SubscriptionDAO();
if($sd != null) {
foreach($sd->getSubscribed() as $s) {
$subscription .= '
<li>
<a href="'.Route::urlize('node', array($s->server, $s->node)).'">'.
$s->node.' ('.$s->server.')
</a>
</li>';
}
}
if($bookmarks == null)
$bookmarks = array();
foreach($bookmarks as $b) {
switch ($b['type']) {
case 'conference':
$conference .= '
<li>'.$b['name'].'</li>';
break;
case 'url':
$remove = $this->genCallAjax('ajaxBookmarkUrlRemove', "'".$b['url']."'");
$url .= '
<li>
<a target="_blank" href="'.$b['url'].'">'.
$b['name'].'
</a>
<a href="#" onclick="'.$remove.'">X</a>
</li>';
break;
}
}
if($subscription != '') {
$html .= '
<h3>'.t('Groups').'</h3>
<ul>'.
$subscription.'
</ul>';
}
if($url != '') {
$html .= '
<h3>'.t('Links').'</h3>
<ul>'.
$url.'
</ul>';
}
if($conference != '') {
$html .= '
<h3>'.t('Conferences').'</h3>
<ul>'.
$conference.'
</ul>';
}
$submit = $this->genCallAjax('ajaxBookmarkAdd', "movim_parse_form('bookmarkadd')");
$html .= '
<div class="popup" id="bookmarkadd">
<form name="bookmarkadd">
<fieldset>
<legend>'.t('Add a new URL').'</legend>
<div id="bookmarkadderror"></div>
<div class="element large mini">
<input name="url" placeholder="'.t('URL').'"/>
</div>
<div class="element large mini">
<input name="name" placeholder="'.t('Name').'"/>
</div>
</fieldset>
<a
class="button tiny icon yes black merged left"
onclick="'.$submit.'"
>'.
t('Add').'
</a><a
class="button tiny icon black merged right"
onclick="movim_toggle_display(\'#bookmarkadd\')"
>'.
t('Close').'
</a>
</form>
</div>
';
return $html;
}
function build()
{
$getbookmark = $this->genCallAjax("ajaxGetBookmark");
$setbookmark = $this->genCallAjax("ajaxSetBookmark", "''");
?>
<script type="text/javascript">
function setBookmark() {
<?php echo $setbookmark; ?>
}
</script>
<?php
?>
<h2><?php echo t('Bookmarks'); ?></h2>
<div id="bookmarks">
<?php echo $this->prepareBookmark(Cache::c('bookmark')); ?>
</div>
<br />
<a class="button icon add tiny merged right" style="float: right;"
onclick="movim_toggle_display('#bookmarkadd')"><?php echo('Add'); ?></a>
<a class="button icon refresh alone tiny merged left" style="float: right;"
onclick="<?php echo $getbookmark; ?>"></a>
<br />
<?php
}
}

7
system/Widget/widgets/Bookmark/bookmark.css

@ -1,7 +0,0 @@
#bookmarks li {
white-space: nowrap;
width: auto;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.5em;
}

438
system/Widget/widgets/Chat/Chat.php

@ -1,438 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Chat.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Chat extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chat.css');
$this->addjs('chat.js');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('messagepublished', 'onMessagePublished');
$this->registerEvent('composing', 'onComposing');
$this->registerEvent('paused', 'onPaused');
$this->registerEvent('attention', 'onAttention');
$this->registerEvent('presence', 'onPresence');
}
function onPresence($presence)
{
$arr = $presence->getPresence();
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(isset($contact) && $contact->chaton == 1) {
$txt = array(
1 => t('Online'),
2 => t('Away'),
3 => t('Do Not Disturb'),
4 => t('Extended Away'),
5 => t('Offline'),
);
$html = '
<div class="message presence">
<span class="date">'.date('G:i', time()).'</span>'.
prepareString(htmlentities($txt[$arr['presence']], ENT_COMPAT, "UTF-8")).'
</div>';
RPC::call('movim_append',
'messages'.$arr['jid'],
$html);
RPC::call('scrollTalk',
'messages'.$arr['jid']);
}
}
function onMessage($message)
{
if($message->key == $message->from) {
$key = $message->from;
$jid = $message->to;
} else {
$key = $message->to;
$jid = $message->from;
}
if($message->key != $message->from)
RPC::call('notify');
$rd = new \modl\RosterLinkDAO();
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(isset($contact) && $contact->chaton == 0) {
$contact->chaton = 2;
$rd->setChat($jid, 2);
$evt = new Event();
$evt->runEvent('openchat');
RPC::call('movim_prepend',
'chats',
$this->prepareChat($contact));
RPC::call('scrollAllTalks');
} else if(isset($contact) && $message->body != '') {
$html = $this->prepareMessage($message);
if($contact->chaton == 1) {
RPC::call('colorTalk',
'messages'.$contact->jid);
}
RPC::call('movim_append',
'messages'.$contact->jid,
$html);
RPC::call('hideComposing',
$contact->jid);
RPC::call('hidePaused',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onMessagePublished($jid)
{
Notification::appendNotification(t('Message Published'), 'success');
}
function onComposing($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if(in_array($contact->chaton, array(1, 2))) {
RPC::call('showComposing',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onPaused($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if(in_array($contact->chaton, array(1, 2))) {
RPC::call('showPaused',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onAttention($jid)
{
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
$html = '
<div style="font-weight: bold; color: black;" class="message" >
<span class="date">'.date('G:i', time()).'</span>'.
t('%s needs your attention', $contact->getTrueName()).'
</div>';
RPC::call('movim_append',
'messages'.$jid,
$html);
RPC::call('scrollTalk',
'messages'.$jid);
}
/**
* Open a new talk
*
* @param string $jid
* @return void
*/
function ajaxOpenTalk($jid)
{
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(
isset($contact)
&& $contact->chaton == 0
&& !in_array($contact->presence, array(5, 6))) {
$contact->chaton = 2;
$rd = new \modl\RosterLinkDAO();
$rd->setChat($jid, 2);
RPC::call('movim_prepend',
'chats',
$this->prepareChat($contact));
RPC::call('scrollAllTalks');
RPC::commit();
}
$evt = new Event();
$evt->runEvent('openchat');
}
/**
* Send a message
*
* @param string $to
* @param string $message
* @return void
*/
function ajaxSendMessage($to, $message)
{
$m = new \modl\Message();
$m->key = $this->user->getLogin();
$m->to = echapJid($to);
$m->from = $this->user->getLogin();
$m->type = 'chat';
$m->body = rawurldecode($message);
$m->published = date('Y-m-d H:i:s');
$m->delivered = date('Y-m-d H:i:s');
$md = new \modl\MessageDAO();
$md->set($m);
$evt = new Event();
$evt->runEvent('message', $m);
// We decode URL codes to send the correct message to the XMPP server
$m = new \moxl\MessagePublish();
$m->setTo($to)
->setContent(htmlspecialchars(rawurldecode($message)))
->request();
}
/**
* Send a "composing" message
*
* @param string $to
* @return void
*/
function ajaxSendComposing($to)
{
$mc = new \moxl\MessageComposing();
$mc->setTo($to)
->request();
}
/**
* Send a "paused" message
*
* @param string $to
* @return void
*/
function ajaxSendPaused($to)
{
$mp = new \moxl\MessagePaused();
$mp->setTo($to)
->request();
}
/**
* Close a talk
*
* @param string $jid
* @return void
*/
function ajaxCloseTalk($jid)
{
$rd = new \modl\RosterLinkDAO();
$contacts = $rd->getChats();
foreach($contacts as $contact) {
if(
$contact->jid == $jid
&& (
(int)$contact->chaton == 1
|| (int)$contact->chaton == 2)
) {
$contact->chaton = 0;
$rd->setNow($contact);
}
}
RPC::call('movim_delete',
'chat'.$jid);
$evt = new Event();
$evt->runEvent('closechat');
}
function ajaxHideTalk($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if($contact->chaton == 1)
$contact->chaton = 2;
else
$contact->chaton = 1;
$rd->setNow($contact);
RPC::call('scrollTalk',
'messages'.$contact->jid);
RPC::commit();
}
function prepareMessage($message) {
if($message->body != '') {
$html = '<div class="message ';
if($message->key == $message->from)
$html.= 'me';
$content = $message->body;
if(preg_match("#^/me#", $message->body)) {
$html .= " own ";
$content = "** ".substr($message->body, 4);
}
$html .= '"><span class="date">'.date('H:i', strtotime($message->published)).'</span>';
$html.= prepareString(htmlentities($content, ENT_COMPAT, "UTF-8")).'</div>';
return $html;
} else {
return '';
}
}
function prepareChats()
{
$rc = new \modl\ContactDAO();
$contacts = $rc->getRosterChat();
if(isset($contacts)) {
foreach($contacts as $contact) {
$html .= trim($this->prepareChat($contact));
}
}
return $html;
}
function prepareChat($contact)
{
$md = new \modl\MessageDAO();
$messages = $md->getContact($contact->jid, 0, 10);
if(!empty($messages)) {
$day = '';
foreach($messages as $m) {
if($day != date('d',strtotime($m->published))) {
$messageshtml .= '<div class="message presence">'.prepareDate(strtotime($m->published), false).'</div>';
$day = date('d',strtotime($m->published));
}
$messageshtml .= $this->prepareMessage($m);
}
}
$style = '';
if($contact->chaton == 2) {
$tabstyle = ' style="display: none;" ';
$panelstyle = ' style="display: block;" ';
}
$html = '
<div class="chat"
onclick="this.querySelector(\'textarea\').focus()"
id="chat'.$contact->jid.'">
<div class="panel" '.$panelstyle.'>
<div class="head" >
<span class="chatbutton cross" onclick="'.$this->genCallAjax("ajaxCloseTalk", "'".$contact->jid."'").'"></span>
<span class="chatbutton arrow" onclick="'.$this->genCallAjax("ajaxHideTalk", "'".$contact->jid."'").' hideTalk(this)"></span>
<img class="avatar" src="'.$contact->getPhoto('xs').'" />
<a class="name" href="'.Route::urlize('friend',$contact->jid).'">
'.$contact->getTrueName().'
</a>
<div class="clear"></div>
</div>
<div class="messages" id="messages'.$contact->jid.'">
'.$messageshtml.'
<div style="display: none;" class="message" id="composing'.$contact->jid.'">'.t('Composing...').'</div>
<div style="display: none;" class="message" id="paused'.$contact->jid.'">'.t('Paused...').'</div>
</div>
<div class="text">
<textarea
rows="1"
id="textarea'.$contact->jid.'"
onkeypress="
if(event.keyCode == 13) {
'.$this->genCallAjax('ajaxSendMessage', "'".$contact->jid."'", "sendMessage(this, '".$contact->jid."')").'
lastkeypress = new Date().getTime()+1000;
return false;
}
if(lastkeypress < new Date().getTime())
'.$this->genCallAjax('ajaxSendComposing', "'".$contact->jid."'").'
lastkeypress = new Date().getTime()+1000;
"
onkeyup="
movim_textarea_autoheight(this);
var val = this.value;
setTimeout(function()
{
if(lastkeypress < new Date().getTime() && val != \'\') {
'.$this->genCallAjax('ajaxSendPaused', "'".$contact->jid."'").'
lastkeypress = new Date().getTime()+1000;
}
},1100); // Listen for 2 seconds of silence
"
></textarea>
</div>
</div>
<div class="tab '.$tabclass.'" '.$tabstyle.' onclick="'.$this->genCallAjax("ajaxHideTalk", "'".$contact->jid."'").' showTalk(this);">
<div class="name">
<img class="avatar" src="'.$contact->getPhoto('xs').'" />'.$contact->getTrueName().'
</div>
</div>
</div>
';
return $html;
}
function build()
{
echo '<div id="chats">';
echo $this->prepareChats();
echo '</div>';
}
}

192
system/Widget/widgets/Chat/chat.css

@ -1,192 +0,0 @@
#chats {
position: fixed;
bottom: -4px;
right: 210px;
z-index: 3;
}
#chats .chat {
display: inline-block;
position: relative;
bottom: 0;
overflow: hidden;
box-shadow: 0px 5px 10px rgba(0,0,0,0.3);
margin-left: 0.5em;
}
#chats .chat .panel {
display: none;
}
#chats .chat .tab {
background-color: #DDD;
border: 1px solid #888;
border-top: 1px solid #AAA;
border-bottom: 0px;
overflow: hidden;
}
#chats .chat .tab.alert .name {
display: relative;
}
#chats .chat .tab.alert .name:after {
content: "+1";
color: white;
font-size: 10px;
padding: 0px;
line-height: 1.7em;
float: right;
background-color: #C5371E;
margin-top: 3px;
padding: 0px 8px;
margin-left: 10px;
}
#chats .chat .tab:hover {
background-color: #EEE;
border: 1px solid #AAA;
border-bottom: none;
color: black;
}
#chats .chat .tab .name {
padding-right: 5px ;
line-height: 24px;
}
#chats .chat .tab .name img {
margin-right: 5px;
float: left;
width: 24px;
}
#chats .chat .panel .head span.chatbutton {
width: 15px;
height: 15px;
background-repeat: no-repeat;
padding: 0px;
margin-top: 6px;
margin-right: 3px;
float: right;
}
#chats .chat .panel .head span.chatbutton.cross {
background-image: url(img/cross.png);
}
#chats .chat .panel .head span.chatbutton.arrow {
background-image: url(img/arrow.png);
}
#chats .chat .panel .head a.name {
padding-right: 1em;
display: inline-block;
margin: 0px;
width: 62%;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 3px;
font-size: 0.9em;
white-space: nowrap;
}
#chats .chat .tab:hover {
cursor: pointer;
}
#chats .chat .panel {
background-color: white;
width: 225px;
}
#chats .chat .panel .head {
background-color: #242424;
color: white;
line-height: 17px;
border: 1px solid #222;
border-bottom: 1px solid #242424;
}
#chats .chat .panel .head:hover {
cursor: pointer;
}
#chats .chat .panel .head > * {
color: white;
}
#chats .chat .panel .head a:hover {
text-decoration: underline;
}
#chats .chat .panel .head img {
margin-right: 5px;
float: left;
width: 24px;
}
#chats .chat .panel .messages {
background-color: white;
color: gray;
max-height: 250px;
overflow: auto;
min-height: 3em;
border: 1px solid #888;
border-top: 0px;
border-bottom: 0px;
}
#chats .chat .panel .text {
overflow: hidden;
border: 1px solid #888;
}
#chats .chat .panel .text textarea {
width: 100%;
border: 0px;
padding: 0.2em;
overflow: auto;
background-color: white;
resize: none;
/*height: 1em;
line-height: 1em;
font-size: 1em;*/
font-size: 1em;
height: 1.3em;
overflow-y: hidden;
}
#chats .chat .panel .text textarea:focus {
border: 0px;
}
#chats .chat .panel .messages .message {
padding: 5px;
word-wrap: break-word;
font-size: 12px;
}
#chats .chat .panel .messages .message.me {
background-color: #FFC;
}
#chats .chat .panel .messages .message.own {
color: blue;
}
#chats .chat .panel .messages .message.presence {
color: black;
font-weight: bold;
}
#chats .chat .panel .messages .message span.date {
float: right;
color: #ccc;
padding: 2px;
line-height: 1em;
}
#chats .chat .panel .messages .message.me span.date {
color: #444;
}

102
system/Widget/widgets/Chat/chat.js

@ -1,102 +0,0 @@
function scrollAllTalks() {
var mes = document.querySelectorAll('.messages');
for (var i=0; i<mes.length; i++){
// We add 200px to prevent smiley loading
mes.item(i).scrollTop = mes.item(i).scrollHeight + 200;
}
}
//Loads the Notification sound.
var chatSoundNotif = document.createElement('audio');
chatSoundNotif.setAttribute('src', './system/Widget/widgets/Chat/sound/notif.ogg');
chatSoundNotif.load();
chatSoundNotif.volume = 1;
movim_add_onload(function()
{
scrollAllTalks();
});
function colorTalk(params) {
messages = document.getElementById(params);
tabstyle = messages.parentNode.parentNode.querySelector('.tab').className = 'tab alert';
}
function showTalk(n) {
panel = n.parentNode.querySelector('.panel');
panel.style.display = 'block';
n.style.display = 'none';
n.className = 'tab';
}
function hideTalk(n) {
panel = n.parentNode.parentNode.parentNode.querySelector('.panel');
tab = n.parentNode.parentNode.parentNode.querySelector('.tab');
panel.style.display = 'none';
tab.style.display = 'block';
}
function scrollTalk(params) {
var messages = document.getElementById(params);
messages.scrollTop = messages.scrollHeight;
}
function showComposing(jid) {
var box = document.getElementById('messages' + jid);
var composing = document.getElementById('composing' + jid);
hidePaused(jid);
box.appendChild(composing);
composing.style.display = 'block';
}
function showPaused(jid) {
var box = document.getElementById('messages' + jid);
var paused = document.getElementById('paused' + jid);
hideComposing(jid);
box.appendChild(paused);
paused.style.display = 'block';
}
function notify() {
if(document_focus == false) {
movim_title_inc();
//play the notif sound
chatSoundNotif.pause();
chatSoundNotif.currentTime= 0;
chatSoundNotif.play();
}
}
function hideComposing(jid) {
var composing = document.getElementById('composing' + jid);
composing.style.display = 'none';
}
function hidePaused(jid) {
var paused = document.getElementById('paused' + jid);
paused.style.display = 'none';
}
function sendMessage(n, jid)
{
var text = n.value;
n.value = "";
n.focus();
// We escape the text to prevent XML errors
return encodeURIComponent(text);
}
function disableSound(){
chatSoundNotif.volume = 0;
}

BIN
system/Widget/widgets/Chat/img/arrow.png

Before

Width: 11  |  Height: 11  |  Size: 263 B

BIN
system/Widget/widgets/Chat/img/cross.png

Before

Width: 11  |  Height: 11  |  Size: 376 B

BIN
system/Widget/widgets/Chat/sound/notif.ogg

150
system/Widget/widgets/ChatExt/ChatExt.php

@ -1,150 +0,0 @@
<?php
/**
* @package Widgets
*
* @file ChatExt.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
require_once(LIB_PATH . "Widget/widgets/Chat/Chat.php");
class ChatExt extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chatext.css');
$this->addjs('chatext.js');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('openchat', 'onEvent');
$this->registerEvent('closechat', 'onEvent');
}
function prepareChat($contact)
{
$md = new \modl\MessageDAO();
$messages = $md->getContact($contact->jid, 0, 10);
if(!empty($messages)) {
$day = '';
foreach($messages as $m) {
if($day != date('d',strtotime($m->published))) {
$messageshtml .= '<div class="message presence">'.prepareDate(strtotime($m->published), false).'</div>';
$day = date('d',strtotime($m->published));
}
$chat = new Chat();
$messageshtml .= $chat->prepareMessage($m);
}
}
$style = '';
if($contact->chaton == 2) {
$tabstyle = ' style="display: none;" ';
$panelstyle = ' style="display: block;" ';
}
$html = '
<div class="chat" onclick="this.querySelector(\'textarea\').focus()">
<div class="messages" id="messages'.$contact->jid.'">
'.$messageshtml.'
<div style="display: none;" class="message" id="composing'.$contact->jid.'">'.t('Composing...').'</div>
<div style="display: none;" class="message" id="paused'.$contact->jid.'">'.t('Paused...').'</div>
</div>
<div class="text">
<textarea
rows="1"
onkeyup="movim_textarea_autoheight(this);"
onkeypress="if(event.keyCode == 13) { self.opener.'.$this->genCallWidget('Chat','ajaxSendMessage', "'".$contact->jid."'", "sendMessage(this, '".$contact->jid."')").' return false; }"
></textarea>
</div>
</div>
';
return $html;
}
function prepareList($contact, $first = false)
{
if($first)
$checked = ' checked ';
$html .= '
<li>
<input type="radio" name="contact" id="contact'.$contact->jid.'" '.$checked.'/>
<label class="tab" for="contact'.$contact->jid.'" onclick="setTimeout(function() {scrollAllTalks()}, 100);">
<img class="avatar" src="'.$contact->getPhoto('xs').'" />'.
$contact->getTrueName().'
</label>
<div class="content">'.trim($this->prepareChat($contact)).'
<span
class="chatbutton cross"
onclick="self.opener.'.$this->genCallWidget('Chat','ajaxCloseTalk', "'".$contact->jid."'").'"></span>
</div>
</li>';
return $html;
}
function onEvent()
{
if(!Cache::c('chatpop')) {
$html = $this->preparePop();
RPC::call('popUpEvent', 'movim_fill', 'chatpop', $html);
RPC::call('popUpEvent', 'scrollAllTalks');
}
}
function preparePop()
{
$rc = new \modl\ContactDAO();
$contacts = $rc->getRosterChat();
$list = '';
if(isset($contacts)) {
$first = true;
foreach($contacts as $contact) {
$list .= $this->prepareList($contact, $first);
$first = false;
}
$html = '<ul id="chatpoplist">'.$list.'</ul>';
}
return $html;
}
function onMessage($message)
{
if($message->key == $message->from) {
$key = $message->from;
$jid = $message->to;
} else {
$key = $message->to;
$jid = $message->from;
}
$chatpop = Cache::c('chatpop');
if(!$chatpop) {
$chat = new Chat();
RPC::call('popUpEvent', 'movim_append', 'messages'.$jid, $chat->prepareMessage($message));
RPC::call('popUpEvent', 'scrollAllTalks');
}
}
function build()
{
}
}

0
system/Widget/widgets/ChatExt/chatext.css

31
system/Widget/widgets/ChatExt/chatext.js

@ -1,31 +0,0 @@
// Initialise popup pointer
var popupWin = null;
function openPopup() {
var url = "?q=chatpop"
if( !popupWin || popupWin.closed ) {
popupWin = window.open( url, "popupWin", "height=400,width=600,directories=0,titlebar=0,toolbar=0,location=0,status=0,menubar=0,resizable=no" );
} else popupWin.focus();
}
function closePopup() {
popupWin.close();
}
function focusPopup() {
popupWin.focus();
}
function popUpEvent(args) {
if( popupWin && !popupWin.closed ) {
// The popup is open so call it
var func = args[0];
args.shift();
var params = args;
window['popupWin'][func](params);
} else {
// The popup is closed so open it
openPopup();
}
}

45
system/Widget/widgets/ChatPop/ChatPop.php

@ -1,45 +0,0 @@
<?php
/**
* @package Widgets
*
* @file ChatExt.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
require_once(LIB_PATH . "Widget/widgets/ChatExt/ChatExt.php");
class ChatPop extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chatpop.css');
$this->addjs('chatpop.js');
}
function build()
{
$chatext = new ChatExt();
echo '<div id="chatpop">';
echo $chatext->preparePop();
echo '</div>';
?>
<div id="connection">
<?php echo t('Connection').'...'; ?>
</div>
<?php
}
}

161
system/Widget/widgets/ChatPop/chatpop.css

@ -1,161 +0,0 @@
body {
margin: 0px;
background-color: #333;
font-family: sans-serif;
}
#connection {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.6);
display: none;
color: white;
font-size: 1.5em;
text-align: center;
line-height: 5em;
}
#chatpop {
height: 100%;
width: 100%;
position: fixed;
top: 0px;
left: 0px;
}
#chatpop #chatpoplist label {
display: block;
}
#chatpop #chatpoplist li input[type=radio] {
display: none;
}
#chatpop #chatpoplist li input[type=radio]:checked ~ .content {
display: block;
}
#chatpop #chatpoplist input[type=radio]:checked ~ label {
background-color: #111;
}
#chatpop #chatpoplist {
width: 25%;
height: 100%;
list-style-type: none;
margin: 0px;
overflow-y: auto;
display: block;
padding: 0px;
}
#chatpop #chatpoplist li {
margin: 0px;
padding: 0px;
}
#chatpop #chatpoplist li .tab {
white-space: nowrap;
width: auto;
overflow: hidden;
color: #BBB;
line-height: 30px;
font-size: 13px;
text-overflow: ellipsis;
}
#chatpop #chatpoplist li:hover .tab {
background-color: #222;
cursor: pointer;
}
#chatpop #chatpoplist li .tab img.avatar {
float: left;
margin-right: 5px;
width: 30px;
}
#chatpop #chatpoplist li .content {
position: fixed;
top: 0px;
right: 0px;
height: 90%;
width: 75%;
display: none;
background-color: white;
overflow-y: auto;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
}
#chatpop #chatpoplist li .content .text {
position: fixed;
bottom: 0px;
right: 0px;
width: 75%;
background-color: red;
min-height: 10%;
border-top: 1px solid #333;
background-color: white;
}
#chatpop #chatpoplist li .content .text textarea {
width: 100%;
margin: 0px;
padding: 0px;
border: 0px;
height: auto;
background-color: white;
resize: none;
}
#chatpop #chatpoplist li .content .messages {
font-size: 13px;
}
#chatpop #chatpoplist li .content .messages .message {
margin: 10px;
margin-right: 30px;
background-color: #FFE8CC;
padding: 5px;
min-height: 25px;
}
#chatpop #chatpoplist li .content .messages .message.me {
margin-left: 30px;
margin-right: 10px;
background-color: #FFFFCC;
}
#chatpop #chatpoplist li .content .messages .message .date {
float: right;
color: #888;
font-size: 11px;
padding-left: 10px;
}
#chatpop #chatpoplist li .content .messages .message.presence {
background-color: transparent;
font-weight: bold;
min-height: 0px;
}
#chatpop #chatpoplist span.chatbutton {
width: 28px;
height: 28px;
background-repeat: no-repeat;
background-position: center center;
position: fixed;
bottom: 0px;
left: 0px;
}
#chatpop #chatpoplist span.chatbutton:hover {
cursor: pointer;
}
#chatpop #chatpoplist li span.chatbutton.cross {
background-image: url(img/cross.png);
}

46
system/Widget/widgets/ChatPop/chatpop.js

@ -1,46 +0,0 @@
function notifyOpener() {
document.querySelector('#connection').style.display = 'none';
if(self.opener || !self.opener.popupWin)
self.opener.popupWin = self;
}
setInterval( notifyOpener, 200 );
self.focus();
function doSomething() {
alert("I'm doing something");
}
function handleError() {
document.querySelector('#connection').style.display = 'block';
}
window.onerror = handleError;
window.onunload = function() {
self.opener.Roster_ajaxToggleChat();
};
function scrollAllTalks() {
var mes = document.querySelectorAll('.content');
for (var i=0; i<mes.length; i++){
// We add 200px to prevent smiley loading
mes.item(i).scrollTop = mes.item(i).scrollHeight + 200;
}
}
function sendMessage(n, jid)
{
var text = n.value;
n.value = "";
n.focus();
// We escape the text to prevent XML errors
return encodeURIComponent(text);
}
//setInterval( scrollAllTalks, 200 );

BIN
system/Widget/widgets/ChatPop/img/cross.png

Before

Width: 11  |  Height: 11  |  Size: 376 B

196
system/Widget/widgets/Config/Config.php

@ -1,196 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Config extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('config.css');
$this->addjs('color/jscolor.js');
$this->registerEvent('config', 'onConfig');
}
function onConfig(array $data)
{
$this->user->setConfig($data);
Notification::appendNotification(t('Configuration updated'));
}
function ajaxSubmit($data) {
$config = $this->user->getConfig();
if(isset($config))
$data = array_merge($config, $data);
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($data))
->request();
}
function ajaxGet() {
$s = new moxl\StorageGet();
$s->setXmlns('movim:prefs')
->request();
}
function build()
{
$languages = load_lang_array();
/* We load the user configuration */
$conf = $this->user->getConfig('language');
$color = $this->user->getConfig('color');
$submit = $this->genCallAjax('ajaxSubmit', "movim_parse_form('general')")
. "this.className='button icon loading'; setTimeout(function() {location.reload(false)}, 2000); this.onclick=null;";
?>
<div class="tabelem padded" title="<?php echo t('Configuration'); ?>" id="config" >
<form enctype="multipart/form-data" method="post" action="index.php" name="general">
<fieldset>
<legend><?php echo t('General'); ?></legend>
<div class="element">
<label for="language"><?php echo t('Language'); ?></label>
<div class="select">
<select name="language" id="language">
<option value="en">English (default)</option>
<?php
foreach($languages as $key => $value ) {
if($key == $conf) { ?>
<option value="<?php echo $key; ?>" selected="selected"><?php echo $value; ?></option>
<?php } else {?>
<option value="<?php echo $key; ?>"><?php echo $value; ?></option>
<?php }
} ?>
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo t('Apparence'); ?></legend>
<div class="element">
<label for="color"><?php echo t('Background color'); ?></label>
<a
type="button"
onclick="
document.querySelector('input[name=color]').value = '082D50';
document.body.style.backgroundColor = '#082D50';"
style="width: 45%; float: right;"
class="button icon back">
<?php echo t('Reset');?>
</a>
<input
style="box-shadow: none; width: 50%; float: left;"
name="color"
class="color"
onchange="document.body.style.backgroundColor = '#'+this.value;"
value="
<?php
if(isset($color))
echo $color;
else
echo "082D50";
?>
">
</div>
<div class="element large">
<label for="pattern"><?php echo t('Pattern'); ?></label>
<input type="radio" name="pattern" id="argyle" value="argyle"/>
<label for="argyle"><span></span>
<div class="preview argyle"
style="background-color: #6d695c;"></div>
</label>
<input type="radio" name="pattern" id="default" value="default"/>
<label for="default"><span></span>
<div class="preview default"
style="background-color: #082D50;;"></div>
</label>
<input type="radio" name="pattern" id="tableclothe" value="tableclothe"/>
<label for="tableclothe"><span></span>
<div class="preview tableclothe"
style="background-color: rgba(200, 0, 0, 1);"></div>
</label>
<input type="radio" name="pattern" id="blueprint" value="blueprint"/>
<label for="blueprint"><span></span>
<div class="preview blueprint"
style="background-color:#269;"></div>
</label>
<input type="radio" name="pattern" id="cicada" value="cicada"/>
<label for="cicada"><span></span>
<div class="preview cicada"
style="background-color: #026873;"></div>
</label>
<input type="radio" name="pattern" id="stripes" value="stripes"/>
<label for="stripes"><span></span>
<div class="preview stripes"
style="background-color: orange;"></div>
</label>
<input type="radio" name="pattern" id="stars" value="stars"/>
<label for="stars"><span></span>
<div class="preview stars"
style="background-color:black; background-size: 100px 100px;"></div>
</label>
<input type="radio" name="pattern" id="paper" value="paper"/>
<label for="paper"><span></span>
<div class="preview paper"
style="background-color: #23343E;"></div>
</label>
<input type="radio" name="pattern" id="tartan" value="tartan"/>
<label for="tartan"><span></span>
<div class="preview tartan"
style="background-color: hsl(2, 57%, 40%);"></div>
</label>
<input type="radio" name="pattern" id="empty" value=""/>
<label for="empty"><span></span>
<div class="preview empty"
style="background-color: white;"></div>
</label>
</div>
</fieldset>
<br />
<hr />
<!--<label id="lock" for="soundnotif"><?php echo t('Enable Sound Notification:'); ?></label>
<input type="checkbox" name="soundnotif" value="soundnotif" checked="checked" /><br /> -->
<!--<input value="<?php echo t('Submit'); ?>" onclick="<?php echo $submit; ?>" type="button" class="button icon yes merged right" style="float: right;">
<input type="reset" value="<?php echo t('Reset'); ?>" class="button icon no merged left" style="float: right;">-->
<br />
<a onclick="<?php echo $submit; ?>" type="button" class="button icon yes" style="float: right;"><?php echo t('Submit'); ?></a>
<!--<a type="reset" value="<?php echo t('Reset'); ?>" class="button icon no merged left" style="float: right;">-->
</p>
</form>
<br /><br />
<div class="message info"><?php echo t("This configuration is shared wherever you are connected !");?></div>
</div>
<?php
}
}

BIN
system/Widget/widgets/Config/color/arrow.gif

Before

Width: 7  |  Height: 11  |  Size: 66 B

BIN
system/Widget/widgets/Config/color/cross.gif

Before

Width: 15  |  Height: 15  |  Size: 83 B

12
system/Widget/widgets/Config/color/demo.html

@ -1,12 +0,0 @@
<html>
<head>
<title>jscolor demo</title>
</head>
<body>
<script type="text/javascript" src="jscolor.js"></script>
Click here: <input class="color" value="66ff00">
</body>
</html>

BIN
system/Widget/widgets/Config/color/hs.png

Before

Width: 181  |  Height: 101  |  Size: 2.6 KiB

BIN
system/Widget/widgets/Config/color/hv.png

Before

Width: 181  |  Height: 101  |  Size: 2.8 KiB

953
system/Widget/widgets/Config/color/jscolor.js

@ -1,953 +0,0 @@
/**
* jscolor, JavaScript Color Picker
*
* @version 1.4.0
* @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
* @author Jan Odvarko, http://odvarko.cz
* @created 2008-06-15
* @updated 2012-07-06
* @link http://jscolor.com
*/
var jscolor = {
dir : '', // location of jscolor directory (leave empty to autodetect)
bindClass : 'color', // class name
binding : true, // automatic binding via <input class="...">
preloading : true, // use image preloading?
install : function() {
jscolor.addEvent(window, 'load', jscolor.init);
},
init : function() {
if(jscolor.binding) {
jscolor.bind();
}
if(jscolor.preloading) {
jscolor.preload();
}
},
getDir : function() {
if(!jscolor.dir) {
var detected = jscolor.detectDir();
jscolor.dir = detected!==false ? detected : 'jscolor/';
}
return jscolor.dir;
},
detectDir : function() {
var base = location.href;
var e = document.getElementsByTagName('base');
for(var i=0; i<e.length; i+=1) {
if(e[i].href) { base = e[i].href; }
}
var e = document.getElementsByTagName('script');
for(var i=0; i<e.length; i+=1) {
if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
var src = new jscolor.URI(e[i].src);
var srcAbs = src.toAbsolute(base);
srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
srcAbs.query = null;
srcAbs.fragment = null;
return srcAbs.toString();
}
}
return false;
},
bind : function() {
var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
var e = document.getElementsByTagName('input');
for(var i=0; i<e.length; i+=1) {
var m;
if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
var prop = {};
if(m[3]) {
try {
prop = (new Function ('return (' + m[3] + ')'))();
} catch(eInvalidProp) {}
}
e[i].color = new jscolor.color(e[i], prop);
}
}
},
preload : function() {
for(var fn in jscolor.imgRequire) {
if(jscolor.imgRequire.hasOwnProperty(fn)) {
jscolor.loadImage(fn);
}
}
},
images : {
pad : [ 181, 101 ],
sld : [ 16, 101 ],
cross : [ 15, 15 ],
arrow : [ 7, 11 ]
},
imgRequire : {},
imgLoaded : {},
requireImage : function(filename) {
jscolor.imgRequire[filename] = true;
},
loadImage : function(filename) {
if(!jscolor.imgLoaded[filename]) {
jscolor.imgLoaded[filename] = new Image();
jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
}
},
fetchElement : function(mixed) {
return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
},
addEvent : function(el, evnt, func) {
if(el.addEventListener) {
el.addEventListener(evnt, func, false);
} else if(el.attachEvent) {
el.attachEvent('on'+evnt, func);
}
},
fireEvent : function(el, evnt) {
if(!el) {
return;
}
if(document.createEvent) {
var ev = document.createEvent('HTMLEvents');
ev.initEvent(evnt, true, true);
el.dispatchEvent(ev);
} else if(document.createEventObject) {
var ev = document.createEventObject();
el.fireEvent('on'+evnt, ev);
} else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
el['on'+evnt]();
}
},
getElementPos : function(e) {
var e1=e, e2=e;
var x=0, y=0;
if(e1.offsetParent) {
do {
x += e1.offsetLeft;
y += e1.offsetTop;
} while(e1 = e1.offsetParent);
}
while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
x -= e2.scrollLeft;
y -= e2.scrollTop;
}
return [x, y];
},
getElementSize : function(e) {
return [e.offsetWidth, e.offsetHeight];
},
getRelMousePos : function(e) {
var x = 0, y = 0;
if (!e) { e = window.event; }
if (typeof e.offsetX === 'number') {
x = e.offsetX;
y = e.offsetY;
} else if (typeof e.layerX === 'number') {
x = e.layerX;
y = e.layerY;
}
return { x: x, y: y };
},
getViewPos : function() {
if(typeof window.pageYOffset === 'number') {
return [window.pageXOffset, window.pageYOffset];
} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
return [document.body.scrollLeft, document.body.scrollTop];
} else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
} else {
return [0, 0];
}
},
getViewSize : function() {
if(typeof window.innerWidth === 'number') {
return [window.innerWidth, window.innerHeight];
} else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
return [document.body.clientWidth, document.body.clientHeight];
} else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
return [document.documentElement.clientWidth, document.documentElement.clientHeight];
} else {
return [0, 0];
}
},
URI : function(uri) { // See RFC3986
this.scheme = null;
this.authority = null;
this.path = '';
this.query = null;
this.fragment = null;
this.parse = function(uri) {
var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
this.scheme = m[3] ? m[2] : null;
this.authority = m[5] ? m[6] : null;
this.path = m[7];
this.query = m[9] ? m[10] : null;
this.fragment = m[12] ? m[13] : null;
return this;
};
this.toString = function() {
var result = '';
if(this.scheme !== null) { result = result + this.scheme + ':'; }
if(this.authority !== null) { result = result + '//' + this.authority; }
if(this.path !== null) { result = result + this.path; }
if(this.query !== null) { result = result + '?' + this.query; }
if(this.fragment !== null) { result = result + '#' + this.fragment; }
return result;
};
this.toAbsolute = function(base) {
var base = new jscolor.URI(base);
var r = this;
var t = new jscolor.URI;
if(base.scheme === null) { return false; }
if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
r.scheme = null;
}
if(r.scheme !== null) {
t.scheme = r.scheme;
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.authority !== null) {
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.path === '') {
t.path = base.path;
if(r.query !== null) {
t.query = r.query;
} else {
t.query = base.query;
}
} else {
if(r.path.substr(0,1) === '/') {
t.path = removeDotSegments(r.path);
} else {
if(base.authority !== null && base.path === '') {
t.path = '/'+r.path;
} else {
t.path = base.path.replace(/[^\/]+$/,'')+r.path;
}
t.path = removeDotSegments(t.path);
}
t.query = r.query;
}
t.authority = base.authority;
}
t.scheme = base.scheme;
}
t.fragment = r.fragment;
return t;
};
function removeDotSegments(path) {
var out = '';
while(path) {
if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
path = path.replace(/^\.+/,'').substr(1);
} else if(path.substr(0,3)==='/./' || path==='/.') {
path = '/'+path.substr(3);
} else if(path.substr(0,4)==='/../' || path==='/..') {
path = '/'+path.substr(4);
out = out.replace(/\/?[^\/]*$/, '');
} else if(path==='.' || path==='..') {
path = '';
} else {
var rm = path.match(/^\/?[^\/]*/)[0];
path = path.substr(rm.length);
out = out + rm;
}
}
return out;
}
if(uri) {
this.parse(uri);
}
},
/*
* Usage example:
* var myColor = new jscolor.color(myInputElement)
*/
color : function(target, prop) {
this.required = true; // refuse empty values?
this.adjust = true; // adjust value to uniform notation?
this.hash = false; // prefix color with # symbol?
this.caps = true; // uppercase?
this.slider = true; // show the value/saturation slider?
this.valueElement = target; // value holder
this.styleElement = target; // where to reflect current color
this.onImmediateChange = null; // onchange callback (can be either string or function)
this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
this.minH = 0; // read-only 0-6
this.maxH = 6; // read-only 0-6
this.minS = 0; // read-only 0-1
this.maxS = 1; // read-only 0-1
this.minV = 0; // read-only 0-1
this.maxV = 1; // read-only 0-1
this.pickerOnfocus = true; // display picker on focus?
this.pickerMode = 'HSV'; // HSV | HVS
this.pickerPosition = 'bottom'; // left | right | top | bottom
this.pickerSmartPosition = true; // automatically adjust picker position when necessary
this.pickerButtonHeight = 20; // px
this.pickerClosable = false;
this.pickerCloseText = 'Close';
this.pickerButtonColor = 'ButtonText'; // px
this.pickerFace = 10; // px
this.pickerFaceColor = 'ThreeDFace'; // CSS color
this.pickerBorder = 1; // px
this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight'; // CSS color
this.pickerInset = 1; // px
this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow'; // CSS color
this.pickerZIndex = 10000;
for(var p in prop) {
if(prop.hasOwnProperty(p)) {
this[p] = prop[p];
}
}
this.hidePicker = function() {
if(isPickerOwner()) {
removePicker();
}
};
this.showPicker = function() {
if(!isPickerOwner()) {
var tp = jscolor.getElementPos(target); // target pos
var ts = jscolor.getElementSize(target); // target size
var vp = jscolor.getViewPos(); // view pos
var vs = jscolor.getViewSize(); // view size
var ps = getPickerDims(this); // picker size
var a, b, c;
switch(this.pickerPosition.toLowerCase()) {
case 'left': a=1; b=0; c=-1; break;
case 'right':a=1; b=0; c=1; break;
case 'top': a=0; b=1; c=-1; break;
default: a=0; b=1; c=1; break;
}
var l = (ts[b]+ps[b])/2;
// picker pos
if (!this.pickerSmartPosition) {
var pp = [
tp[a],
tp[b]+ts[b]-l+l*c
];
} else {
var pp = [
-vp[a]+tp[a]+ps[a] > vs[a] ?
(-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
tp[a],
-vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
(-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
(tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
];
}
drawPicker(pp[a], pp[b]);
}
};
this.importColor = function() {
if(!valueElement) {
this.exportColor();
} else {
if(!this.adjust) {
if(!this.fromString(valueElement.value, leaveValue)) {
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
}
} else if(!this.required && /^\s*$/.test(valueElement.value)) {
valueElement.value = '';
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
} else if(this.fromString(valueElement.value)) {
// OK
} else {
this.exportColor();
}
}
};
this.exportColor = function(flags) {
if(!(flags & leaveValue) && valueElement) {
var value = this.toString();
if(this.caps) { value = value.toUpperCase(); }
if(this.hash) { value = '#'+value; }
valueElement.value = value;
}
if(!(flags & leaveStyle) && styleElement) {
styleElement.style.backgroundImage = "none";
styleElement.style.backgroundColor =
'#'+this.toString();
styleElement.style.color =
0.213 * this.rgb[0] +
0.715 * this.rgb[1] +
0.072 * this.rgb[2]
< 0.5 ? '#FFF' : '#000';
}
if(!(flags & leavePad) && isPickerOwner()) {
redrawPad();
}
if(!(flags & leaveSld) && isPickerOwner()) {
redrawSld();
}
};
this.fromHSV = function(h, s, v, flags) { // null = don't change
if(h !== null) { h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); }
if(s !== null) { s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); }
if(v !== null) { v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); }
this.rgb = HSV_RGB(
h===null ? this.hsv[0] : (this.hsv[0]=h),
s===null ? this.hsv[1] : (this.hsv[1]=s),
v===null ? this.hsv[2] : (this.hsv[2]=v)
);
this.exportColor(flags);
};
this.fromRGB = function(r, g, b, flags) { // null = don't change
if(r !== null) { r = Math.max(0.0, Math.min(1.0, r)); }
if(g !== null) { g = Math.max(0.0, Math.min(1.0, g)); }
if(b !== null) { b = Math.max(0.0, Math.min(1.0, b)); }
var hsv = RGB_HSV(
r===null ? this.rgb[0] : r,
g===null ? this.rgb[1] : g,
b===null ? this.rgb[2] : b
);
if(hsv[0] !== null) {
this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]));
}
if(hsv[2] !== 0) {
this.hsv[1] = hsv[1]===null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]));
}
this.hsv[2] = hsv[2]===null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
// update RGB according to final HSV, as some values might be trimmed
var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
this.rgb[0] = rgb[0];
this.rgb[1] = rgb[1];
this.rgb[2] = rgb[2];
this.exportColor(flags);
};
this.fromString = function(hex, flags) {
var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
if(!m) {
return false;
} else {
if(m[1].length === 6) { // 6-char notation
this.fromRGB(
parseInt(m[1].substr(0,2),16) / 255,
parseInt(m[1].substr(2,2),16) / 255,
parseInt(m[1].substr(4,2),16) / 255,
flags
);
} else { // 3-char notation
this.fromRGB(
parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
flags
);
}
return true;
}
};
this.toString = function() {
return (
(0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
);
};
function RGB_HSV(r, g, b) {
var n = Math.min(Math.min(r,g),b);
var v = Math.max(Math.max(r,g),b);
var m = v - n;
if(m === 0) { return [ null, 0, v ]; }
var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
return [ h===6?0:h, m/v, v ];
}
function HSV_RGB(h, s, v) {
if(h === null) { return [ v, v, v ]; }
var i = Math.floor(h);
var f = i%2 ? h-i : 1-(h-i);
var m = v * (1 - s);
var n = v * (1 - s*f);
switch(i) {
case 6:
case 0: return [v,n,m];
case 1: return [n,v,m];
case 2: return [m,v,n];
case 3: return [m,n,v];
case 4: return [n,m,v];
case 5: return [v,m,n];
}
}
function removePicker() {
delete jscolor.picker.owner;
document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
}
function drawPicker(x, y) {
if(!jscolor.picker) {
jscolor.picker = {
box : document.createElement('div'),
boxB : document.createElement('div'),
pad : document.createElement('div'),
padB : document.createElement('div'),
padM : document.createElement('div'),
sld : document.createElement('div'),
sldB : document.createElement('div'),
sldM : document.createElement('div'),
btn : document.createElement('div'),
btnS : document.createElement('span'),
btnT : document.createTextNode(THIS.pickerCloseText)
};
for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
var seg = document.createElement('div');
seg.style.height = segSize+'px';
seg.style.fontSize = '1px';
seg.style.lineHeight = '0';
jscolor.picker.sld.appendChild(seg);
}
jscolor.picker.sldB.appendChild(jscolor.picker.sld);
jscolor.picker.box.appendChild(jscolor.picker.sldB);
jscolor.picker.box.appendChild(jscolor.picker.sldM);
jscolor.picker.padB.appendChild(jscolor.picker.pad);
jscolor.picker.box.appendChild(jscolor.picker.padB);
jscolor.picker.box.appendChild(jscolor.picker.padM);
jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
jscolor.picker.btn.appendChild(jscolor.picker.btnS);
jscolor.picker.box.appendChild(jscolor.picker.btn);
jscolor.picker.boxB.appendChild(jscolor.picker.box);
}
var p = jscolor.picker;
// controls interaction
p.box.onmouseup =
p.box.onmouseout = function() { target.focus(); };
p.box.onmousedown = function() { abortBlur=true; };
p.box.onmousemove = function(e) {
if (holdPad || holdSld) {
holdPad && setPad(e);
holdSld && setSld(e);
if (document.selection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
dispatchImmediateChange();
}
};
p.padM.onmouseup =
p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
p.padM.onmousedown = function(e) {
// if the slider is at the bottom, move it up
switch(modeID) {
case 0: if (THIS.hsv[2] === 0) { THIS.fromHSV(null, null, 1.0); }; break;
case 1: if (THIS.hsv[1] === 0) { THIS.fromHSV(null, 1.0, null); }; break;
}
holdPad=true;
setPad(e);
dispatchImmediateChange();
};
p.sldM.onmouseup =
p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
p.sldM.onmousedown = function(e) {
holdSld=true;
setSld(e);
dispatchImmediateChange();
};
// picker
var dims = getPickerDims(THIS);
p.box.style.width = dims[0] + 'px';
p.box.style.height = dims[1] + 'px';
// picker border
p.boxB.style.position = 'absolute';
p.boxB.style.clear = 'both';
p.boxB.style.left = x+'px';
p.boxB.style.top = y+'px';
p.boxB.style.zIndex = THIS.pickerZIndex;
p.boxB.style.border = THIS.pickerBorder+'px solid';
p.boxB.style.borderColor = THIS.pickerBorderColor;
p.boxB.style.background = THIS.pickerFaceColor;
// pad image
p.pad.style.width = jscolor.images.pad[0]+'px';
p.pad.style.height = jscolor.images.pad[1]+'px';
// pad border
p.padB.style.position = 'absolute';
p.padB.style.left = THIS.pickerFace+'px';
p.padB.style.top = THIS.pickerFace+'px';
p.padB.style.border = THIS.pickerInset+'px solid';
p.padB.style.borderColor = THIS.pickerInsetColor;
// pad mouse area
p.padM.style.position = 'absolute';
p.padM.style.left = '0';
p.padM.style.top = '0';
p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
p.padM.style.height = p.box.style.height;
p.padM.style.cursor = 'crosshair';
// slider image
p.sld.style.overflow = 'hidden';
p.sld.style.width = jscolor.images.sld[0]+'px';
p.sld.style.height = jscolor.images.sld[1]+'px';
// slider border
p.sldB.style.display = THIS.slider ? 'block' : 'none';
p.sldB.style.position = 'absolute';
p.sldB.style.right = THIS.pickerFace+'px';
p.sldB.style.top = THIS.pickerFace+'px';
p.sldB.style.border = THIS.pickerInset+'px solid';
p.sldB.style.borderColor = THIS.pickerInsetColor;
// slider mouse area
p.sldM.style.display = THIS.slider ? 'block' : 'none';
p.sldM.style.position = 'absolute';
p.sldM.style.right = '0';
p.sldM.style.top = '0';
p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
p.sldM.style.height = p.box.style.height;
try {
p.sldM.style.cursor = 'pointer';
} catch(eOldIE) {
p.sldM.style.cursor = 'hand';
}
// "close" button
function setBtnBorder() {
var insetColors = THIS.pickerInsetColor.split(/\s+/);
var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
p.btn.style.borderColor = pickerOutsetColor;
}
p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
p.btn.style.position = 'absolute';
p.btn.style.left = THIS.pickerFace + 'px';
p.btn.style.bottom = THIS.pickerFace + 'px';
p.btn.style.padding = '0 15px';
p.btn.style.height = '18px';
p.btn.style.border = THIS.pickerInset + 'px solid';
setBtnBorder();
p.btn.style.color = THIS.pickerButtonColor;
p.btn.style.font = '12px sans-serif';
p.btn.style.textAlign = 'center';
try {
p.btn.style.cursor = 'pointer';
} catch(eOldIE) {
p.btn.style.cursor = 'hand';
}
p.btn.onmousedown = function () {
THIS.hidePicker();
};
p.btnS.style.lineHeight = p.btn.style.height;
// load images in optimal order
switch(modeID) {
case 0: var padImg = 'hs.png'; break;
case 1: var padImg = 'hv.png'; break;
}
p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
p.padM.style.backgroundRepeat = "no-repeat";
p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
p.sldM.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
p.pad.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundPosition = "0 0";
// place pointers
redrawPad();
redrawSld();
jscolor.picker.owner = THIS;
document.getElementsByTagName('body')[0].appendChild(p.boxB);
}
function getPickerDims(o) {
var dims = [
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
(o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
o.pickerClosable ?
4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
];
return dims;
}
function redrawPad() {
// redraw the pad pointer
switch(modeID) {
case 0: var yComponent = 1; break;
case 1: var yComponent = 2; break;
}
var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
jscolor.picker.padM.style.backgroundPosition =
(THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
(THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
// redraw the slider image
var seg = jscolor.picker.sld.childNodes;
switch(modeID) {
case 0:
var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
for(var i=0; i<seg.length; i+=1) {
seg[i].style.backgroundColor = 'rgb('+
(rgb[0]*(1-i/seg.length)*100)+'%,'+
(rgb[1]*(1-i/seg.length)*100)+'%,'+
(rgb[2]*(1-i/seg.length)*100)+'%)';
}
break;
case 1:
var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
var i = Math.floor(THIS.hsv[0]);
var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
switch(i) {
case 6:
case 0: rgb=[0,1,2]; break;
case 1: rgb=[1,0,2]; break;
case 2: rgb=[2,0,1]; break;
case 3: rgb=[2,1,0]; break;
case 4: rgb=[1,2,0]; break;
case 5: rgb=[0,2,1]; break;
}
for(var i=0; i<seg.length; i+=1) {
s = 1 - 1/(seg.length-1)*i;
c[1] = c[0] * (1 - s*f);
c[2] = c[0] * (1 - s);
seg[i].style.backgroundColor = 'rgb('+
(c[rgb[0]]*100)+'%,'+
(c[rgb[1]]*100)+'%,'+
(c[rgb[2]]*100)+'%)';
}
break;
}
}
function redrawSld() {
// redraw the slider pointer
switch(modeID) {
case 0: var yComponent = 2; break;
case 1: var yComponent = 1; break;
}
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
jscolor.picker.sldM.style.backgroundPosition =
'0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
}
function isPickerOwner() {
return jscolor.picker && jscolor.picker.owner === THIS;
}
function blurTarget() {
if(valueElement === target) {
THIS.importColor();
}
if(THIS.pickerOnfocus) {
THIS.hidePicker();
}
}
function blurValue() {
if(valueElement !== target) {
THIS.importColor();
}
}
function setPad(e) {
var mpos = jscolor.getRelMousePos(e);
var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
}
}
function setSld(e) {
var mpos = jscolor.getRelMousePos(e);
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
}
}
function dispatchImmediateChange() {
if (THIS.onImmediateChange) {
var callback;
if (typeof THIS.onImmediateChange === 'string') {
callback = new Function (THIS.onImmediateChange);
} else {
callback = THIS.onImmediateChange;
}
callback.call(THIS);
}
}
var THIS = this;
var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
var abortBlur = false;
var
valueElement = jscolor.fetchElement(this.valueElement),
styleElement = jscolor.fetchElement(this.styleElement);
var
holdPad = false,
holdSld = false;
var
leaveValue = 1<<0,
leaveStyle = 1<<1,
leavePad = 1<<2,
leaveSld = 1<<3;
// target
jscolor.addEvent(target, 'focus', function() {
if(THIS.pickerOnfocus) { THIS.showPicker(); }
});
jscolor.addEvent(target, 'blur', function() {
if(!abortBlur) {
window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
} else {
abortBlur = false;
}
});
// valueElement
if(valueElement) {
var updateField = function() {
THIS.fromString(valueElement.value, leaveValue);
dispatchImmediateChange();
};
jscolor.addEvent(valueElement, 'keyup', updateField);
jscolor.addEvent(valueElement, 'input', updateField);
jscolor.addEvent(valueElement, 'blur', blurValue);
valueElement.setAttribute('autocomplete', 'off');
}
// styleElement
if(styleElement) {
styleElement.jscStyle = {
backgroundImage : styleElement.style.backgroundImage,
backgroundColor : styleElement.style.backgroundColor,
color : styleElement.style.color
};
}
// require images
switch(modeID) {
case 0: jscolor.requireImage('hs.png'); break;
case 1: jscolor.requireImage('hv.png'); break;
}
jscolor.requireImage('cross.gif');
jscolor.requireImage('arrow.gif');
this.importColor();
}
};
jscolor.install();

0
system/Widget/widgets/Config/config.css

104
system/Widget/widgets/ConfigData/ConfigData.php

@ -1,104 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ConfigData extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('configdata.css');
}
function ajaxClearRosterLink() {
$rd = new \modl\RosterLinkDAO();
$rd->clearRosterLink();
$this->refresh();
}
function ajaxClearMessage() {
$md = new \modl\MessageDAO();
$md->clearMessage();
$this->refresh();
}
function ajaxClearPost() {
$pd = new \modl\PostnDAO();
$pd->clearPost();
$this->refresh();
}
function refresh() {
$html = $this->prepareConfigData();
RPC::call('movim_fill', 'configdata', $html);
RPC::commit();
}
function prepareConfigData() {
$cd = new \modl\ContactDAO();
$stats = $cd->getStatistics();
$clearrosterlink = $this->genCallAjax('ajaxClearRosterLink');
$clearmessage = $this->genCallAjax('ajaxClearMessage');
$clearpost = $this->genCallAjax('ajaxClearPost');
$html = '
<form enctype="multipart/form-data" method="post" action="index.php" name="general">
<fieldset>
<legend>'.t('Cache').'</legend>
<div class="clear"></div>
<div class="element thin">
<label for="name">'.t('Post'). ' - '.$stats['Post'].'</label><br />
<a
type="button"
name="email"
class="button icon back"
onclick="'.$clearpost.'">'.t('Clear').'</a>
</div>
<div class="element thin">
<label for="name">'.t('Messages'). ' - '.$stats['Message'].'</label><br />
<a
type="button"
name="email"
class="button icon back"
onclick="'.$clearmessage.'">'.t('Clear').'</a>
</div>
<div class="element thin">
<label for="name">'.t('Contacts'). ' - '.$stats['RosterLink'].'</label><br />
<a
type="button"
class="button icon back"
onclick="'.$clearrosterlink.'">'.t('Clear').'</a>
</div>
</fieldset>
</form>';
return $html;
}
function build()
{
?>
<div class="tabelem padded" title="<?php echo t('Data'); ?>" id="configdata" >
<?php echo $this->prepareConfigData(); ?>
</div>
<?php
}
}

0
system/Widget/widgets/ConfigData/configdata.css

143
system/Widget/widgets/ContactCard/ContactCard.php

@ -1,143 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactCard extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('contactcard.css');
$this->registerEvent('vcard', 'onVcard');
}
function onVcard($contact)
{
$html = $this->prepareContactCard($contact);
RPC::call('movim_fill', 'contactcard', $html);
}
function prepareContactCard($contact)
{
$gender = getGender();
$marital = getMarital();
$html .= '
<form name="vcard" id="vcardform"><br />
<h1>'.t('Profile').'</h1><br />
<fieldset>
<legend>'.t('General Informations').'</legend>';
if($this->testIsSet($contact->fn))
$html .= '<div class="element simple">
<label for="fn">'.t('Name').'</label>
<span>'.$contact->fn.'</span>
</div>';
if($this->testIsSet($contact->name))
$html .= '<div class="element simple">
<label for="name">'.t('Nickname').'</label>
<span>'.$contact->name.'</span>
</div>';
if(
$contact->date != '0000-00-00'
&& $contact->date != '1970-01-01'
&& $this->testIsSet($contact->date))
$html .= '<div class="element simple">
<label for="day">'.t('Date of Birth').'</label>
<span>'.date('j M Y',strtotime($contact->date)).'</span>
</div>';
if($contact->gender != 'N' && $this->testIsSet($contact->gender))
$html .= '<div class="element simple">
<label for="gender">'.t('Gender').'</label>
<span>'.$gender[$contact->gender].'</span>
</div>';
if($contact->marital != 'none' && $this->testIsSet($contact->marital))
$html .= '<div class="element simple">
<label for="marital">'.t('Marital Status').'</label>
<span>'.$marital[$contact->marital].'</span>
</div>';
if($this->testIsSet($contact->email))
$html .= '<div class="element simple">
<label for="url">'.t('Email').'</label>
<a target="_blank" href="mailto:'.$contact->email.'">'.$contact->email.'</a>
</div>';
if($this->testIsSet($contact->url))
$html .= '<div class="element simple">
<label for="url">'.t('Website').'</label>
<a target="_blank" href="'.$contact->url.'">'.$contact->url.'</a>
</div>';
if($this->testIsSet($contact->desc) && prepareString($contact->desc) != '')
$html .= '<div class="element large simple">
<label for="desc">'.t('About Me').'</label>
<span>'.prepareString($contact->desc).'</span>
</div>';
if($this->testIsSet($contact->adrlocality) ||
$this->testIsSet($contact->adrcountry)) {
$html .= '</fieldset>
<br />
<fieldset>
<legend>'.t('Geographic Position').'</legend>';
if($this->testIsSet($contact->adrlocality)) {
$locality .= '<div class="element simple">
<label for="desc">'.t('Locality').'</label>
<span>'.$contact->adrlocality;
if($contact->adrpostalcode != 0)
$locality .= ' ('.$contact->adrpostalcode.')';
$locality .= '</span>
</div>';
$html .= $locality;
}
if($this->testIsSet($contact->adrcountry))
$html .= '<div class="element simple">
<label for="desc">'.t('Country').'</label>
<span>'.$contact->adrcountry.'</span>
</div>';
}
$html .= '</fieldset>
<div class="config_button" onclick="'.$this->genCallWidget("ContactSummary","ajaxRefreshVcard", "'".$contact->jid."'").'"></div>
</form>';
return $html;
}
function build()
{
$cd = new modl\ContactDAO();
$contact = $cd->get($_GET['f']);
?>
<div class="tabelem protect red" title="<?php echo t('Profile'); ?>" id="contactcard" >
<?php
if(isset($contact))
echo $this->prepareContactCard($contact);
?>
</div>
<?php
}
}

8
system/Widget/widgets/ContactCard/contactcard.css

@ -1,8 +0,0 @@
#contactcard {
padding: 0px 1.5em;
}
#contactcard h1 {
padding: 0px;
padding-bottom: 20px;
}

212
system/Widget/widgets/ContactInfo/ContactInfo.php

@ -1,212 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactInfo extends WidgetCommon
{
function WidgetLoad() {
}
function ajaxRemoveContact($jid) {
$r = new moxl\RosterRemoveItem();
$r->setTo($jid)
->request();
$p = new moxl\PresenceUnsubscribe();
$p->setTo($jid)
->request();
}
function prepareContactInfo()
{
$cd = new \modl\ContactDAO();
$c = $cd->getRosterItem($_GET['f']);
$html = '';
if(isset($c)) {
// Mood
if($c->mood) {
$moodarray = getMood();
$html .= '<h2>'.t('Mood').'</h2>';
$mood = '';
foreach(unserialize($c->mood) as $m)
$mood .= $moodarray[$m].',';
$html .= t("I'm ").substr($mood, 0, -1).'<br />';
}
if($c->tuneartist || $c->tunetitle) {
$html .= '<h2>'.t('Listening').'</h2>';
if($c->tuneartist)
$artist = $c->tuneartist. ' - ';
if($c->tunetitle)
$title = $c->tunetitle;
if($c->tunesource)
$album = t('on').' '.$c->tunesource;
$html .= $artist.$title.' '.$album;
}
// Last seen
if($c->delay && $c->delay != '0000-00-00 00:00:00') {
$html .= '<h2>'.t('Last seen').'</h2>';
$html .= prepareDate(strtotime($c->delay)).'<br />';
}
if($c->loclatitude != '' && $c->loclongitude != ''
|| $c->getPlace() != '') {
$html .= '
<h2>'.t('Location').'</h2>';
$html .= prepareDate(strtotime($c->loctimestamp)).'<br /><br />';
if($c->getPlace() != '')
$html .= $c->getPlace().'<br /><br />';
if(isset($c->loclatitude) && isset($c->loclongitude))
$html .= '
<div style="height: 250px;" id="map"></div>
<script type="text/javascript">
var map = L.map("map").setView(['.$c->loclatitude.' ,'.$c->loclongitude.'], 11);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "",
maxZoom: 18
}).addTo(map);
var marker = L.marker(['.$c->loclatitude.' ,'.$c->loclongitude.']).addTo(map)
</script>';
}
// Client informations
if($c->node && $c->ver) {
$node = $c->node.'#'.$c->ver;
$cad = new \modl\CapsDAO();
$caps = $cad->get($node);
$clienttype =
array(
'bot' => t('Bot'),
'pc' => t('Desktop'),
'phone' => t('Phone'),
'handheld' => t('Phone'),
'web' => t('Web'),
);
if(isset($caps) && $caps->name != '' && $caps->type != '' ) {
$cinfos = '';
$cinfos .= $caps->name.' ('.$clienttype[$caps->type].')<br />';
$html .='<h2>'.t('Client Informations').'</h2>' . $cinfos;
}
}
// Chat button
if($c->jid != $this->user->getLogin()) {
$presences = getPresences();
$html .='<h2>'.t('Actions').'</h2>';
if(isset($c->presence) && !in_array($c->presence, array(5, 6))) {
$html .= '
<a
class="button tiny icon chat"
href="#"
style="float: left;"
id="friendchat"
onclick="'.$this->genCallWidget("Chat","ajaxOpenTalk", "'".$c->jid."'").'"
>
'.$presences[$c->presence].' - '.t('Chat').'
</a>';
}
}
$html .= '<div style="clear: both;"></div>';
$html .='
<a
class=""
href="#"
style="margin: 10px 0px; display: block;"
id="friendremoveask"
onclick="
document.querySelector(\'#friendremoveyes\').style.display = \'block\';
document.querySelector(\'#friendremoveno\').style.display = \'block\';
this.style.display = \'none\'
"
>
'.t('Remove this contact').'
</a>
<a
class="button tiny icon yes merged left';
if(!isset($c->presence) || $c->presence == 5)
$html .=' left';
$html .= '"
href="#"
id="friendremoveyes"
style="float: left; display: none;"
onclick="'.$this->genCallAjax("ajaxRemoveContact", "'".$_GET['f']."'")
. 'this.className=\'button tiny icon loading merged left\'; setTimeout(function() {location.reload(false)}, 2000);"
>
'.t('Yes').'
</a>
<a
class="button tiny icon no merged right"
href="#"
style="float: left; display: none;"
id="friendremoveno"
onclick="
document.querySelector(\'#friendremoveask\').style.display = \'block\';
document.querySelector(\'#friendremoveyes\').style.display = \'none\';
this.style.display = \'none\'
"
>
'.t('No').'
</a>';
} elseif($_GET['f'] != $this->user->getLogin()) {
$html .='<h2>'.t('Actions').'</h2>';
$html .='
<a
class="button tiny icon add"
href="#"
onclick="'.$this->genCallWidget("Roster","ajaxAddContact", "'".$_GET['f']."'", "''")
. 'this.className=\'button tiny icon loading merged left\'; setTimeout(function() {location.reload(false)}, 2000);"
>
'.t('Invite this user').'
</a>';
}
return $html;
}
function build() {
echo $this->prepareContactInfo();
}
}

83
system/Widget/widgets/ContactManage/ContactManage.php

@ -1,83 +0,0 @@
<?php
/**
* @package Widgets
*
* @file ContactManage.php
* This file is part of MOVIM.
*
* @brief A little widget which manage the current contact
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2013 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactManage extends WidgetCommon
{
function WidgetLoad() {
}
public function ajaxContactManage($form) {
$rd = new \moxl\RosterUpdateItem();
$rd->setTo(echapJid($form['jid']))
->setName(htmlspecialchars($form['alias']))
->setGroup(htmlspecialchars($form['group']))
->request();
Notification::appendNotification(t('Contact updated'));
}
private function prepareContactManage($jid) {
$rd = new \modl\RosterLinkDAO();
$groups = $rd->getGroups();
$rl = $rd->get($jid);
$submit = $this->genCallAjax('ajaxContactManage', "movim_parse_form('manage')");
$html = '';
$html .= '<h2>'.t('Manage').'</h2>';
$html .= '
<form name="manage">';
$ghtml = '';
foreach($groups as $g)
$ghtml .= '<option value="'.$g.'"/>';
$html .= '
<input type="hidden" name="jid" value="'.$jid.'"/>
<div class="element large mini">
<input name="alias" id="alias" class="tiny" placeholder="'.t('Alias').'" value="'.$rl->rostername.'"/>
</div>
<div class="element large mini">
<datalist id="group" style="display: none;">
'.$ghtml.'
</datalist>
<input name="group" list="group" id="alias" class="tiny" placeholder="'.t('Group').'" value="'.$rl->group.'"/>
</div>
<a class="button tiny icon yes" onclick="'.$submit.'">'.t('Save').'</a>';
$html .= '
</form>';
return $html;
}
function build() {
?>
<div class="clear"></div>
<?php
if($_GET['f'] != $this->user->getLogin())
echo $this->prepareContactManage($_GET['f']);
}
}

75
system/Widget/widgets/ContactPubsubSubscription/ContactPubsubSubscription.php

@ -1,75 +0,0 @@
<?php
/**
* @package Widgets
*
* @file ContactPubsubSubscription.php
* This file is part of MOVIM.
*
* @brief The Group configuration widget
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactPubsubSubscription extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('groupsubscribedlist', 'onGroupSubscribedList');
$this->registerEvent('groupsubscribedlisterror', 'onGroupSubscribedListError');
}
function prepareList($list) {
if(is_array($list[0])){
$html = '<ul class="list">';
foreach($list as $item){
$html .= '<li><a href="?q=node&s='.$item[1].'&n='.$item[0].'">'.$item[2].'</a></li>';
}
$html .= '</ul>';
return $html;
}
Notification::appendNotification(t('No public groups found'), 'info');
}
function onGroupSubscribedList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'publicgroups', $html);
}
function onGroupSubscribedListError($error)
{
Notification::appendNotification($error, 'error');
}
function ajaxGetGroupSubscribedList($to){
$r = new moxl\PubsubSubscriptionListGetFriends();
$r->setTo($to)->request();
}
function build()
{
?>
<div class="tabelem padded protect red" title="<?php echo t('Public groups'); ?>" id="groupsubscribedlistfromfriend">
<a
class="button icon yes"
onclick="<?php echo $this->genCallAjax('ajaxGetGroupSubscribedList', "'".$_GET['f']."'"); ?> this.style.display = 'none'">
<?php echo t("Get public groups");?>
</a>
<div id="publicgroups"></div>
</div>
<?php
}
}
?>

121
system/Widget/widgets/ContactSummary/ContactSummary.php

@ -1,121 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactSummary extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('contactsummary.css');
$this->registerEvent('vcard', 'onVcard');
}
function onVcard($contact)
{
$html = $this->prepareContactSummary($contact);
RPC::call('movim_fill', 'contactsummary', $html);
}
function ajaxRefreshVcard($jid)
{
$r = new moxl\VcardGet();
$r->setTo($jid)->request();
}
function prepareContactSummary($contact)
{
$gender = getGender();
$marital = getMarital();
// Contact avatar
$html .= '
<div class="block avatar">
<img src="'.$contact->getPhoto('l').'"/>
</div>';
$presencetxt = getPresencesTxt();
// Contact general infos
$html .= '
<div class="block">
<h1 class="'.$presencetxt[$contact->presence].'">'.$contact->getTrueName().'</h1><br />';
if($this->testIsSet($contact->name))
$html .= $contact->name.' ';
else
$html .= $contact->getTrueName().' ';
if($this->testIsSet($contact->url))
$html .= '<br /><a target="_blank" href="'.$contact->url.'">'.$contact->url.'</a>';
$html .= '<br /><br />
</div>';
if($this->testIsSet($contact->status)) {
$html .= '
<div
class="block"
style="
max-height: 7em;
margin: 1em;
min-height: auto;
overflow: hidden;
text-overflow: ellipsis;"
>';
$html .= '
<div class="textbubble">
'.prepareString($contact->status).'
</div>';
$html .= '
</div>';
}
return $html;
}
function build()
{
$cd = new modl\ContactDAO();
if($_GET['f'] == $this->user->getLogin())
$contact = $cd->get($this->user->getLogin());
else
$contact = $cd->getRosterItem($_GET['f']);
if(!isset($contact))
$contact = $cd->get($_GET['f']);
?>
<div id="contactsummary">
<?php
if(isset($contact->photobin)) {
echo $this->prepareContactSummary($contact);
}
else {
$contact = new modl\Contact();
echo $this->prepareContactSummary($contact);
?>
<script type="text/javascript">setTimeout("<?php $this->callAjax('ajaxRefreshVcard', "'".$_GET['f']."'");?>", 1000);</script>
<?php } ?>
</div>
<?php
}
}

1
system/Widget/widgets/ContactSummary/contactsummary.css

@ -1 +0,0 @@

160
system/Widget/widgets/Explore/Explore.php

@ -1,160 +0,0 @@
<?php
class Explore extends WidgetCommon {
function WidgetLoad()
{
$this->addcss('explore.css');
}
function ajaxSearchContacts($form) {
$html = $this->prepareContacts($form);
RPC::call('movim_fill', 'contactsresult', $html);
RPC::commit();
}
function colorSearch($search, $text) {
return str_replace(
$search,
'<span style="background-color: yellow;">'.$search.'</span>',
$text
);
}
function prepareServers() {
$nd = new \modl\NodeDAO();
$servers = $nd->getServers();
$html = '<ul class="list">';
foreach($servers as $s) {
$html .= '
<li>
<a href="'.Route::urlize('server', $s->serverid).'">'.
$s->serverid. '
<span class="tag">'.$s->number.'</span>
</a>
</li>';
}
$html .= '</ul>';
return $html;
//var_dump($nd->getServers());
}
function prepareContacts($form = false) {
/*if(!$form){
$where = array('public' => 1);
}
else{
$where = array(
'public' => 1,
array(
'fn%' => '%'.$form['search'].'%',
'|jid%' => '%'.$form['search'].'%',
'|name%' => '%'.$form['search'].'%',
'|email%' => '%'.$form['search'].'%',
'|nickname%' => '%'.$form['search'].'%'
)
);
}
$users_limit = 20;
$gender = getGender();
$marital = getMarital();
$query = Contact::query()->select()
->where($where)
//s->orderby('id', true)
->limit(0, $users_limit);
$users = Contact::run_query($query);
$html = '
<div class="posthead">
<!--<ul class="filters">
<li class="on">'.t('Last registered').'</li>
</ul>-->
<div class="clear"></div>
</div>';*/
$cd = new \modl\ContactDAO();
$users = array_reverse($cd->getAllPublic());
$gender = getGender();
$marital = getMarital();
foreach($users as $user) {
$html .= '
<div class="post">
<a href="?q=friend&f='.$user->jid.'">
<img class="avatar" src="'.$user->getPhoto('m').'"/>
<div class="postbubble">
<span class="name">'.
$user->getTrueName().'
</span>
<span class="asv">'.
$user->getAge().' '.
$gender[$user->gender].' '.
$marital[$user->marital].'
</span>
<div
class="content"
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 1.5em;
"
>'.prepareString($user->desc).'</div>
</div>
</a>
</div>
';
}
return $html;
}
function build()
{
?>
<div id="explore">
<!--<form name="searchform" style="margin: 1em 1.5em;" onsubmit="event.preventDefault();">
<div class="element" style="min-height: 0em;">
<input
id="addjid"
class="tiny"
name="search"
placeholder="<?php echo t('Search a contact'); ?>"
onkeypress="if(event.keyCode==13){<?php $this->callAjax("ajaxSearchContacts","movim_parse_form('searchform')"); ?>}"
/>
</div>
<div class="element" style="min-height: 0em; margin-top: 5px;">
<a
class="button icon submit"
href="#"
onclick="<?php $this->callAjax("ajaxSearchContacts","movim_parse_form('searchform')"); ?> "
style="">
<?php echo t('Search'); ?>
</a>
</div>
</form>-->
<div id="serverresult" class="paddedtop">
<h2><?php echo t('Discussion Servers'); ?></h2>
<?php echo $this->prepareServers(); ?>
</div>
<div class="paddedtopbottom">
<h2><?php echo t('Last registered'); ?></h2>
</div>
<div id="contactsresult">
<?php echo $this->prepareContacts(); ?>
</div>
</div>
<?php
}
}

4
system/Widget/widgets/Explore/explore.css

@ -1,4 +0,0 @@
#explore {
margin-bottom: 2em;
min-height: 600px;
}

213
system/Widget/widgets/Feed/Feed.php

@ -1,213 +0,0 @@
<?php
class Feed extends WidgetCommon {
private $_feedsize = 10;
function WidgetLoad()
{
$this->addcss('feed.css');
$this->addjs('feed.js');
$this->registerEvent('post', 'onStream');
$this->registerEvent('postdeleted', 'onPostDelete');
$this->registerEvent('postdeleteerror', 'onPostDeleteError');
$this->registerEvent('comment', 'onComment');
$this->registerEvent('nocomment', 'onNoComment');
$this->registerEvent('nocommentstream', 'onNoCommentStream');
$this->registerEvent('commentpublisherror', 'onCommentPublishError');
$this->registerEvent('stream', 'onStream');
$this->registerEvent('postpublished', 'onPostPublished');
$this->registerEvent('postpublisherror', 'onPostPublishError');
$this->registerEvent('nodecreated', 'onNodeCreated');
$this->registerEvent('nodecreationerror', 'onNodeCreationError');
$this->registerEvent('config', 'onConfig');
$this->cached = false;
}
function onConfig(array $data)
{
$this->user->setConfig($data);
RPC::call('movim_fill', 'feedhead', $this->prepareHead());
}
function onNodeCreated() {
$config = $this->user->getConfig();
$config['feed'] = 'created';
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($config))
->request();
}
function onNodeCreationError() {
$config = $this->user->getConfig();
$config['feed'] = 'error';
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($config))
->request();
Notification::appendNotification(
t("Your server doesn't support post publication, you can only read contact's feeds"),
'error');
}
function onCommentPublishError() {
$html =
'<div class="message error">'.
t("Comment publication error").'
</div>';
RPC::call('movim_fill', 'feednotifs', $html);
}
function onPostPublished($post) {
$pd = new \modl\PostnDAO();
$pl = $pd->getFeed(-1, $this->_feedsize);
$html = $this->preparePosts($pl);
RPC::call('createCommentNode', $post->nodeid);
RPC::call('movim_fill', 'feedcontent', $html);
}
function ajaxCreateCommentNode($parentid) {
$n = new moxl\MicroblogCommentCreateNode();
$n->setTo($this->user->getLogin())
->setParentId($parentid)
->request();
}
function onPostPublishError($error) {
Notification::appendNotification(t('An error occured : ').$error, 'error');
}
function prepareHead() {
$html = '';
global $session;
if($session['config']['config'] == false) {
$html .=
'<div class="message warning" style="margin: 1.5em;">'.
t("Your server doesn't support post publication, you can only read contact's feeds").
'</div>';
} elseif(!isset($session['config']['feed'])) {
$html .= '
<div id="feednotifs">
<div class="message info">'.
t("Creating your feed...").
'</div>
</div>
<script type="text/javascript">'.
$this->genCallAjax('ajaxCreateNode').
'</script>';
} else {
$html .= '
<script type="text/javascript">
function createCommentNode(parentid) {'.
$this->genCallAjax('ajaxCreateCommentNode', 'parentid[0]').
'}
</script>
'.$this->prepareSubmitForm($this->user->getLogin(), 'urn:xmpp:microblog:0').'
<div id="feednotifs"></div>';
}
return $html;
}
function prepareFeed($start) {
$pd = new \modl\PostnDAO();
$pl = $pd->getFeed($start+1, $this->_feedsize);
$html = $this->preparePosts($pl);
// We ask for the HTML of all the posts
$next = $start + $this->_feedsize;
if(sizeof($pl) > $this->_feedsize-1 && $html != '') {
$html .= '
<div class="post">
<div
class="older"
onclick="'.$this->genCallAjax('ajaxGetFeed', "'".$next."'").'; this.parentNode.style.display = \'none\'">'.
t('Get older posts').'
</div>
</div>';
}
return $html;
}
function ajaxGetFeed($start) {
$html = $this->prepareFeed($start);
RPC::call('movim_append', 'feedcontent', $html);
RPC::commit();
}
function onStream($payload) {
$html = '';
$html = $this->prepareFeed(-1);
if($html == '')
$html = '
<div class="message info" style="margin: 1.5em; margin-top: 0em;">'.
t("Your feed cannot be loaded.").'
</div>';
RPC::call('movim_fill', 'feedcontent', $html);
RPC::commit();
}
function ajaxCreateNode()
{
$p = new moxl\MicroblogCreateNode();
$p->setTo($this->user->getLogin())
->request();
}
function build()
{
?>
<div class="tabelem" title="<?php echo t('Feed'); ?>" id="feed">
<div id="feedhead">
<?php
echo $this->prepareHead();
?>
</div>
<div class="posthead">
<a
class="button tiny icon blog merged left"
href="<?php echo Route::urlize('blog',$this->user->getLogin()); ?>"
target="_blank">
<?php echo t('Blog'); ?>
</a><a
class="button tiny icon feed merged right"
href="<?php echo Route::urlize('feed',$this->user->getLogin()); ?>"
target="_blank">
<?php echo t('Feed'); ?> (Atom)
</a>
<ul class="filters">
<li class="on" onclick="showPosts(this, false);"><?php echo t('All');?></li>
<li onclick="showPosts(this, true);"><?php echo t('My Posts');?></li>
</ul>
</div>
<div id="feedcontent">
<?php
echo $this->prepareFeed(-1);
?>
</div>
</div>
<?php
}
}

1
system/Widget/widgets/Feed/feed.css

@ -1 +0,0 @@

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save