mirror of
https://github.com/YunoHost-Apps/movim_ynh.git
synced 2024-09-03 19:46:19 +02:00
update movim upstream
This commit is contained in:
parent
fd4dbff608
commit
48b740e51c
2416 changed files with 143837 additions and 11 deletions
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
1.7 2016-?
|
1.7 2016-?
|
||||||
- Update to movim 0.9 git2016-03-14
|
- Update to movim 0.9 git2016-03-14
|
||||||
- Php composer stuff is now shipped in the package
|
|
||||||
- conf/nginx.conf : disable the Yunohost logo
|
- conf/nginx.conf : disable the Yunohost logo
|
||||||
- script/install : comment (disable) php composer stuff
|
|
||||||
- script/upgrade : comment (disable) php composer stuff
|
|
||||||
|
|
||||||
1.6.1 2016-02-12
|
1.6.1 2016-02-12
|
||||||
- Update to movim 0.9 git2016-01-27
|
- Update to movim 0.9 git2016-01-27
|
||||||
|
|
|
@ -80,10 +80,9 @@ sudo chown -R movim:www-data $final_path
|
||||||
sudo chmod -R 750 $final_path
|
sudo chmod -R 750 $final_path
|
||||||
|
|
||||||
# Install PHP dependencies
|
# Install PHP dependencies
|
||||||
# This is not necessary anymore, movim_ynh ships everything
|
sudo su -c "curl -sS https://getcomposer.org/installer | php -- --install-dir=$final_path" movim
|
||||||
#sudo su -c "curl -sS https://getcomposer.org/installer | php -- --install-dir=$final_path" movim
|
sudo su -c "cd $final_path && php composer.phar config --global discard-changes true" movim # auto yes
|
||||||
#sudo su -c "cd $final_path && php composer.phar config --global discard-changes true" movim # auto yes
|
sudo su -c "cd $final_path && php composer.phar install -n" movim # install + quiet mode
|
||||||
#sudo su -c "cd $final_path && php composer.phar install -n" movim # install + quiet mode
|
|
||||||
|
|
||||||
# Movim configuration
|
# Movim configuration
|
||||||
sudo sed -i "s@'username' => 'username'@'username' => '$db_user'@g" $final_path/config/db.inc.php
|
sudo sed -i "s@'username' => 'username'@'username' => '$db_user'@g" $final_path/config/db.inc.php
|
||||||
|
|
|
@ -32,10 +32,9 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update PHP dependencies
|
# Update PHP dependencies
|
||||||
# Not necessary anymore, shipped with movim_ynh
|
sudo su -c "cd $final_path && rm composer.lock"
|
||||||
#sudo su -c "cd $final_path && rm composer.lock"
|
sudo su -c "cd $final_path && php composer.phar config --global discard-changes true" movim
|
||||||
#sudo su -c "cd $final_path && php composer.phar config --global discard-changes true" movim
|
sudo su -c "cd $final_path && php composer.phar install -n" movim
|
||||||
#sudo su -c "cd $final_path && php composer.phar install -n" movim
|
|
||||||
|
|
||||||
# Movim configuration
|
# Movim configuration
|
||||||
sudo sed -i "s@/ws/@$path/ws/@g" $final_path/app/assets/js/movim_websocket.js
|
sudo sed -i "s@/ws/@$path/ws/@g" $final_path/app/assets/js/movim_websocket.js
|
||||||
|
|
276
sources/CHANGELOG.md
Normal file
276
sources/CHANGELOG.md
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
Movim Changelog
|
||||||
|
================
|
||||||
|
|
||||||
|
v0.9.1 (trunk)
|
||||||
|
---------------------------
|
||||||
|
* CSS fixes
|
||||||
|
* Add Last Message Edition support
|
||||||
|
* Improve Post discovery in the News page
|
||||||
|
* Add stickers support
|
||||||
|
* Improve loading time for Chat page
|
||||||
|
* Improve Chat bubbles display
|
||||||
|
* New compact date display
|
||||||
|
* Clean properly the tags in the database
|
||||||
|
* Allow tags with special characters
|
||||||
|
* Various UI and navigation fixed
|
||||||
|
* Update the dependencies
|
||||||
|
|
||||||
|
v0.9
|
||||||
|
---------------------------
|
||||||
|
* New User Interface for the whole project
|
||||||
|
* Removed BOSH connections and introduce pure XMPP TLS connections
|
||||||
|
* Full real-time + daemon
|
||||||
|
* New Blog engine and custom CSS support
|
||||||
|
* New post publication system + attachements supported (upload and embed links)
|
||||||
|
* Fully responsive design UI based on Material Design
|
||||||
|
* Huge code cleanup and refactoring
|
||||||
|
* Updated i18n system and new languages
|
||||||
|
* New eventing system
|
||||||
|
* New administration panel
|
||||||
|
* New dedicated chat page and emojis support
|
||||||
|
* New project icon and favicon
|
||||||
|
* New implementation for the Groups feature
|
||||||
|
* New Roster based on Angular
|
||||||
|
* Refactor the Contact management system and add a gallery on the profiles
|
||||||
|
* New universal-share bookmarklet
|
||||||
|
* CSS animations and mobile integration (FirefoxOS and Android)
|
||||||
|
* Internet Explorer 11 support
|
||||||
|
* PHP7 Support
|
||||||
|
|
||||||
|
v0.8.1
|
||||||
|
---------------------------
|
||||||
|
* Add charts in the Statistics
|
||||||
|
* Add a Caps support table
|
||||||
|
* Fix some Jingle issues
|
||||||
|
* New Mud actions to create/update the database and change the administration configuration
|
||||||
|
* New InitAccount widget to create persistent PEP node on the first login
|
||||||
|
* Clean the Feed widget
|
||||||
|
* Fix various CSS bugs + fix mobile UI
|
||||||
|
* Add title attribute to some truncated texts
|
||||||
|
* Add a new fancy login system
|
||||||
|
* Show the status in the Roster
|
||||||
|
* Optimize the Presence handling
|
||||||
|
* Improve the MUC presence handling
|
||||||
|
* Improve the posts CSS
|
||||||
|
* Add a fancy XEP visualisator
|
||||||
|
|
||||||
|
v0.8.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Refactor the whole Movim sourcecode + clean old code
|
||||||
|
* Quite all the Movim widgets are now using a full MVC system
|
||||||
|
* Rewrite the core session manager (Sessionx)
|
||||||
|
* Add a new localisation system + new translations
|
||||||
|
* Move the Movim librairies and dependencies to Composer and convert Modl and Moxl to PSR-0 to simplify the loading and packaging of the libraries
|
||||||
|
* Monolog is now the new log library for Movim
|
||||||
|
* Lots of warnings fixed
|
||||||
|
* Add WebRTC threw Jingle audio-video conferencing
|
||||||
|
* Make the UI fully responsible (from smartphone to FullHD screens)
|
||||||
|
* The Roster widget has been totally rewriten
|
||||||
|
* New picture library manager (with new thumbnail generation system)
|
||||||
|
* Better MUC integration in the Chat widget
|
||||||
|
* Rich text messages are now supported in the Chat widget
|
||||||
|
* Add Vcard4 (http://xmpp.org/extensions/xep-0292.html) support in the profile
|
||||||
|
* Implement the new official Movim API (https://api.movim.eu/)
|
||||||
|
* Huge sourcecode optimisation
|
||||||
|
* Rewrite the Administration panel and split it in many little widgets
|
||||||
|
* Move the full configuration system to the database (except the database credentials)
|
||||||
|
* List all the Movim network pods on a new page
|
||||||
|
* Move the all UI to OpenSans
|
||||||
|
* Add Title support during post publication
|
||||||
|
* New statistics page for the administrators
|
||||||
|
* Rewrite the infos page and move it to a widget, move the data structure from XML to JSON
|
||||||
|
* Use SASL2 library (https://github.com/edhelas/sasl2) for the XMPP authentication and add SCRAM-SHA1 mechanism support
|
||||||
|
* Split the Profile form in 3 littles forms (general, avatar and localisation)
|
||||||
|
* Rewrite the Explore page
|
||||||
|
* Move from XML to JSON for the browser-server requests
|
||||||
|
* Update the locales
|
||||||
|
|
||||||
|
v0.7.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Rewrite Modl to Modl2 with dynamic database update, PDO support (MySQL and PostgreSQL)
|
||||||
|
* Add support of XEP-0084: User Avatar
|
||||||
|
* Bug fixes in chatroom
|
||||||
|
* Complete rewrite f the bookmark/subscription system
|
||||||
|
* Huge code optimisation (x10 of some parts)
|
||||||
|
* CSS fixes
|
||||||
|
* Fix lot of issues on the groups (add youtube video support) + microblog
|
||||||
|
* Add a new log system
|
||||||
|
* Various minor bug fixed
|
||||||
|
|
||||||
|
v0.7.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Huge speed optimisation
|
||||||
|
* Fux UI fix
|
||||||
|
* Implement picute insertion in posts
|
||||||
|
* Chat fix
|
||||||
|
* Smiley updated
|
||||||
|
|
||||||
|
v0.7.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Media hosting and implementation (picture) @edhelas
|
||||||
|
* Group implementation @edhelas @nodpounod
|
||||||
|
* Datajar to Modl (https://github.com/edhelas/modl) portage @edhelas
|
||||||
|
* Video + picture integration (gallery preview) @edhelas
|
||||||
|
* Admin panel with hosting space administration @edhelas
|
||||||
|
* URL rewriting @edhelas
|
||||||
|
* Multi User Chat @edhelas
|
||||||
|
|
||||||
|
v0.6.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Fix SSL certificate problem
|
||||||
|
|
||||||
|
v0.6.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Create a new installer @kilian @edhelas
|
||||||
|
* Create admin user interface to change conf.xml @edhelas
|
||||||
|
* Improved user experience @edhelas
|
||||||
|
|
||||||
|
### Core @edhelas ###
|
||||||
|
|
||||||
|
* 100% Moxl integration
|
||||||
|
* Add Moxl support to build.sh
|
||||||
|
|
||||||
|
### Widgets @edhelas ###
|
||||||
|
|
||||||
|
#### Chat ####
|
||||||
|
|
||||||
|
* Support “user is typing”
|
||||||
|
|
||||||
|
#### Roster ####
|
||||||
|
|
||||||
|
* bidirectional friendrequests. Users can always see each other
|
||||||
|
* little search box to filter the list (nodpounod)
|
||||||
|
|
||||||
|
#### Post ####
|
||||||
|
|
||||||
|
* http://xmpp.org/extensions/xep-0071.html some basic WYSIWYG
|
||||||
|
* Provide public/private posts
|
||||||
|
|
||||||
|
### Datajar ###
|
||||||
|
|
||||||
|
* Support updating of db-schemas.
|
||||||
|
|
||||||
|
### Translations ###
|
||||||
|
|
||||||
|
* Pull new translations automaticly into trunk
|
||||||
|
* Add new translations
|
||||||
|
|
||||||
|
### Moxl ###
|
||||||
|
* Support of the XEP-0115 Entity Capabilities, which enables the client to communicate its features and the extent of its XMPP support to the server
|
||||||
|
* Implementation of DIGEST-MD5 and CRAM-MD5 as more secure log-in mechanisms
|
||||||
|
|
||||||
|
v0.5.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Parse all the Movim messages to make them more “user-friendly” (smileys, links, bb-code like) @Etenil
|
||||||
|
* DONE Make a public XML page reporting on the pod status (how many user hosted, version, current status…), to be pinged from pod.movim.eu @edhelas
|
||||||
|
* Move DataJar based Classes into a single folder @edhelas
|
||||||
|
* Cleaner CSS @edhelas
|
||||||
|
* Update dates (like “2 min ago”) automatically @edhelas
|
||||||
|
* Clean and move UserConf in a single class @edhelas
|
||||||
|
* New UI @edhelas
|
||||||
|
|
||||||
|
### Core ###
|
||||||
|
|
||||||
|
* Integrate Datajar @etenil
|
||||||
|
* Test Movim on all Datajar back-ends @etenil
|
||||||
|
* Write a makefile to manage packaging/pulling dependencies @etenil
|
||||||
|
* Provide a more consistent API for the XMPP library (to ease the replacement of JAXL later) @etenil
|
||||||
|
* Store the Caps (XEP-115) in the database to cache them @edhelas
|
||||||
|
|
||||||
|
### Widgets @edhelas ###
|
||||||
|
|
||||||
|
* Move Profile to a single page
|
||||||
|
* Merge “News” and “Feed” in one single widget and create filters (by source, date…)
|
||||||
|
* Create a system to cache the Widgets
|
||||||
|
|
||||||
|
#### Roster ####
|
||||||
|
|
||||||
|
* Add groups support
|
||||||
|
* Fixed Bug : chat link when a contact become online
|
||||||
|
|
||||||
|
#### Profile ####
|
||||||
|
|
||||||
|
* New system to switch the presences
|
||||||
|
* Change the status
|
||||||
|
|
||||||
|
#### Feed/Wall ####
|
||||||
|
|
||||||
|
* Store comments in the database
|
||||||
|
* Add comments
|
||||||
|
* Show/hide old comments if there is a lot of them (like 2 or more)
|
||||||
|
|
||||||
|
#### vCard ####
|
||||||
|
|
||||||
|
* Add Avatar support
|
||||||
|
* Date picker for the birth date (kilian)
|
||||||
|
* Display client informations
|
||||||
|
|
||||||
|
#### Chat ####
|
||||||
|
|
||||||
|
* More consistent UI
|
||||||
|
* Store all the Messages in the database to handle them more cleanly
|
||||||
|
|
||||||
|
v0.4.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Multisession support
|
||||||
|
* Dynamically modify page title
|
||||||
|
* image.php to built pictures from the database + ask the browser to cache them
|
||||||
|
* Inscription on the Server (XMPP+Movim)
|
||||||
|
* HTML5 + HTML Title page notification on a new message
|
||||||
|
* Support of HTTP Proxy (installation and configuration)
|
||||||
|
* Support of HTTPS Servers
|
||||||
|
* Implementation on ORDERBY in the Storage database library
|
||||||
|
* Fix language selector
|
||||||
|
* Fix Roster display and organisation
|
||||||
|
* Fix Chat display
|
||||||
|
* Rename some widgets
|
||||||
|
* Fix Vcard widget
|
||||||
|
|
||||||
|
v0.3.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Widgets debugging
|
||||||
|
* Enlarge widgets
|
||||||
|
* Notifications
|
||||||
|
* Blinking tab title
|
||||||
|
* Coloured nicknames
|
||||||
|
* Cached conversation
|
||||||
|
* Tabbed conversations
|
||||||
|
* Blocks-based layout
|
||||||
|
* More bug fixes
|
||||||
|
* URL Rewriting
|
||||||
|
* Logger
|
||||||
|
|
||||||
|
v0.2.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Inter-widgets communication
|
||||||
|
* Proper disconnection handling
|
||||||
|
* Added Installer
|
||||||
|
* Changed to static loading
|
||||||
|
* Speed optimisations
|
||||||
|
* Improved Javascript libraries
|
||||||
|
* Added unit-testing structure
|
||||||
|
* Restructured the program
|
||||||
|
* Reimplemented PHP's session
|
||||||
|
* Added Cache
|
||||||
|
* Use of SQLite3 as Cache/Session back-end (only for 0.2)
|
||||||
|
* Improved theme
|
||||||
|
|
||||||
|
v0.1.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Base core
|
||||||
|
* Events system
|
||||||
|
* Configuration
|
||||||
|
* XMPP connection
|
||||||
|
* Widget system
|
||||||
|
|
49
sources/CMakeLists.txt
Normal file
49
sources/CMakeLists.txt
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
project(movim)
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
exec_program("cat ../VERSION | cut -d . -f 1 2>/dev/null"
|
||||||
|
OUTPUT_VARIABLE MOVIM_VERSION_MAJOR)
|
||||||
|
exec_program("cat ../VERSION | cut -d . -f 2 2>/dev/null"
|
||||||
|
OUTPUT_VARIABLE MOVIM_VERSION_MINOR)
|
||||||
|
exec_program("git rev-parse --short HEAD 2>/dev/null"
|
||||||
|
OUTPUT_VARIABLE MOVIM_VERSION_PATCH)
|
||||||
|
|
||||||
|
set(VERSION_MAJOR "${MOVIM_VERSION_MAJOR}")
|
||||||
|
set(VERSION_MINOR "${MOVIM_VERSION_MINOR}")
|
||||||
|
set(VERSION_PATCH "${MOVIM_VERSION_PATCH}")
|
||||||
|
|
||||||
|
#install(DIRECTORY "config" DESTINATION "/etc/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "debian/etc" DESTINATION "/")
|
||||||
|
install(DIRECTORY "debian/lib" DESTINATION "/")
|
||||||
|
install(DIRECTORY "app" DESTINATION "/usr/share/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "src" DESTINATION "/var/lib/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "system" DESTINATION "/usr/share/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "lib" DESTINATION "/var/lib/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "locales" DESTINATION "/var/lib/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "themes" DESTINATION "/var/lib/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(DIRECTORY "vendor" DESTINATION "/var/lib/${CMAKE_PROJECT_NAME}" REGEX ".git" EXCLUDE)
|
||||||
|
|
||||||
|
install(FILES index.php bootstrap.php daemon.php linker.php mud.php composer.json "VERSION" DESTINATION "/usr/share/${CMAKE_PROJECT_NAME}")
|
||||||
|
install(FILES "config/db.example.inc.php" DESTINATION "/etc/${CMAKE_PROJECT_NAME}")
|
||||||
|
|
||||||
|
# package settings
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Kick Ass Social Network, decentralized and fully based on XMPP ")
|
||||||
|
set(CPACK_PACKAGE_VENDOR "Jaussoin Timothée")
|
||||||
|
set(CPACK_PACKAGE_CONTACT "edhelas@movim.eu")
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}")
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "../COPYING")
|
||||||
|
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${VERSION}")
|
||||||
|
set(ACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${VERSION}")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Kickass distributed social networking platform that protect your privacy an comes with a set of awesome features.")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "php5 (>= 5.4.0), php5-gd (>= 5.4.0), php5-curl (>= 5.4.0), php5-imagick (>= 3.0.0), dbconfig-common(>= 1.8.0)")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jaussoin Timothée <edhelas@movim.eu>")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://movim.eu/")
|
||||||
|
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/debian/conffiles;${CMAKE_CURRENT_SOURCE_DIR}/debian/config;${CMAKE_CURRENT_SOURCE_DIR}/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/debian/postrm;${CMAKE_CURRENT_SOURCE_DIR}/debian/templates;")
|
||||||
|
|
||||||
|
set(PACK "DEB" CACHE STRING "Generate a Package")
|
||||||
|
set(CPACK_GENERATOR ${PACK})
|
||||||
|
|
||||||
|
include(CPack)
|
661
sources/COPYING
Normal file
661
sources/COPYING
Normal file
|
@ -0,0 +1,661 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 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.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the work with which it is combined will remain governed by version
|
||||||
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero 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
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
8
sources/INSTALL.md
Normal file
8
sources/INSTALL.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Movim Installation
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Movim deployment tutorial: https://github.com/movim/movim/wiki/Install-Movim
|
||||||
|
|
||||||
|
You can also follow the Jappix project documentation for a full stack deployment:
|
||||||
|
|
||||||
|
* The XMPP server: https://github.com/jappix/jappix/wiki/XmppServer
|
43
sources/README.md
Normal file
43
sources/README.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
Movim - Kickass Social Network
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
Movim is a decentralized social network, written in PHP and HTML5 and based on the XMPP standard protocol.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
Please refer to the installation instructions that are available on the GitHub Wiki : https://github.com/movim/movim/wiki .
|
||||||
|
|
||||||
|
|
||||||
|
Translations
|
||||||
|
------------
|
||||||
|
Help us translate Movim on https://www.transifex.com/projects/p/movim/.
|
||||||
|
|
||||||
|
Links
|
||||||
|
-----
|
||||||
|
* Movim official website: https://movim.eu/
|
||||||
|
* Twitter : https://twitter.com/MovimNetwork
|
||||||
|
* XMPP Chatroom : movim@conference.movim.eu
|
||||||
|
|
||||||
|
### Pods
|
||||||
|
You can also use Movim on our official Pods :
|
||||||
|
|
||||||
|
* https://pod.movim.eu/ server hosted in France
|
||||||
|
* https://nl.movim.eu/ server hosted in The Netherlands
|
||||||
|
|
||||||
|
### Librairies
|
||||||
|
Movim also contains two specific librairies :
|
||||||
|
|
||||||
|
* https://github.com/movim/moxl Moxl (for Movim XMPP Library) is a PHP XMPP library especially made for the Movim project
|
||||||
|
* https://github.com/movim/modl Modl (for Movim Data Layer) is a light PHP Database layer using DAO pattern
|
||||||
|
|
||||||
|
Support Us
|
||||||
|
----------
|
||||||
|
You can support us on :
|
||||||
|
* Flattr : https://flattr.com/thing/568092/Movim
|
||||||
|
* Bountysource : https://www.bountysource.com/teams/movim
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Movim is released under the terms of the AGPL license. See COPYING for more details.
|
1
sources/VERSION
Normal file
1
sources/VERSION
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0.9.1dev
|
860
sources/app/assets/js/favico.js
Normal file
860
sources/app/assets/js/favico.js
Normal file
|
@ -0,0 +1,860 @@
|
||||||
|
/**
|
||||||
|
* @license MIT or GPL-2.0
|
||||||
|
* @fileOverview Favico animations
|
||||||
|
* @author Miroslav Magda, http://blog.ejci.net
|
||||||
|
* @version 0.3.10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new favico instance
|
||||||
|
* @param {Object} Options
|
||||||
|
* @return {Object} Favico object
|
||||||
|
* @example
|
||||||
|
* var favico = new Favico({
|
||||||
|
* bgColor : '#d00',
|
||||||
|
* textColor : '#fff',
|
||||||
|
* fontFamily : 'sans-serif',
|
||||||
|
* fontStyle : 'bold',
|
||||||
|
* position : 'down',
|
||||||
|
* type : 'circle',
|
||||||
|
* animation : 'slide',
|
||||||
|
* dataUrl: function(url){},
|
||||||
|
* win: top
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
var Favico = (function (opt) {
|
||||||
|
'use strict';
|
||||||
|
opt = (opt) ? opt : {};
|
||||||
|
var _def = {
|
||||||
|
bgColor: '#d00',
|
||||||
|
textColor: '#fff',
|
||||||
|
fontFamily: 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,...
|
||||||
|
fontStyle: 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900
|
||||||
|
type: 'circle',
|
||||||
|
position: 'down', // down, up, left, leftup (upleft)
|
||||||
|
animation: 'slide',
|
||||||
|
elementId: false,
|
||||||
|
dataUrl: false,
|
||||||
|
win: window
|
||||||
|
};
|
||||||
|
var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser, _animTimeout, _drawTimeout, _doc;
|
||||||
|
|
||||||
|
_browser = {};
|
||||||
|
_browser.ff = typeof InstallTrigger != 'undefined';
|
||||||
|
_browser.chrome = !!window.chrome;
|
||||||
|
_browser.opera = !!window.opera || navigator.userAgent.indexOf('Opera') >= 0;
|
||||||
|
_browser.ie = /*@cc_on!@*/false;
|
||||||
|
_browser.safari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
|
||||||
|
_browser.supported = (_browser.chrome || _browser.ff || _browser.opera);
|
||||||
|
|
||||||
|
var _queue = [];
|
||||||
|
_readyCb = function () {
|
||||||
|
};
|
||||||
|
_ready = _stop = false;
|
||||||
|
/**
|
||||||
|
* Initialize favico
|
||||||
|
*/
|
||||||
|
var init = function () {
|
||||||
|
//merge initial options
|
||||||
|
_opt = merge(_def, opt);
|
||||||
|
_opt.bgColor = hexToRgb(_opt.bgColor);
|
||||||
|
_opt.textColor = hexToRgb(_opt.textColor);
|
||||||
|
_opt.position = _opt.position.toLowerCase();
|
||||||
|
_opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation;
|
||||||
|
|
||||||
|
_doc = _opt.win.document;
|
||||||
|
|
||||||
|
var isUp = _opt.position.indexOf('up') > -1;
|
||||||
|
var isLeft = _opt.position.indexOf('left') > -1;
|
||||||
|
|
||||||
|
//transform the animations
|
||||||
|
if (isUp || isLeft) {
|
||||||
|
for (var a in animation.types) {
|
||||||
|
for (var i = 0; i < animation.types[a].length; i++) {
|
||||||
|
var step = animation.types[a][i];
|
||||||
|
|
||||||
|
if (isUp) {
|
||||||
|
if (step.y < 0.6) {
|
||||||
|
step.y = step.y - 0.4;
|
||||||
|
} else {
|
||||||
|
step.y = step.y - 2 * step.y + (1 - step.w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLeft) {
|
||||||
|
if (step.x < 0.6) {
|
||||||
|
step.x = step.x - 0.4;
|
||||||
|
} else {
|
||||||
|
step.x = step.x - 2 * step.x + (1 - step.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.types[a][i] = step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_opt.type = (type['' + _opt.type]) ? _opt.type : _def.type;
|
||||||
|
|
||||||
|
_orig = link.getIcon();
|
||||||
|
//create temp canvas
|
||||||
|
_canvas = document.createElement('canvas');
|
||||||
|
//create temp image
|
||||||
|
_img = document.createElement('img');
|
||||||
|
if (_orig.hasAttribute('href')) {
|
||||||
|
_img.setAttribute('crossOrigin', 'anonymous');
|
||||||
|
//get width/height
|
||||||
|
_img.onload = function () {
|
||||||
|
_h = (_img.height > 0) ? _img.height : 32;
|
||||||
|
_w = (_img.width > 0) ? _img.width : 32;
|
||||||
|
_canvas.height = _h;
|
||||||
|
_canvas.width = _w;
|
||||||
|
_context = _canvas.getContext('2d');
|
||||||
|
icon.ready();
|
||||||
|
};
|
||||||
|
_img.setAttribute('src', _orig.getAttribute('href'));
|
||||||
|
} else {
|
||||||
|
_img.onload = function () {
|
||||||
|
_h = 32;
|
||||||
|
_w = 32;
|
||||||
|
_img.height = _h;
|
||||||
|
_img.width = _w;
|
||||||
|
_canvas.height = _h;
|
||||||
|
_canvas.width = _w;
|
||||||
|
_context = _canvas.getContext('2d');
|
||||||
|
icon.ready();
|
||||||
|
};
|
||||||
|
_img.setAttribute('src', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Icon namespace
|
||||||
|
*/
|
||||||
|
var icon = {};
|
||||||
|
/**
|
||||||
|
* Icon is ready (reset icon) and start animation (if ther is any)
|
||||||
|
*/
|
||||||
|
icon.ready = function () {
|
||||||
|
_ready = true;
|
||||||
|
icon.reset();
|
||||||
|
_readyCb();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Reset icon to default state
|
||||||
|
*/
|
||||||
|
icon.reset = function () {
|
||||||
|
//reset
|
||||||
|
if (!_ready) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_queue = [];
|
||||||
|
_lastBadge = false;
|
||||||
|
_running = false;
|
||||||
|
_context.clearRect(0, 0, _w, _h);
|
||||||
|
_context.drawImage(_img, 0, 0, _w, _h);
|
||||||
|
//_stop=true;
|
||||||
|
link.setIcon(_canvas);
|
||||||
|
//webcam('stop');
|
||||||
|
//video('stop');
|
||||||
|
window.clearTimeout(_animTimeout);
|
||||||
|
window.clearTimeout(_drawTimeout);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Start animation
|
||||||
|
*/
|
||||||
|
icon.start = function () {
|
||||||
|
if (!_ready || _running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var finished = function () {
|
||||||
|
_lastBadge = _queue[0];
|
||||||
|
_running = false;
|
||||||
|
if (_queue.length > 0) {
|
||||||
|
_queue.shift();
|
||||||
|
icon.start();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_queue.length > 0) {
|
||||||
|
_running = true;
|
||||||
|
var run = function () {
|
||||||
|
// apply options for this animation
|
||||||
|
['type', 'animation', 'bgColor', 'textColor', 'fontFamily', 'fontStyle'].forEach(function (a) {
|
||||||
|
if (a in _queue[0].options) {
|
||||||
|
_opt[a] = _queue[0].options[a];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
animation.run(_queue[0].options, function () {
|
||||||
|
finished();
|
||||||
|
}, false);
|
||||||
|
};
|
||||||
|
if (_lastBadge) {
|
||||||
|
animation.run(_lastBadge.options, function () {
|
||||||
|
run();
|
||||||
|
}, true);
|
||||||
|
} else {
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Badge types
|
||||||
|
*/
|
||||||
|
var type = {};
|
||||||
|
var options = function (opt) {
|
||||||
|
opt.n = ((typeof opt.n) === 'number') ? Math.abs(opt.n | 0) : opt.n;
|
||||||
|
opt.x = _w * opt.x;
|
||||||
|
opt.y = _h * opt.y;
|
||||||
|
opt.w = _w * opt.w;
|
||||||
|
opt.h = _h * opt.h;
|
||||||
|
opt.len = ("" + opt.n).length;
|
||||||
|
return opt;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Generate circle
|
||||||
|
* @param {Object} opt Badge options
|
||||||
|
*/
|
||||||
|
type.circle = function (opt) {
|
||||||
|
opt = options(opt);
|
||||||
|
var more = false;
|
||||||
|
if (opt.len === 2) {
|
||||||
|
opt.x = opt.x - opt.w * 0.4;
|
||||||
|
opt.w = opt.w * 1.4;
|
||||||
|
more = true;
|
||||||
|
} else if (opt.len >= 3) {
|
||||||
|
opt.x = opt.x - opt.w * 0.65;
|
||||||
|
opt.w = opt.w * 1.65;
|
||||||
|
more = true;
|
||||||
|
}
|
||||||
|
_context.clearRect(0, 0, _w, _h);
|
||||||
|
_context.drawImage(_img, 0, 0, _w, _h);
|
||||||
|
_context.beginPath();
|
||||||
|
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily;
|
||||||
|
_context.textAlign = 'center';
|
||||||
|
if (more) {
|
||||||
|
_context.moveTo(opt.x + opt.w / 2, opt.y);
|
||||||
|
_context.lineTo(opt.x + opt.w - opt.h / 2, opt.y);
|
||||||
|
_context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2);
|
||||||
|
_context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2);
|
||||||
|
_context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h);
|
||||||
|
_context.lineTo(opt.x + opt.h / 2, opt.y + opt.h);
|
||||||
|
_context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2);
|
||||||
|
_context.lineTo(opt.x, opt.y + opt.h / 2);
|
||||||
|
_context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y);
|
||||||
|
} else {
|
||||||
|
_context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI);
|
||||||
|
}
|
||||||
|
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
|
||||||
|
_context.fill();
|
||||||
|
_context.closePath();
|
||||||
|
_context.beginPath();
|
||||||
|
_context.stroke();
|
||||||
|
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
|
||||||
|
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||||
|
if ((typeof opt.n) === 'number' && opt.n > 999) {
|
||||||
|
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
|
||||||
|
} else {
|
||||||
|
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||||
|
}
|
||||||
|
_context.closePath();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Generate rectangle
|
||||||
|
* @param {Object} opt Badge options
|
||||||
|
*/
|
||||||
|
type.rectangle = function (opt) {
|
||||||
|
opt = options(opt);
|
||||||
|
var more = false;
|
||||||
|
if (opt.len === 2) {
|
||||||
|
opt.x = opt.x - opt.w * 0.4;
|
||||||
|
opt.w = opt.w * 1.4;
|
||||||
|
more = true;
|
||||||
|
} else if (opt.len >= 3) {
|
||||||
|
opt.x = opt.x - opt.w * 0.65;
|
||||||
|
opt.w = opt.w * 1.65;
|
||||||
|
more = true;
|
||||||
|
}
|
||||||
|
_context.clearRect(0, 0, _w, _h);
|
||||||
|
_context.drawImage(_img, 0, 0, _w, _h);
|
||||||
|
_context.beginPath();
|
||||||
|
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px " + _opt.fontFamily;
|
||||||
|
_context.textAlign = 'center';
|
||||||
|
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
|
||||||
|
_context.fillRect(opt.x, opt.y, opt.w, opt.h);
|
||||||
|
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
|
||||||
|
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||||
|
if ((typeof opt.n) === 'number' && opt.n > 999) {
|
||||||
|
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
|
||||||
|
} else {
|
||||||
|
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||||
|
}
|
||||||
|
_context.closePath();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set badge
|
||||||
|
*/
|
||||||
|
var badge = function (number, opts) {
|
||||||
|
opts = ((typeof opts) === 'string' ? {
|
||||||
|
animation: opts
|
||||||
|
} : opts) || {};
|
||||||
|
_readyCb = function () {
|
||||||
|
try {
|
||||||
|
if (typeof (number) === 'number' ? (number > 0) : (number !== '')) {
|
||||||
|
var q = {
|
||||||
|
type: 'badge',
|
||||||
|
options: {
|
||||||
|
n: number
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ('animation' in opts && animation.types['' + opts.animation]) {
|
||||||
|
q.options.animation = '' + opts.animation;
|
||||||
|
}
|
||||||
|
if ('type' in opts && type['' + opts.type]) {
|
||||||
|
q.options.type = '' + opts.type;
|
||||||
|
}
|
||||||
|
['bgColor', 'textColor'].forEach(function (o) {
|
||||||
|
if (o in opts) {
|
||||||
|
q.options[o] = hexToRgb(opts[o]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
['fontStyle', 'fontFamily'].forEach(function (o) {
|
||||||
|
if (o in opts) {
|
||||||
|
q.options[o] = opts[o];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_queue.push(q);
|
||||||
|
if (_queue.length > 100) {
|
||||||
|
throw new Error('Too many badges requests in queue.');
|
||||||
|
}
|
||||||
|
icon.start();
|
||||||
|
} else {
|
||||||
|
icon.reset();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Error setting badge. Message: ' + e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_ready) {
|
||||||
|
_readyCb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set image as icon
|
||||||
|
*/
|
||||||
|
var image = function (imageElement) {
|
||||||
|
_readyCb = function () {
|
||||||
|
try {
|
||||||
|
var w = imageElement.width;
|
||||||
|
var h = imageElement.height;
|
||||||
|
var newImg = document.createElement('img');
|
||||||
|
var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
|
||||||
|
newImg.setAttribute('crossOrigin', 'anonymous');
|
||||||
|
newImg.onload=function(){
|
||||||
|
_context.clearRect(0, 0, _w, _h);
|
||||||
|
_context.drawImage(newImg, 0, 0, _w, _h);
|
||||||
|
link.setIcon(_canvas);
|
||||||
|
};
|
||||||
|
newImg.setAttribute('src', imageElement.getAttribute('src'));
|
||||||
|
newImg.height = (h / ratio);
|
||||||
|
newImg.width = (w / ratio);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Error setting image. Message: ' + e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_ready) {
|
||||||
|
_readyCb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Set video as icon
|
||||||
|
*/
|
||||||
|
var video = function (videoElement) {
|
||||||
|
_readyCb = function () {
|
||||||
|
try {
|
||||||
|
if (videoElement === 'stop') {
|
||||||
|
_stop = true;
|
||||||
|
icon.reset();
|
||||||
|
_stop = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//var w = videoElement.width;
|
||||||
|
//var h = videoElement.height;
|
||||||
|
//var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
|
||||||
|
videoElement.addEventListener('play', function () {
|
||||||
|
drawVideo(this);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Error setting video. Message: ' + e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_ready) {
|
||||||
|
_readyCb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Set video as icon
|
||||||
|
*/
|
||||||
|
var webcam = function (action) {
|
||||||
|
//UR
|
||||||
|
if (!window.URL || !window.URL.createObjectURL) {
|
||||||
|
window.URL = window.URL || {};
|
||||||
|
window.URL.createObjectURL = function (obj) {
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (_browser.supported) {
|
||||||
|
var newVideo = false;
|
||||||
|
navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
|
||||||
|
_readyCb = function () {
|
||||||
|
try {
|
||||||
|
if (action === 'stop') {
|
||||||
|
_stop = true;
|
||||||
|
icon.reset();
|
||||||
|
_stop = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newVideo = document.createElement('video');
|
||||||
|
newVideo.width = _w;
|
||||||
|
newVideo.height = _h;
|
||||||
|
navigator.getUserMedia({
|
||||||
|
video: true,
|
||||||
|
audio: false
|
||||||
|
}, function (stream) {
|
||||||
|
newVideo.src = URL.createObjectURL(stream);
|
||||||
|
newVideo.play();
|
||||||
|
drawVideo(newVideo);
|
||||||
|
}, function () {
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Error setting webcam. Message: ' + e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_ready) {
|
||||||
|
_readyCb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw video to context and repeat :)
|
||||||
|
*/
|
||||||
|
function drawVideo(video) {
|
||||||
|
if (video.paused || video.ended || _stop) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//nasty hack for FF webcam (Thanks to Julian Ćwirko, kontakt@redsunmedia.pl)
|
||||||
|
try {
|
||||||
|
_context.clearRect(0, 0, _w, _h);
|
||||||
|
_context.drawImage(video, 0, 0, _w, _h);
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
_drawTimeout = setTimeout(function () {
|
||||||
|
drawVideo(video);
|
||||||
|
}, animation.duration);
|
||||||
|
link.setIcon(_canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
var link = {};
|
||||||
|
/**
|
||||||
|
* Get icon from HEAD tag or create a new <link> element
|
||||||
|
*/
|
||||||
|
link.getIcon = function () {
|
||||||
|
var elm = false;
|
||||||
|
//get link element
|
||||||
|
var getLink = function () {
|
||||||
|
var link = _doc.getElementsByTagName('head')[0].getElementsByTagName('link');
|
||||||
|
for (var l = link.length, i = (l - 1); i >= 0; i--) {
|
||||||
|
if ((/(^|\s)icon(\s|$)/i).test(link[i].getAttribute('rel'))) {
|
||||||
|
return link[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (_opt.element) {
|
||||||
|
elm = _opt.element;
|
||||||
|
} else if (_opt.elementId) {
|
||||||
|
//if img element identified by elementId
|
||||||
|
elm = _doc.getElementById(_opt.elementId);
|
||||||
|
elm.setAttribute('href', elm.getAttribute('src'));
|
||||||
|
} else {
|
||||||
|
//if link element
|
||||||
|
elm = getLink();
|
||||||
|
if (elm === false) {
|
||||||
|
elm = _doc.createElement('link');
|
||||||
|
elm.setAttribute('rel', 'icon');
|
||||||
|
_doc.getElementsByTagName('head')[0].appendChild(elm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elm.setAttribute('type', 'image/png');
|
||||||
|
return elm;
|
||||||
|
};
|
||||||
|
link.setIcon = function (canvas) {
|
||||||
|
var url = canvas.toDataURL('image/png');
|
||||||
|
if (_opt.dataUrl) {
|
||||||
|
//if using custom exporter
|
||||||
|
_opt.dataUrl(url);
|
||||||
|
}
|
||||||
|
if (_opt.element) {
|
||||||
|
_opt.element.setAttribute('href', url);
|
||||||
|
_opt.element.setAttribute('src', url);
|
||||||
|
} else if (_opt.elementId) {
|
||||||
|
//if is attached to element (image)
|
||||||
|
var elm = _doc.getElementById(_opt.elementId);
|
||||||
|
elm.setAttribute('href', url);
|
||||||
|
elm.setAttribute('src', url);
|
||||||
|
} else {
|
||||||
|
//if is attached to fav icon
|
||||||
|
if (_browser.ff || _browser.opera) {
|
||||||
|
//for FF we need to "recreate" element, atach to dom and remove old <link>
|
||||||
|
//var originalType = _orig.getAttribute('rel');
|
||||||
|
var old = _orig;
|
||||||
|
_orig = _doc.createElement('link');
|
||||||
|
//_orig.setAttribute('rel', originalType);
|
||||||
|
if (_browser.opera) {
|
||||||
|
_orig.setAttribute('rel', 'icon');
|
||||||
|
}
|
||||||
|
_orig.setAttribute('rel', 'icon');
|
||||||
|
_orig.setAttribute('type', 'image/png');
|
||||||
|
_doc.getElementsByTagName('head')[0].appendChild(_orig);
|
||||||
|
_orig.setAttribute('href', url);
|
||||||
|
if (old.parentNode) {
|
||||||
|
old.parentNode.removeChild(old);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_orig.setAttribute('href', url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
|
||||||
|
//HEX to RGB convertor
|
||||||
|
function hexToRgb(hex) {
|
||||||
|
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||||
|
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
|
||||||
|
return r + r + g + g + b + b;
|
||||||
|
});
|
||||||
|
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result ? {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16)
|
||||||
|
} : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge options
|
||||||
|
*/
|
||||||
|
function merge(def, opt) {
|
||||||
|
var mergedOpt = {};
|
||||||
|
var attrname;
|
||||||
|
for (attrname in def) {
|
||||||
|
mergedOpt[attrname] = def[attrname];
|
||||||
|
}
|
||||||
|
for (attrname in opt) {
|
||||||
|
mergedOpt[attrname] = opt[attrname];
|
||||||
|
}
|
||||||
|
return mergedOpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cross-browser page visibility shim
|
||||||
|
* http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible
|
||||||
|
*/
|
||||||
|
function isPageHidden() {
|
||||||
|
return _doc.hidden || _doc.msHidden || _doc.webkitHidden || _doc.mozHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace animation
|
||||||
|
*/
|
||||||
|
var animation = {};
|
||||||
|
/**
|
||||||
|
* Animation "frame" duration
|
||||||
|
*/
|
||||||
|
animation.duration = 40;
|
||||||
|
/**
|
||||||
|
* Animation types (none,fade,pop,slide)
|
||||||
|
*/
|
||||||
|
animation.types = {};
|
||||||
|
animation.types.fade = [{
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.0
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.2
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.3
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.4
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.5
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.6
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.7
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.8
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 0.9
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1.0
|
||||||
|
}];
|
||||||
|
animation.types.none = [{
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}];
|
||||||
|
animation.types.pop = [{
|
||||||
|
x: 1,
|
||||||
|
y: 1,
|
||||||
|
w: 0,
|
||||||
|
h: 0,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.9,
|
||||||
|
y: 0.9,
|
||||||
|
w: 0.1,
|
||||||
|
h: 0.1,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.8,
|
||||||
|
y: 0.8,
|
||||||
|
w: 0.2,
|
||||||
|
h: 0.2,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.7,
|
||||||
|
y: 0.7,
|
||||||
|
w: 0.3,
|
||||||
|
h: 0.3,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.6,
|
||||||
|
y: 0.6,
|
||||||
|
w: 0.4,
|
||||||
|
h: 0.4,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.5,
|
||||||
|
w: 0.5,
|
||||||
|
h: 0.5,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}];
|
||||||
|
animation.types.popFade = [{
|
||||||
|
x: 0.75,
|
||||||
|
y: 0.75,
|
||||||
|
w: 0,
|
||||||
|
h: 0,
|
||||||
|
o: 0
|
||||||
|
}, {
|
||||||
|
x: 0.65,
|
||||||
|
y: 0.65,
|
||||||
|
w: 0.1,
|
||||||
|
h: 0.1,
|
||||||
|
o: 0.2
|
||||||
|
}, {
|
||||||
|
x: 0.6,
|
||||||
|
y: 0.6,
|
||||||
|
w: 0.2,
|
||||||
|
h: 0.2,
|
||||||
|
o: 0.4
|
||||||
|
}, {
|
||||||
|
x: 0.55,
|
||||||
|
y: 0.55,
|
||||||
|
w: 0.3,
|
||||||
|
h: 0.3,
|
||||||
|
o: 0.6
|
||||||
|
}, {
|
||||||
|
x: 0.50,
|
||||||
|
y: 0.50,
|
||||||
|
w: 0.4,
|
||||||
|
h: 0.4,
|
||||||
|
o: 0.8
|
||||||
|
}, {
|
||||||
|
x: 0.45,
|
||||||
|
y: 0.45,
|
||||||
|
w: 0.5,
|
||||||
|
h: 0.5,
|
||||||
|
o: 0.9
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}];
|
||||||
|
animation.types.slide = [{
|
||||||
|
x: 0.4,
|
||||||
|
y: 1,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.9,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.9,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.8,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.7,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.6,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.5,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}, {
|
||||||
|
x: 0.4,
|
||||||
|
y: 0.4,
|
||||||
|
w: 0.6,
|
||||||
|
h: 0.6,
|
||||||
|
o: 1
|
||||||
|
}];
|
||||||
|
/**
|
||||||
|
* Run animation
|
||||||
|
* @param {Object} opt Animation options
|
||||||
|
* @param {Object} cb Callabak after all steps are done
|
||||||
|
* @param {Object} revert Reverse order? true|false
|
||||||
|
* @param {Object} step Optional step number (frame bumber)
|
||||||
|
*/
|
||||||
|
animation.run = function (opt, cb, revert, step) {
|
||||||
|
var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation];
|
||||||
|
if (revert === true) {
|
||||||
|
step = (typeof step !== 'undefined') ? step : animationType.length - 1;
|
||||||
|
} else {
|
||||||
|
step = (typeof step !== 'undefined') ? step : 0;
|
||||||
|
}
|
||||||
|
cb = (cb) ? cb : function () {
|
||||||
|
};
|
||||||
|
if ((step < animationType.length) && (step >= 0)) {
|
||||||
|
type[_opt.type](merge(opt, animationType[step]));
|
||||||
|
_animTimeout = setTimeout(function () {
|
||||||
|
if (revert) {
|
||||||
|
step = step - 1;
|
||||||
|
} else {
|
||||||
|
step = step + 1;
|
||||||
|
}
|
||||||
|
animation.run(opt, cb, revert, step);
|
||||||
|
}, animation.duration);
|
||||||
|
|
||||||
|
link.setIcon(_canvas);
|
||||||
|
} else {
|
||||||
|
cb();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//auto init
|
||||||
|
init();
|
||||||
|
return {
|
||||||
|
badge: badge,
|
||||||
|
video: video,
|
||||||
|
image: image,
|
||||||
|
webcam: webcam,
|
||||||
|
reset: icon.reset,
|
||||||
|
browser: {
|
||||||
|
supported: _browser.supported
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// AMD / RequireJS
|
||||||
|
if (typeof define !== 'undefined' && define.amd) {
|
||||||
|
define([], function () {
|
||||||
|
return Favico;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// CommonJS
|
||||||
|
else if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
module.exports = Favico;
|
||||||
|
}
|
||||||
|
// included directly via <script> tag
|
||||||
|
else {
|
||||||
|
this.Favico = Favico;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
BIN
sources/app/assets/js/images/marker-icon.png
Normal file
BIN
sources/app/assets/js/images/marker-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
sources/app/assets/js/images/marker-shadow.png
Normal file
BIN
sources/app/assets/js/images/marker-shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 535 B |
64
sources/app/assets/js/movim_base.js
Normal file
64
sources/app/assets/js/movim_base.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* Movim Base
|
||||||
|
*
|
||||||
|
* Some basic functions essential for Movim
|
||||||
|
*/
|
||||||
|
|
||||||
|
var onloaders = new Array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a function to the onload event
|
||||||
|
* @param function func
|
||||||
|
*/
|
||||||
|
function movim_add_onload(func)
|
||||||
|
{
|
||||||
|
onloaders.push(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function that is run once the page is loaded.
|
||||||
|
*/
|
||||||
|
function movim_onload()
|
||||||
|
{
|
||||||
|
for(var i = 0; i < onloaders.length; i++) {
|
||||||
|
if(typeof(onloaders[i]) === "function")
|
||||||
|
onloaders[i]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : remove this function
|
||||||
|
*/
|
||||||
|
function movim_change_class(element, classname, title) {
|
||||||
|
var node = document.getElementById(element);
|
||||||
|
var tmp;
|
||||||
|
for (var i = 0; i < node.childNodes.length; i++) {
|
||||||
|
tmp=node.childNodes[i];
|
||||||
|
tmpClass = tmp.className;
|
||||||
|
if (typeof tmpClass != "undefined" && tmp.className.match(/.*protect.*/)) {
|
||||||
|
privacy = node.childNodes[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
privacy.className = classname;
|
||||||
|
privacy.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Geolocalisation function
|
||||||
|
* TODO : remove this function
|
||||||
|
*/
|
||||||
|
|
||||||
|
function setPosition(node) {
|
||||||
|
if (navigator.geolocation) {
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
function (position) {
|
||||||
|
var poss = position.coords.latitude +','+position.coords.longitude;
|
||||||
|
node.value = poss;
|
||||||
|
},
|
||||||
|
// next function is the error callback
|
||||||
|
function (error) { }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
203
sources/app/assets/js/movim_hash.js
Normal file
203
sources/app/assets/js/movim_hash.js
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/**
|
||||||
|
* Implements hashes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function H(object)
|
||||||
|
{
|
||||||
|
return new Hash(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHash(object)
|
||||||
|
{
|
||||||
|
var type = "";
|
||||||
|
if(object != null) {
|
||||||
|
type = object.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type == "Hash";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows iterating over a hash.
|
||||||
|
*/
|
||||||
|
function HashIterator(data, keys)
|
||||||
|
{
|
||||||
|
this.hash = data;
|
||||||
|
this.keys = keys;
|
||||||
|
this.cursor = 0;
|
||||||
|
this.iterated = false;
|
||||||
|
this.type = "HashIterator";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves one item further.
|
||||||
|
*/
|
||||||
|
this.next = function()
|
||||||
|
{
|
||||||
|
if(this.iterated && this.cursor < this.keys.length - 1) {
|
||||||
|
this.cursor++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(!this.iterated) {
|
||||||
|
this.iterated = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves back one item.
|
||||||
|
*/
|
||||||
|
this.prev = function()
|
||||||
|
{
|
||||||
|
if(this.iterated && this.cursor > 0) {
|
||||||
|
this.cursor--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(!this.iterated) {
|
||||||
|
this.iterated = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the key at the current position.
|
||||||
|
*/
|
||||||
|
this.key = function()
|
||||||
|
{
|
||||||
|
return this.keys[this.cursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cursor on the first key.
|
||||||
|
*/
|
||||||
|
this.start = function()
|
||||||
|
{
|
||||||
|
this.cursor = 0;
|
||||||
|
this.iterated = false;
|
||||||
|
return this.cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cursor on the last key.
|
||||||
|
*/
|
||||||
|
this.end = function()
|
||||||
|
{
|
||||||
|
this.cursor = this.keys.length - 1;
|
||||||
|
this.iterated = false;
|
||||||
|
return this.cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the value at the current position.
|
||||||
|
*/
|
||||||
|
this.val = function()
|
||||||
|
{
|
||||||
|
return this.hash[this.keys[this.cursor]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Hash(object)
|
||||||
|
{
|
||||||
|
this.container = null;
|
||||||
|
this.type = "Hash";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an element to the Hash.
|
||||||
|
*/
|
||||||
|
this.set = function(key, val)
|
||||||
|
{
|
||||||
|
var ret = this.container[key] = val;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the value for a key.
|
||||||
|
*/
|
||||||
|
this.get = function(key)
|
||||||
|
{
|
||||||
|
return this.container[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.del = function(key)
|
||||||
|
{
|
||||||
|
var value = this.container[key];
|
||||||
|
delete this.container[key];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.haskey = function(key)
|
||||||
|
{
|
||||||
|
return key in this.container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates through the hash.
|
||||||
|
*/
|
||||||
|
this.iterate = function()
|
||||||
|
{
|
||||||
|
return new HashIterator(this.container, this.keys());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conversions */
|
||||||
|
/**
|
||||||
|
* Return an array containing the keys.
|
||||||
|
*/
|
||||||
|
this.keys = function()
|
||||||
|
{
|
||||||
|
var keys = new Array();
|
||||||
|
for(var key in this.container) {
|
||||||
|
keys.push(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the hash into an array of values.
|
||||||
|
*/
|
||||||
|
this.values = function()
|
||||||
|
{
|
||||||
|
var values = new Array();
|
||||||
|
for(var key in this.container) {
|
||||||
|
values.push(this.container[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the hash to a string.
|
||||||
|
*/
|
||||||
|
this.to_string = function(want_keys)
|
||||||
|
{
|
||||||
|
if(arguments.length == 0) {
|
||||||
|
want_keys = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = ""; var i = 0;
|
||||||
|
for(var key in this.container) {
|
||||||
|
if(i > 0) buffer += ", ";
|
||||||
|
if(want_keys) {
|
||||||
|
buffer += key + ": ";
|
||||||
|
}
|
||||||
|
buffer += this.container[key];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Contructor
|
||||||
|
if(arguments.length > 0 && object != null) {
|
||||||
|
this.container = object;
|
||||||
|
} else {
|
||||||
|
this.container = {};
|
||||||
|
}
|
||||||
|
}
|
73
sources/app/assets/js/movim_map.js
Normal file
73
sources/app/assets/js/movim_map.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* @brief Definition of the MovimMap object
|
||||||
|
*/
|
||||||
|
var MovimMap = {
|
||||||
|
init: function() {
|
||||||
|
if(document.getElementById('postsmap') == null) return;
|
||||||
|
|
||||||
|
MovimMap.postsmap = L.map('postsmap').setView([40,0], 2);
|
||||||
|
|
||||||
|
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||||
|
attribution: "Map data © <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(MovimMap.postsmap);
|
||||||
|
|
||||||
|
MovimMap.bound = [];
|
||||||
|
|
||||||
|
MovimMap.layerGroup = new L.LayerGroup().addTo(MovimMap.postsmap);
|
||||||
|
},
|
||||||
|
refresh: function() {
|
||||||
|
if(document.getElementById('postsmap') == null) return;
|
||||||
|
|
||||||
|
if(MovimMap.postsmap != null) {
|
||||||
|
MovimMap.layerGroup.clearLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
var articles = document.querySelectorAll('article');
|
||||||
|
for(var i = 0; i < articles.length; i++) {
|
||||||
|
var article = articles[i];
|
||||||
|
if(article.dataset.lat != null) {
|
||||||
|
MovimMap.addMarker(article.dataset.lat, article.dataset.lon, article.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MovimMap.addContact();
|
||||||
|
|
||||||
|
MovimMap.fit();
|
||||||
|
},
|
||||||
|
addContact: function() {
|
||||||
|
if(document.getElementById('postsmap') == null) return;
|
||||||
|
|
||||||
|
var profile = document.querySelector('#contactsummary_widget .profile');
|
||||||
|
|
||||||
|
if(profile.dataset != null && profile.dataset.lat != null) {
|
||||||
|
var popup = "<img style='float: left; margin-right: 1em;' src='" + profile.dataset.avatar + "'/>" +
|
||||||
|
"<div style='padding: 0.5em;'>" + profile.dataset.date + '</div>';
|
||||||
|
|
||||||
|
var red = L.icon({
|
||||||
|
iconUrl: BASE_URI + '/themes/movim/img/marker-icon.png',
|
||||||
|
iconSize: [25,41], // size of the icon
|
||||||
|
shadowSize: [50, 64], // size of the shadow
|
||||||
|
iconAnchor: [13, 41]
|
||||||
|
});
|
||||||
|
|
||||||
|
var marker = L.marker([profile.dataset.lat ,profile.dataset.lon], {icon: red}).addTo(MovimMap.postsmap);
|
||||||
|
marker.bindPopup(popup).openPopup();
|
||||||
|
|
||||||
|
MovimMap.bound.push([profile.dataset.lat, profile.dataset.lon]);
|
||||||
|
|
||||||
|
MovimMap.fit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addMarker: function(lat, lon, id) {
|
||||||
|
var marker = L.marker([lat, lon]);
|
||||||
|
MovimMap.layerGroup.addLayer(marker);
|
||||||
|
|
||||||
|
if(id != null) marker.onclick = function() { document.location = '#' + id};
|
||||||
|
|
||||||
|
MovimMap.bound.push([lat, lon]);
|
||||||
|
},
|
||||||
|
fit: function() {
|
||||||
|
MovimMap.postsmap.fitBounds(MovimMap.bound);
|
||||||
|
},
|
||||||
|
}
|
185
sources/app/assets/js/movim_tpl.js
Normal file
185
sources/app/assets/js/movim_tpl.js
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/**
|
||||||
|
* Movim Javascript Template functions
|
||||||
|
*
|
||||||
|
* These are the default callback functions that users may (or may not) use.
|
||||||
|
*
|
||||||
|
* Note that all of them take only one parameter. Don't be fooled by this, the
|
||||||
|
* expected parameter is actually an array containing the real parameters. These
|
||||||
|
* are checked before use.
|
||||||
|
*
|
||||||
|
* Look at the comments for help.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// movim_append(div, text)
|
||||||
|
function movim_append(id, html)
|
||||||
|
{
|
||||||
|
target = document.getElementById(id);
|
||||||
|
if(target) {
|
||||||
|
target.insertAdjacentHTML('beforeend', html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// movim_prepend(div, text)
|
||||||
|
function movim_prepend(id, html)
|
||||||
|
{
|
||||||
|
target = document.getElementById(id);
|
||||||
|
if(target) {
|
||||||
|
target.insertAdjacentHTML('afterbegin', html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// movim_fill(div, text)
|
||||||
|
function movim_fill(id, html)
|
||||||
|
{
|
||||||
|
target = document.getElementById(id);
|
||||||
|
if(target) {
|
||||||
|
target.innerHTML = html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// movim_delete(div)
|
||||||
|
function movim_delete(id)
|
||||||
|
{
|
||||||
|
target = document.getElementById(id);
|
||||||
|
if(target)
|
||||||
|
target.parentNode.removeChild(target);
|
||||||
|
}
|
||||||
|
// movim_replace(id)
|
||||||
|
function movim_replace(id, html)
|
||||||
|
{
|
||||||
|
target = document.getElementById(id);
|
||||||
|
if(target) {
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.innerHTML = html;
|
||||||
|
var element = div.firstChild;
|
||||||
|
replacedNode = target.parentNode.replaceChild(element, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var MovimTpl = {
|
||||||
|
init : function() {
|
||||||
|
if(document.getElementById('back') != null)
|
||||||
|
document.getElementById('back').style.display = 'none';
|
||||||
|
|
||||||
|
MovimTpl.scrollHeaders();
|
||||||
|
},
|
||||||
|
scrollHeaders : function() {
|
||||||
|
/*var headers = document.querySelectorAll('main > section > div > header');
|
||||||
|
|
||||||
|
for(var i = 0, len = headers.length; i < len; ++i ) {
|
||||||
|
var header = headers[i];
|
||||||
|
|
||||||
|
header.parentNode.onscroll = function() {
|
||||||
|
var header = this.querySelector('header');
|
||||||
|
if(this.scrollTop == 0) {
|
||||||
|
movim_remove_class(header, 'scroll');
|
||||||
|
} else {
|
||||||
|
movim_add_class(header, 'scroll');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
},
|
||||||
|
showPanel : function() {
|
||||||
|
movim_add_class('main section > div:first-child:nth-last-child(2) ~ div', 'enabled');
|
||||||
|
MovimTpl.scrollPanelTop();
|
||||||
|
//MovimTpl.scrollHeaders();
|
||||||
|
},
|
||||||
|
hidePanel : function() {
|
||||||
|
//Header_ajaxReset(CURRENT_PAGE);
|
||||||
|
var selector = 'main section > div:first-child:nth-last-child(2) ~ div';
|
||||||
|
var inner = document.querySelector(selector + ' div');
|
||||||
|
|
||||||
|
movim_remove_class(selector, 'enabled');
|
||||||
|
|
||||||
|
// Clear the right panel
|
||||||
|
//if(inner != null) inner.innerHTML = '';
|
||||||
|
//else document.querySelector(selector).innerHTML = '';
|
||||||
|
},
|
||||||
|
fill : function(selector, html) {
|
||||||
|
target = document.querySelector(selector);
|
||||||
|
if(target) {
|
||||||
|
target.innerHTML = html;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isPanel : function() {
|
||||||
|
if(movim_has_class('main section > div:first-child:nth-last-child(2) ~ div', 'enabled')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isPanelScrolled : function() {
|
||||||
|
var selector = document.querySelector('main section > div:first-child:nth-last-child(2) ~ div div');
|
||||||
|
|
||||||
|
if(selector != null) {
|
||||||
|
return (selector.scrollHeight - Math.floor(selector.scrollTop) === selector.clientHeight);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollPanel : function() {
|
||||||
|
var selector = document.querySelector('main section > div:first-child:nth-last-child(2) ~ div div');
|
||||||
|
|
||||||
|
if(selector != null) {
|
||||||
|
selector.scrollTop = selector.scrollHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollPanelTop : function() {
|
||||||
|
var selector = document.querySelector('main section > div:first-child:nth-last-child(2) ~ div');
|
||||||
|
|
||||||
|
if(selector != null) {
|
||||||
|
selector.scrollTop = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleMenu : function() {
|
||||||
|
movim_toggle_class('body > nav', 'active');
|
||||||
|
},
|
||||||
|
toggleContextMenu : function(e) {
|
||||||
|
var element = 'ul.context_menu';
|
||||||
|
var classname = 'shown';
|
||||||
|
|
||||||
|
if(document.querySelector(element) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(document.querySelector('.show_context_menu').contains(e.target)) {
|
||||||
|
movim_add_class(element, classname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(!document.querySelector(element).contains(e.target))
|
||||||
|
movim_remove_class(element, classname);
|
||||||
|
},
|
||||||
|
toggleActionButton : function() {
|
||||||
|
movim_toggle_class('.button.action', 'active');
|
||||||
|
},
|
||||||
|
hideContextMenu : function() {
|
||||||
|
movim_remove_class('ul.context_menu', 'shown');
|
||||||
|
},
|
||||||
|
hideMenu : function() {
|
||||||
|
movim_remove_class('body > nav', 'active');
|
||||||
|
},
|
||||||
|
back : function() {
|
||||||
|
// If the contect menu is show
|
||||||
|
var cm = document.querySelector('ul.context_menu');
|
||||||
|
if(cm != null && cm.className.includes('shown')) {
|
||||||
|
MovimTpl.toggleContextMenu(document);
|
||||||
|
}
|
||||||
|
// If a dialog box is show
|
||||||
|
else if(Dialog.filled()) {
|
||||||
|
Dialog.clear();
|
||||||
|
// If the menu is shown
|
||||||
|
} else if(movim_has_class('body > nav', 'active')) {
|
||||||
|
movim_toggle_class('body > nav', 'active');
|
||||||
|
// If the panel is shown
|
||||||
|
} else if(MovimTpl.isPanel()) {
|
||||||
|
MovimTpl.hidePanel();
|
||||||
|
} else {
|
||||||
|
window.history.back();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getHeaderColor : function() {
|
||||||
|
var header = document.querySelector('body main > header');
|
||||||
|
return window.getComputedStyle(header).backgroundColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
movim_add_onload(function() {
|
||||||
|
MovimTpl.init();
|
||||||
|
document.body.addEventListener('click', MovimTpl.toggleContextMenu, false);
|
||||||
|
});
|
321
sources/app/assets/js/movim_utils.js
Normal file
321
sources/app/assets/js/movim_utils.js
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
/**
|
||||||
|
* Movim Utils
|
||||||
|
*
|
||||||
|
* This file include some useful functions used quite everywhere in Movim
|
||||||
|
*/
|
||||||
|
|
||||||
|
function movim_check_string(str) {
|
||||||
|
if (typeof str == 'object') {
|
||||||
|
return str instanceof String;
|
||||||
|
} else {
|
||||||
|
return typeof str == 'string';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function movim_get_node(str) {
|
||||||
|
if(movim_check_string(str))
|
||||||
|
return document.querySelector(str);
|
||||||
|
else
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Force Movim to go back to the login page
|
||||||
|
*/
|
||||||
|
function movim_disconnect()
|
||||||
|
{
|
||||||
|
window.location.replace(ERROR_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Force Movim to reload the page
|
||||||
|
* @param string uri
|
||||||
|
*/
|
||||||
|
function movim_reload(uri) {
|
||||||
|
window.location.replace(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Force Movim to reload the current page
|
||||||
|
* @param string error
|
||||||
|
*/
|
||||||
|
function movim_reload_this() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Force Movim to go to an url
|
||||||
|
* @param string url
|
||||||
|
*/
|
||||||
|
function movim_redirect(url) {
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a hash (key->value) version of a form
|
||||||
|
* @param string the name of the form
|
||||||
|
* @return hash
|
||||||
|
*/
|
||||||
|
function movim_parse_form(formname) {
|
||||||
|
var form = document.forms[formname];
|
||||||
|
if(!form)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var data = H();
|
||||||
|
for(var i = 0; i < form.elements.length; i++) {
|
||||||
|
if(form.elements[i].type == 'checkbox') {
|
||||||
|
data.set(form.elements[i].name,
|
||||||
|
form.elements[i].checked);
|
||||||
|
} else if(form.elements[i].type == 'radio'
|
||||||
|
&& form.elements[i].checked ) {
|
||||||
|
data.set(form.elements[i].name,
|
||||||
|
form.elements[i].value);
|
||||||
|
} else if(form.elements[i].type != 'radio'){
|
||||||
|
data.set(form.elements[i].name,
|
||||||
|
form.elements[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a JSON version of a form
|
||||||
|
* @param string the name of the form
|
||||||
|
* @return JSON
|
||||||
|
*/
|
||||||
|
function movim_form_to_json(formname) {
|
||||||
|
var form = document.forms[formname];
|
||||||
|
if(!form)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var json = {};
|
||||||
|
|
||||||
|
for(var i = 0; i < form.elements.length; i++) {
|
||||||
|
json_att = {};
|
||||||
|
|
||||||
|
for(var j = 0; j < form.elements[i].attributes.length; j++) {
|
||||||
|
json_att[form.elements[i].attributes[j].name] = form.elements[i].attributes[j].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(form.elements[i].name.length != 0) {
|
||||||
|
if(form.elements[i].type == 'checkbox')
|
||||||
|
json[form.elements[i].name] = {'value' : form.elements[i].checked, 'attributes' : json_att};
|
||||||
|
else if(form.elements[i].type == 'radio'
|
||||||
|
&& form.elements[i].checked )
|
||||||
|
json[form.elements[i].name] = {'value' : form.elements[i].value, 'attributes' : json_att};
|
||||||
|
else if(form.elements[i].type != 'radio')
|
||||||
|
json[form.elements[i].name] = {'value' : form.elements[i].value, 'attributes' : json_att};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A magical function to autoresize textarea when typing
|
||||||
|
* @param DOMElement textbox
|
||||||
|
*/
|
||||||
|
function movim_textarea_autoheight(textbox) {
|
||||||
|
if(textbox != null) {
|
||||||
|
var val = textbox.value;
|
||||||
|
val = val.replace(/\n/g, '<br>');
|
||||||
|
var hidden = document.querySelector('#hiddendiv');
|
||||||
|
hidden.innerHTML = val + '<br/>';
|
||||||
|
|
||||||
|
textboxStyle = window.getComputedStyle(textbox);
|
||||||
|
|
||||||
|
hidden.style.paddingTop = textboxStyle.paddingTop;
|
||||||
|
hidden.style.paddingBottom = textboxStyle.paddingBottom;
|
||||||
|
hidden.style.width = textboxStyle.width;
|
||||||
|
hidden.style.fontSize = textboxStyle.fontSize;
|
||||||
|
|
||||||
|
textbox.style.height = hidden.scrollHeight+"px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the element own the class
|
||||||
|
* @param string the selector of the element (e.g '#myid', '.theclass')
|
||||||
|
* @param string the class to check
|
||||||
|
*/
|
||||||
|
function movim_has_class(element,classname) {
|
||||||
|
var node = movim_get_node(element);
|
||||||
|
if(!node) console.log('Node ' + element + ' not found');
|
||||||
|
return node.className.match(new RegExp('(\\s|^)'+classname+'(\\s|$)'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a class of an element
|
||||||
|
* @param string the selector of the element
|
||||||
|
* @param string the class to add
|
||||||
|
*/
|
||||||
|
function movim_add_class(element,classname) {
|
||||||
|
if(!movim_has_class(element,classname)) {
|
||||||
|
var element = movim_get_node(element);
|
||||||
|
element.className += " "+classname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a class of an element
|
||||||
|
* @param string the selector of the element
|
||||||
|
* @param string the class to remove
|
||||||
|
*/
|
||||||
|
function movim_remove_class(element,classname) {
|
||||||
|
if (movim_has_class(element,classname)) {
|
||||||
|
var reg = new RegExp('(\\s|^)'+classname+'(\\s|$)');
|
||||||
|
var element = movim_get_node(element);
|
||||||
|
element.className=element.className.replace(reg,' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggle the class of an element
|
||||||
|
* @param string the selector of the element
|
||||||
|
* @param string the class to toggle
|
||||||
|
*/
|
||||||
|
function movim_toggle_class(element, classname) {
|
||||||
|
if(movim_has_class(element, classname))
|
||||||
|
movim_remove_class(element,classname);
|
||||||
|
else
|
||||||
|
movim_add_class(element, classname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save the current button class
|
||||||
|
* @param string the selector of the element
|
||||||
|
*/
|
||||||
|
function movim_button_save(element) {
|
||||||
|
var elt = document.querySelector(element);
|
||||||
|
elt.dataset.oldclassname = elt.className;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the button
|
||||||
|
* @param string the selector of the element
|
||||||
|
*/
|
||||||
|
function movim_button_reset(element) {
|
||||||
|
var elt = document.querySelector(element);
|
||||||
|
elt.className = elt.dataset.oldclassname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggle the visibility of an element
|
||||||
|
* @param string the selector of the element
|
||||||
|
*/
|
||||||
|
function movim_toggle_display(element) {
|
||||||
|
var node = movim_get_node(element);
|
||||||
|
|
||||||
|
if(node != null) {
|
||||||
|
if(node.style.display == 'block')
|
||||||
|
node.style.display = 'none';
|
||||||
|
else
|
||||||
|
node.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Push a new state in the History
|
||||||
|
* @param strin The new state URL
|
||||||
|
*/
|
||||||
|
function movim_push_state(url) {
|
||||||
|
window.history.pushState(null, "", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set object in localStorage
|
||||||
|
* @param key string
|
||||||
|
* @param value the object
|
||||||
|
*/
|
||||||
|
Storage.prototype.setObject = function(key, value) {
|
||||||
|
this.setItem(key, JSON.stringify(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get object in localStorage
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
Storage.prototype.getObject = function(key) {
|
||||||
|
return JSON.parse(this.getItem(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
function base64_decode(data) {
|
||||||
|
// discuss at: http://phpjs.org/functions/base64_decode/
|
||||||
|
// original by: Tyler Akins (http://rumkin.com)
|
||||||
|
// improved by: Thunder.m
|
||||||
|
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
||||||
|
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
||||||
|
// input by: Aman Gupta
|
||||||
|
// input by: Brett Zamir (http://brett-zamir.me)
|
||||||
|
// bugfixed by: Onno Marsman
|
||||||
|
// bugfixed by: Pellentesque Malesuada
|
||||||
|
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
||||||
|
// example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
|
||||||
|
// returns 1: 'Kevin van Zonneveld'
|
||||||
|
// example 2: base64_decode('YQ===');
|
||||||
|
// returns 2: 'a'
|
||||||
|
|
||||||
|
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||||
|
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
|
||||||
|
ac = 0,
|
||||||
|
dec = '',
|
||||||
|
tmp_arr = [];
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += '';
|
||||||
|
|
||||||
|
do { // unpack four hexets into three octets using index points in b64
|
||||||
|
h1 = b64.indexOf(data.charAt(i++));
|
||||||
|
h2 = b64.indexOf(data.charAt(i++));
|
||||||
|
h3 = b64.indexOf(data.charAt(i++));
|
||||||
|
h4 = b64.indexOf(data.charAt(i++));
|
||||||
|
|
||||||
|
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
|
||||||
|
|
||||||
|
o1 = bits >> 16 & 0xff;
|
||||||
|
o2 = bits >> 8 & 0xff;
|
||||||
|
o3 = bits & 0xff;
|
||||||
|
|
||||||
|
if (h3 == 64) {
|
||||||
|
tmp_arr[ac++] = String.fromCharCode(o1);
|
||||||
|
} else if (h4 == 64) {
|
||||||
|
tmp_arr[ac++] = String.fromCharCode(o1, o2);
|
||||||
|
} else {
|
||||||
|
tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
|
||||||
|
}
|
||||||
|
} while (i < data.length);
|
||||||
|
|
||||||
|
dec = tmp_arr.join('');
|
||||||
|
|
||||||
|
return dec.replace(/\0+$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sanitize string for easy search
|
||||||
|
* @param string
|
||||||
|
*/
|
||||||
|
function accentsTidy(s){
|
||||||
|
//Ian Elliott in http://stackoverflow.com/questions/990904/javascript-remove-accents-diacritics-in-strings
|
||||||
|
var r = s.toLowerCase();
|
||||||
|
r = r.replace(new RegExp("\\s", 'g'),"");
|
||||||
|
r = r.replace(new RegExp("[àáâãäå]", 'g'),"a");
|
||||||
|
r = r.replace(new RegExp("æ", 'g'),"ae");
|
||||||
|
r = r.replace(new RegExp("ç", 'g'),"c");
|
||||||
|
r = r.replace(new RegExp("[èéêë]", 'g'),"e");
|
||||||
|
r = r.replace(new RegExp("[ìíîï]", 'g'),"i");
|
||||||
|
r = r.replace(new RegExp("ñ", 'g'),"n");
|
||||||
|
r = r.replace(new RegExp("[òóôõö]", 'g'),"o");
|
||||||
|
r = r.replace(new RegExp("œ", 'g'),"oe");
|
||||||
|
r = r.replace(new RegExp("[ùúûü]", 'g'),"u");
|
||||||
|
r = r.replace(new RegExp("[ýÿ]", 'g'),"y");
|
||||||
|
r = r.replace(new RegExp("\\W", 'g'),"");
|
||||||
|
return r;
|
||||||
|
};
|
203
sources/app/assets/js/movim_websocket.js
Normal file
203
sources/app/assets/js/movim_websocket.js
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/**
|
||||||
|
* Movim Websocket
|
||||||
|
*
|
||||||
|
* This file define the websocket behaviour and handle its connection
|
||||||
|
*/
|
||||||
|
|
||||||
|
WebSocket.prototype.unregister = function() {
|
||||||
|
this.send(JSON.stringify({'func' : 'unregister'}));
|
||||||
|
};
|
||||||
|
|
||||||
|
WebSocket.prototype.register = function(host) {
|
||||||
|
this.send(JSON.stringify({'func' : 'register', 'host' : host}));
|
||||||
|
};
|
||||||
|
|
||||||
|
WebSocket.prototype.admin = function(key) {
|
||||||
|
this.send(JSON.stringify({'func' : 'admin', 'key' : key}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Definition of the MovimWebsocket object
|
||||||
|
* @param string error
|
||||||
|
*/
|
||||||
|
|
||||||
|
var MovimWebsocket = {
|
||||||
|
connection: null,
|
||||||
|
attached: new Array(),
|
||||||
|
registered: new Array(),
|
||||||
|
unregistered: false,
|
||||||
|
attempts: 1,
|
||||||
|
|
||||||
|
launchAttached : function() {
|
||||||
|
for(var i = 0; i < MovimWebsocket.attached.length; i++) {
|
||||||
|
MovimWebsocket.attached[i]();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
launchRegistered : function() {
|
||||||
|
for(var i = 0; i < MovimWebsocket.registered.length; i++) {
|
||||||
|
MovimWebsocket.registered[i]();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init : function() {
|
||||||
|
if(SECURE_WEBSOCKET) {
|
||||||
|
var uri = 'wss://' + BASE_HOST + '/ws/';
|
||||||
|
} else {
|
||||||
|
var uri = 'ws://' + BASE_HOST + '/ws/';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.connection = new WebSocket(uri);
|
||||||
|
|
||||||
|
this.connection.onopen = function(e) {
|
||||||
|
console.log("Connection established!");
|
||||||
|
MovimWebsocket.attempts = 1;
|
||||||
|
MovimWebsocket.launchAttached();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.connection.onmessage = function(e) {
|
||||||
|
data = pako.ungzip(base64_decode(e.data), { to: 'string' });
|
||||||
|
|
||||||
|
var obj = JSON.parse(data);
|
||||||
|
|
||||||
|
if(obj != null) {
|
||||||
|
if(obj.func == 'registered') {
|
||||||
|
MovimWebsocket.launchRegistered();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(obj.func == 'disconnected') {
|
||||||
|
movim_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
MovimWebsocket.handle(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.connection.onclose = function(e) {
|
||||||
|
console.log("Connection closed by the server or session closed");
|
||||||
|
if(e.code == 1006 || e.code == 1000) {
|
||||||
|
if(MovimWebsocket.unregistered == false) {
|
||||||
|
movim_disconnect();
|
||||||
|
} else {
|
||||||
|
MovimWebsocket.unregistered = false;
|
||||||
|
MovimWebsocket.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.connection.onerror = function(e) {
|
||||||
|
console.log(e.code);
|
||||||
|
console.log(e);
|
||||||
|
console.log("Connection error!");
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
// We've tried to reconnect so increment the attempts by 1
|
||||||
|
MovimWebsocket.attempts++;
|
||||||
|
|
||||||
|
// Connection has closed so try to reconnect every 10 seconds.
|
||||||
|
MovimWebsocket.init();
|
||||||
|
}, MovimWebsocket.generateInterval());
|
||||||
|
|
||||||
|
// We prevent the onclose launch
|
||||||
|
this.onclose = null;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
send : function(widget, func, params) {
|
||||||
|
if(this.connection.readyState == 1) {
|
||||||
|
this.connection.send(
|
||||||
|
JSON.stringify(
|
||||||
|
{'func' : 'message', 'body' :
|
||||||
|
{
|
||||||
|
'widget' : widget,
|
||||||
|
'func' : func,
|
||||||
|
'params' : params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
attach : function(func) {
|
||||||
|
if(typeof(func) === "function") {
|
||||||
|
this.attached.push(func);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
register : function(func) {
|
||||||
|
if(typeof(func) === "function") {
|
||||||
|
this.registered.push(func);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clearAttached : function() {
|
||||||
|
this.attached = new Array();
|
||||||
|
},
|
||||||
|
|
||||||
|
handle : function(funcalls) {
|
||||||
|
if(funcalls != null) {
|
||||||
|
for(h = 0; h < funcalls.length; h++) {
|
||||||
|
var funcall = funcalls[h];
|
||||||
|
if(funcall.func != null && (typeof window[funcall.func] == 'function')) {
|
||||||
|
try {
|
||||||
|
window[funcall.func].apply(null, funcall.params);
|
||||||
|
} catch(err) {
|
||||||
|
console.log("Error caught: " + err.toString() + " - " + funcall.func + ":" + JSON.stringify(funcall.params));
|
||||||
|
}
|
||||||
|
} else if(funcall.func != null) {
|
||||||
|
var funcs = funcall.func.split('.');
|
||||||
|
var called = funcs[0];
|
||||||
|
if(typeof window[called] == 'object') {
|
||||||
|
window[funcs[0]][funcs[1]].apply(null, funcall.params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unregister : function(reload) {
|
||||||
|
if(reload == false) this.unregistered = true;
|
||||||
|
this.connection.unregister();
|
||||||
|
},
|
||||||
|
|
||||||
|
generateInterval :function() {
|
||||||
|
var maxInterval = (Math.pow(2, MovimWebsocket.attempts) - 1) * 1000;
|
||||||
|
|
||||||
|
if (maxInterval > 30*1000) {
|
||||||
|
maxInterval = 30*1000; // If the generated interval is more than 30 seconds, truncate it down to 30 seconds.
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate the interval to a random number between 0 and the maxInterval determined from above
|
||||||
|
return Math.random() * maxInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remoteUnregister()
|
||||||
|
{
|
||||||
|
MovimWebsocket.unregister(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remoteUnregisterReload()
|
||||||
|
{
|
||||||
|
MovimWebsocket.unregister(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("visibilitychange", function () {
|
||||||
|
if(!document.hidden) {
|
||||||
|
if(MovimWebsocket.connection.readyState == 3) {
|
||||||
|
MovimWebsocket.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.onbeforeunload = function() {
|
||||||
|
MovimWebsocket.connection.onclose = function () {}; // disable onclose handler first
|
||||||
|
MovimWebsocket.connection.close()
|
||||||
|
};
|
||||||
|
|
||||||
|
movim_add_onload(function() {
|
||||||
|
// And we start it
|
||||||
|
MovimWebsocket.init();
|
||||||
|
});
|
3025
sources/app/assets/js/pako_inflate.js
Normal file
3025
sources/app/assets/js/pako_inflate.js
Normal file
File diff suppressed because it is too large
Load diff
11
sources/app/controllers/AboutController.php
Normal file
11
sources/app/controllers/AboutController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class AboutController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.about', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/AccountController.php
Normal file
11
sources/app/controllers/AccountController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class AccountController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.account', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/AccountnextController.php
Normal file
11
sources/app/controllers/AccountnextController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class AccountnextController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.account', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
17
sources/app/controllers/AdminController.php
Normal file
17
sources/app/controllers/AdminController.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class AdminController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if(isset($_SESSION['admin']) && $_SESSION['admin'] == true) {
|
||||||
|
$this->page->setTitle(__('title.administration', APP_TITLE));
|
||||||
|
} else {
|
||||||
|
$this->name = 'adminlogin';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
sources/app/controllers/AdminloginController.php
Normal file
23
sources/app/controllers/AdminloginController.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class AdminloginController extends BaseController
|
||||||
|
{
|
||||||
|
function load()
|
||||||
|
{
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch()
|
||||||
|
{
|
||||||
|
$this->page->setTitle(__('title.administration', APP_TITLE));
|
||||||
|
|
||||||
|
$cd = new \Modl\ConfigDAO();
|
||||||
|
$config = $cd->get();
|
||||||
|
|
||||||
|
if($config->username == $_POST['username']
|
||||||
|
&& $config->password == sha1($_POST['password'])) {
|
||||||
|
$_SESSION['admin'] = true;
|
||||||
|
$this->name = 'admin';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
sources/app/controllers/BlogController.php
Normal file
12
sources/app/controllers/BlogController.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class BlogController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
$this->public = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.blog'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/ChatController.php
Normal file
11
sources/app/controllers/ChatController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ChatController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.chats'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/ConfController.php
Normal file
11
sources/app/controllers/ConfController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ConfController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.configuration'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/ContactController.php
Normal file
11
sources/app/controllers/ContactController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ContactController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.contacts'));
|
||||||
|
}
|
||||||
|
}
|
13
sources/app/controllers/DisconnectController.php
Normal file
13
sources/app/controllers/DisconnectController.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class DisconnectController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$user = new User();
|
||||||
|
$user->desauth();
|
||||||
|
$this->redirect('login');
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/FeedController.php
Normal file
11
sources/app/controllers/FeedController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class FeedController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
$this->raw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
}
|
||||||
|
}
|
16
sources/app/controllers/GroupController.php
Normal file
16
sources/app/controllers/GroupController.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class GroupController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$user = new User();
|
||||||
|
if(!$user->isLogged()) {
|
||||||
|
$this->name = 'grouppublic';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->page->setTitle(__('page.groups'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/HelpController.php
Normal file
11
sources/app/controllers/HelpController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HelpController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.help'));
|
||||||
|
}
|
||||||
|
}
|
12
sources/app/controllers/InfosController.php
Normal file
12
sources/app/controllers/InfosController.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class InfosController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
header('Content-type: application/json');
|
||||||
|
$this->session_only = false;
|
||||||
|
$this->raw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
}
|
||||||
|
}
|
16
sources/app/controllers/LoginController.php
Normal file
16
sources/app/controllers/LoginController.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class LoginController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.login', APP_TITLE));
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
if($user->isLogged()) {
|
||||||
|
$this->redirect('root');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/MainController.php
Normal file
11
sources/app/controllers/MainController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MainController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.home'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/MediaController.php
Normal file
11
sources/app/controllers/MediaController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MediaController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.media', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/NewsController.php
Normal file
11
sources/app/controllers/NewsController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class NewsController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.news'));
|
||||||
|
}
|
||||||
|
}
|
12
sources/app/controllers/NodeController.php
Normal file
12
sources/app/controllers/NodeController.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class NodeController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
$this->public = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.groups'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/NotfoundController.php
Normal file
11
sources/app/controllers/NotfoundController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class NotfoundController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.not_found', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
13
sources/app/controllers/PodsController.php
Normal file
13
sources/app/controllers/PodsController.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Discover the other Movim Pods using the Movim API
|
||||||
|
*/
|
||||||
|
class PodsController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('title.discover', APP_TITLE));
|
||||||
|
}
|
||||||
|
}
|
10
sources/app/controllers/RoomController.php
Normal file
10
sources/app/controllers/RoomController.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class RoomController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.room'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/ShareController.php
Normal file
11
sources/app/controllers/ShareController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ShareController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.share'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/TagController.php
Normal file
11
sources/app/controllers/TagController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class TagController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
$this->page->setTitle(__('page.tag'));
|
||||||
|
}
|
||||||
|
}
|
11
sources/app/controllers/VisioController.php
Normal file
11
sources/app/controllers/VisioController.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class VisioController extends BaseController {
|
||||||
|
function load() {
|
||||||
|
$this->session_only = true;
|
||||||
|
$this->raw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch() {
|
||||||
|
}
|
||||||
|
}
|
98
sources/app/helpers/DateHelper.php
Normal file
98
sources/app/helpers/DateHelper.php
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human-readable week
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getDays() {
|
||||||
|
return array(
|
||||||
|
1 => __('day.monday'),
|
||||||
|
2 => __('day.tuesday'),
|
||||||
|
3 => __('day.wednesday'),
|
||||||
|
4 => __('day.thursday'),
|
||||||
|
5 => __('day.friday'),
|
||||||
|
6 => __('day.saturday'),
|
||||||
|
7 => __('day.sunday'));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return a human-readable year
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getMonths() {
|
||||||
|
return array(
|
||||||
|
1 => __('month.january'),
|
||||||
|
2 => __('month.february'),
|
||||||
|
3 => __('month.march'),
|
||||||
|
4 => __('month.april'),
|
||||||
|
5 => __('month.may'),
|
||||||
|
6 => __('month.june'),
|
||||||
|
7 => __('month.july'),
|
||||||
|
8 => __('month.august'),
|
||||||
|
9 => __('month.september'),
|
||||||
|
10 => __('month.october'),
|
||||||
|
11 => __('month.november'),
|
||||||
|
12 => __('month.december'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimezoneCorrection() {
|
||||||
|
$timezones = getTimezoneList();
|
||||||
|
return $timezones[date_default_timezone_get()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human-readable date
|
||||||
|
*
|
||||||
|
* @param timestamp $string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function prepareDate($time, $hours = true, $compact = false) {
|
||||||
|
// We had the server timezone
|
||||||
|
$time = $time + TIMEZONE_OFFSET;
|
||||||
|
|
||||||
|
$t = $time ? $time : time();
|
||||||
|
|
||||||
|
$date = '';
|
||||||
|
|
||||||
|
$reldays = ((time() - $t)-(time()%86400))/86400;
|
||||||
|
// if $time is within a week
|
||||||
|
if($reldays < 7 && $reldays >= -2){
|
||||||
|
//if $time is today or yesterday
|
||||||
|
if($reldays < -1) {
|
||||||
|
$date = __('date.tomorrow');
|
||||||
|
} else if ($reldays <= 0) {
|
||||||
|
//$date = __('date.today');
|
||||||
|
} else if ($reldays <= 1) {
|
||||||
|
$date = __('date.yesterday');
|
||||||
|
}
|
||||||
|
//else print date "ago"
|
||||||
|
else {
|
||||||
|
$date = __('date.ago', ceil($reldays));
|
||||||
|
|
||||||
|
//if($compact) return $date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else print full date
|
||||||
|
else {
|
||||||
|
$date = '';
|
||||||
|
|
||||||
|
if(!$compact)
|
||||||
|
$date .= __('day.'.strtolower(date('l', $t))) . ', ';
|
||||||
|
|
||||||
|
$date .= date('j', $t).' '.__('month.'.strtolower(date('F', $t)));
|
||||||
|
|
||||||
|
//if over 6months print year
|
||||||
|
if (abs($reldays) > 182)
|
||||||
|
$date .= date(', Y', $t);
|
||||||
|
|
||||||
|
if($compact) return $date;
|
||||||
|
}
|
||||||
|
//if $hours option print the time
|
||||||
|
if($hours) {
|
||||||
|
if($date != '') {
|
||||||
|
$date .= ' - ';
|
||||||
|
}
|
||||||
|
$date .= date('H:i', $time);
|
||||||
|
}
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
|
401
sources/app/helpers/StringHelper.php
Normal file
401
sources/app/helpers/StringHelper.php
Normal file
|
@ -0,0 +1,401 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use HeyUpdate\Emoji\Emoji;
|
||||||
|
use HeyUpdate\Emoji\EmojiIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc A singleton wrapper for the Emoji library
|
||||||
|
*/
|
||||||
|
class MovimEmoji
|
||||||
|
{
|
||||||
|
protected static $instance = null;
|
||||||
|
private $_emoji;
|
||||||
|
private $_theme;
|
||||||
|
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$cd = new \Modl\ConfigDAO();
|
||||||
|
$config = $cd->get();
|
||||||
|
$this->_theme = $config->theme;
|
||||||
|
|
||||||
|
$this->_emoji = new Emoji(new EmojiIndex(), $this->getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function replace($string, $large = false)
|
||||||
|
{
|
||||||
|
$this->_emoji->setAssetUrlFormat($this->getPath());
|
||||||
|
$string = $this->_emoji->replaceEmojiWithImages($string);
|
||||||
|
$this->_emoji->setAssetUrlFormat($this->getPath());
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPath($large = false)
|
||||||
|
{
|
||||||
|
return BASE_URI . 'themes/' . $this->_theme . '/img/emojis/svg/%s.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
if (!isset(static::$instance)) {
|
||||||
|
static::$instance = new MovimEmoji;
|
||||||
|
}
|
||||||
|
return static::$instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addUrls($string, $preview = false) {
|
||||||
|
// Add missing links
|
||||||
|
return preg_replace_callback(
|
||||||
|
"/([\w\"'>]+\:\/\/[\w-?'&;#+,%:~=\.\/\@]+)/u", function ($match) use($preview) {
|
||||||
|
if(!in_array(substr($match[0], 0, 1), array('>', '"', '\''))) {
|
||||||
|
$content = $match[0];
|
||||||
|
|
||||||
|
if($preview) {
|
||||||
|
try {
|
||||||
|
$embed = Embed\Embed::create($match[0]);
|
||||||
|
if($embed->type == 'photo'
|
||||||
|
&& $embed->images[0]['width'] <= 1024
|
||||||
|
&& $embed->images[0]['height'] <= 1024) {
|
||||||
|
$content = '<img src="'.$match[0].'"/>';
|
||||||
|
} elseif($embed->type == 'link') {
|
||||||
|
$content .= ' - '. $embed->title . ' - ' . $embed->providerName;
|
||||||
|
}
|
||||||
|
} catch(Exception $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stripslashes('<a href=\"'.$match[0].'\" target=\"_blank\">'.$content.'</a>');
|
||||||
|
} else {
|
||||||
|
return $match[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}, $string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addHFR($string) {
|
||||||
|
// HFR EasterEgg
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/\[:([\w\s-]+)([:\d])*\]/', function ($match) {
|
||||||
|
$num = '';
|
||||||
|
if(count($match) == 3)
|
||||||
|
$num = $match[2].'/';
|
||||||
|
return '<img class="hfr" title="'.$match[0].'" alt="'.$match[0].'" src="http://forum-images.hardware.fr/images/perso/'.$num.$match[1].'.gif"/>';
|
||||||
|
}, $string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc Prepare the string (add the a to the links and show the smileys)
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param boolean display large emojis
|
||||||
|
* @param check the links and convert them to pictures (heavy)
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function prepareString($string, $large = false, $preview = false) {
|
||||||
|
$string = addUrls($string, $preview);
|
||||||
|
|
||||||
|
// We remove all the style attributes
|
||||||
|
/*$string = preg_replace_callback(
|
||||||
|
'/(<[^>]+) style=".*?"/i', function($match) {
|
||||||
|
return $match[1];
|
||||||
|
}, $string
|
||||||
|
);
|
||||||
|
|
||||||
|
// Twitter hashtags
|
||||||
|
$string = preg_replace_callback(
|
||||||
|
"/ #[a-zA-Z0-9_-]{3,}/", function ($match) { return ' <a class="twitter hastag" href="http://twitter.com/search?q='. urlencode(trim($match[0])). '&src=hash" target="_blank">'. trim($match[0]). '</a>'; }, ' ' . $string);
|
||||||
|
$string = preg_replace_callback(
|
||||||
|
"/ @[a-zA-Z0-9_-]{3,}/", function ($match) {
|
||||||
|
return
|
||||||
|
' <a class="twitter at" href="http://twitter.com/'.
|
||||||
|
trim($match[0]).
|
||||||
|
'" target="_blank">'.
|
||||||
|
trim($match[0]).
|
||||||
|
'</a>';
|
||||||
|
}, ' ' . $string
|
||||||
|
);
|
||||||
|
|
||||||
|
//remove all scripts
|
||||||
|
$string = preg_replace_callback(
|
||||||
|
'#<[/]?script[^>]*>#is', function ($match) {
|
||||||
|
return '';
|
||||||
|
}, ' ' . $string
|
||||||
|
);
|
||||||
|
//remove all iframe
|
||||||
|
$string = preg_replace_callback(
|
||||||
|
'#<[/]?iframe[^>]*>#is', function ($match) {
|
||||||
|
return '';
|
||||||
|
}, ' ' . $string
|
||||||
|
);
|
||||||
|
//remove all iframe
|
||||||
|
$string = preg_replace_callback(
|
||||||
|
'#<[/]?ss[^>]*>#is', function ($match) {
|
||||||
|
return '';
|
||||||
|
}, ' ' . $string
|
||||||
|
);*/
|
||||||
|
|
||||||
|
// We add some smileys...
|
||||||
|
$emoji = MovimEmoji::getInstance();
|
||||||
|
$string = $emoji->replace($string, $large);
|
||||||
|
|
||||||
|
return trim($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix self-closing tags
|
||||||
|
*/
|
||||||
|
function fixSelfClosing($string) {
|
||||||
|
return preg_replace_callback('/<([^\s<]+)\/>/',
|
||||||
|
function($match) {
|
||||||
|
return '<'.$match[1].'></'.$match[1].'>';
|
||||||
|
}
|
||||||
|
, $string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the content, body and html tags
|
||||||
|
*/
|
||||||
|
function cleanHTMLTags($string) {
|
||||||
|
return str_replace(
|
||||||
|
array(
|
||||||
|
'<content type="html">',
|
||||||
|
'<html xmlns="http://jabber.org/protocol/xhtml-im">',
|
||||||
|
'<body xmlns="http://www.w3.org/1999/xhtml">',
|
||||||
|
'</body>',
|
||||||
|
'</html>',
|
||||||
|
'</content>'),
|
||||||
|
'',
|
||||||
|
$string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of informations from a XMPP uri
|
||||||
|
*/
|
||||||
|
function explodeURI($uri) {
|
||||||
|
$arr = parse_url(urldecode($uri));
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
if(isset($arr['query'])) {
|
||||||
|
$query = explode(';', $arr['query']);
|
||||||
|
|
||||||
|
|
||||||
|
foreach($query as $elt) {
|
||||||
|
if($elt != '') {
|
||||||
|
list($key, $val) = explode('=', $elt);
|
||||||
|
$result[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = array_merge($arr, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Echap the JID
|
||||||
|
*/
|
||||||
|
function echapJid($jid)
|
||||||
|
{
|
||||||
|
return str_replace(' ', '\40', $jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Echap the anti-slashs for Javascript
|
||||||
|
*/
|
||||||
|
function echapJS($string)
|
||||||
|
{
|
||||||
|
return str_replace("\\", "\\\\", $string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean the resource of a jid
|
||||||
|
*/
|
||||||
|
function cleanJid($jid)
|
||||||
|
{
|
||||||
|
$explode = explode('/', $jid);
|
||||||
|
return reset($explode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the CID
|
||||||
|
*/
|
||||||
|
function getCid($string)
|
||||||
|
{
|
||||||
|
preg_match("/(\w+)\@/", $string, $matches);
|
||||||
|
if(is_array($matches)) {
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Explode JID
|
||||||
|
*/
|
||||||
|
function explodeJid($jid)
|
||||||
|
{
|
||||||
|
$arr = explode('/', $jid);
|
||||||
|
$jid = $arr[0];
|
||||||
|
|
||||||
|
if(isset($arr[1])) $resource = $arr[1];
|
||||||
|
else $resource = null;
|
||||||
|
|
||||||
|
$server = '';
|
||||||
|
|
||||||
|
$arr = explode('@', $jid);
|
||||||
|
$username = $arr[0];
|
||||||
|
if(isset($arr[1])) $server = $arr[1];
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'username' => $username,
|
||||||
|
'server' => $server,
|
||||||
|
'resource' => $resource
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a URIfied string
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function stringToUri($url) {
|
||||||
|
$url = utf8_decode($url);
|
||||||
|
$url = strtolower(strtr($url, utf8_decode('ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ()[]\'"~$&%*@ç!?;,:/\^¨€{}<>|+- .'), 'aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn -- c --- e --_'));
|
||||||
|
$url = str_replace(' ', '', $url);
|
||||||
|
$url = str_replace('---', '-', $url);
|
||||||
|
$url = str_replace('--', '-', $url);
|
||||||
|
$url = trim($url,'-');
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human readable filesize
|
||||||
|
* @param string size in bytes
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function sizeToCleanSize($size)
|
||||||
|
{
|
||||||
|
$units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
||||||
|
$power = $size > 0 ? floor(log($size, 1024)) : 0;
|
||||||
|
return number_format($size / pow(1024, $power), 7, '.', ',') . ' ' . $units[$power];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a colored string in the console
|
||||||
|
* @param string
|
||||||
|
* @param color
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function colorize($string, $color) {
|
||||||
|
$colors = array(
|
||||||
|
'black' => 30,
|
||||||
|
'red' => 31,
|
||||||
|
'green' => 32,
|
||||||
|
'yellow' => 33,
|
||||||
|
'blue' => 34,
|
||||||
|
'purple' => 35,
|
||||||
|
'turquoise' => 36,
|
||||||
|
'white' => 37
|
||||||
|
);
|
||||||
|
|
||||||
|
return "\033[".$colors[$color]."m".$string."\033[0m";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a color generated from the string
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function stringToColor($string) {
|
||||||
|
$colors = array(
|
||||||
|
0 => 'red',
|
||||||
|
1 => 'purple',
|
||||||
|
2 => 'indigo',
|
||||||
|
3 => 'blue',
|
||||||
|
4 => 'green',
|
||||||
|
5 => 'orange',
|
||||||
|
6 => 'yellow',
|
||||||
|
7 => 'brown');
|
||||||
|
|
||||||
|
$s = substr(base_convert(sha1($string), 15, 10), 0, 10);
|
||||||
|
|
||||||
|
if($colors[$s%8]) {
|
||||||
|
return $colors[$s%8];
|
||||||
|
} else {
|
||||||
|
return 'orange';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip tags and add a whitespace
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function stripTags($string)
|
||||||
|
{
|
||||||
|
return strip_tags(preg_replace('/(<\/[^>]+?>)(<[^>\/][^>]*?>)/', '$1 $2', $string));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purify a string
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function purifyHTML($string)
|
||||||
|
{
|
||||||
|
$config = \HTMLPurifier_Config::createDefault();
|
||||||
|
$config->set('HTML.Doctype', 'XHTML 1.1');
|
||||||
|
$config->set('Cache.SerializerPath', '/tmp');
|
||||||
|
$config->set('HTML.DefinitionID', 'html5-definitions');
|
||||||
|
$config->set('HTML.DefinitionRev', 1);
|
||||||
|
if ($def = $config->maybeGetRawHTMLDefinition()) {
|
||||||
|
$def->addElement('video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array(
|
||||||
|
'src' => 'URI',
|
||||||
|
'type' => 'Text',
|
||||||
|
'width' => 'Length',
|
||||||
|
'height' => 'Length',
|
||||||
|
'poster' => 'URI',
|
||||||
|
'preload' => 'Enum#auto,metadata,none',
|
||||||
|
'controls' => 'Bool',
|
||||||
|
));
|
||||||
|
$def->addElement('audio', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array(
|
||||||
|
'src' => 'URI',
|
||||||
|
'preload' => 'Enum#auto,metadata,none',
|
||||||
|
'muted' => 'Bool',
|
||||||
|
'controls' => 'Bool',
|
||||||
|
));
|
||||||
|
$def->addElement('source', 'Block', 'Flow', 'Common', array(
|
||||||
|
'src' => 'URI',
|
||||||
|
'type' => 'Text',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$purifier = new \HTMLPurifier($config);
|
||||||
|
return $purifier->purify($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the first two letters of a string
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function firstLetterCapitalize($string) {
|
||||||
|
return ucfirst(strtolower(mb_substr($string, 0, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncates the given string at the specified length.
|
||||||
|
*
|
||||||
|
* @param string $str The input string.
|
||||||
|
* @param int $width The number of chars at which the string will be truncated.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function truncate($str, $width) {
|
||||||
|
return strtok(wordwrap($str, $width, "…\n"), "\n");
|
||||||
|
}
|
93
sources/app/helpers/TimezoneHelper.php
Normal file
93
sources/app/helpers/TimezoneHelper.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the timezone list
|
||||||
|
*/
|
||||||
|
function getTimezoneList()
|
||||||
|
{
|
||||||
|
global $timezones;
|
||||||
|
require_once(HELPERS_PATH.'TimezoneList.php');
|
||||||
|
return $timezones;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the offset of a timezone
|
||||||
|
*/
|
||||||
|
function getTimezoneOffset($timezone)
|
||||||
|
{
|
||||||
|
$tz = new DateTimeZone($timezone);
|
||||||
|
$utc = new DateTimeZone('UTC');
|
||||||
|
return $tz->getOffset(new DateTime('now', $utc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the timezone list
|
||||||
|
*/
|
||||||
|
function generateTimezoneList()
|
||||||
|
{
|
||||||
|
$regions = array(
|
||||||
|
DateTimeZone::AFRICA,
|
||||||
|
DateTimeZone::AMERICA,
|
||||||
|
DateTimeZone::ANTARCTICA,
|
||||||
|
DateTimeZone::ASIA,
|
||||||
|
DateTimeZone::ATLANTIC,
|
||||||
|
DateTimeZone::AUSTRALIA,
|
||||||
|
DateTimeZone::EUROPE,
|
||||||
|
DateTimeZone::INDIAN,
|
||||||
|
DateTimeZone::PACIFIC,
|
||||||
|
);
|
||||||
|
|
||||||
|
$timezones = array();
|
||||||
|
foreach( $regions as $region )
|
||||||
|
{
|
||||||
|
$timezones = array_merge( $timezones, DateTimeZone::listIdentifiers( $region ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$timezone_offsets = array();
|
||||||
|
foreach( $timezones as $timezone )
|
||||||
|
{
|
||||||
|
$tz = new DateTimeZone($timezone);
|
||||||
|
$utc = new DateTimeZone('UTC');
|
||||||
|
$timezone_offsets[$timezone] = $tz->getOffset(new DateTime('now', $utc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort timezone by timezone name
|
||||||
|
ksort($timezone_offsets);
|
||||||
|
|
||||||
|
$timezone_list = array();
|
||||||
|
foreach( $timezone_offsets as $timezone => $offset )
|
||||||
|
{
|
||||||
|
$offset_prefix = $offset < 0 ? '-' : '+';
|
||||||
|
$offset_formatted = gmdate( 'H:i', abs($offset) );
|
||||||
|
|
||||||
|
$pretty_offset = "UTC${offset_prefix}${offset_formatted}";
|
||||||
|
|
||||||
|
$split = explode("/", $timezone);
|
||||||
|
|
||||||
|
$timezone_list[$timezone] = "$split[1]/$split[0] (${pretty_offset})";
|
||||||
|
}
|
||||||
|
|
||||||
|
asort($timezone_list);
|
||||||
|
|
||||||
|
return $timezone_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the user local timezone
|
||||||
|
*/
|
||||||
|
function getLocalTimezone()
|
||||||
|
{
|
||||||
|
date_default_timezone_set('UTC');
|
||||||
|
$iTime = time();
|
||||||
|
$arr = localtime($iTime);
|
||||||
|
$arr[5] += 1900;
|
||||||
|
$arr[4]++;
|
||||||
|
$iTztime = gmmktime($arr[2], $arr[1], $arr[0], $arr[4], $arr[3], $arr[5]);
|
||||||
|
$offset = doubleval(($iTztime-$iTime)/(60*60));
|
||||||
|
$zonelist = getTimezoneList();
|
||||||
|
|
||||||
|
$index = array_keys($zonelist, $offset);
|
||||||
|
if(sizeof($index)!=1)
|
||||||
|
return false;
|
||||||
|
return $index[0];
|
||||||
|
}
|
417
sources/app/helpers/TimezoneList.php
Normal file
417
sources/app/helpers/TimezoneList.php
Normal file
|
@ -0,0 +1,417 @@
|
||||||
|
<?php global $timezones;
|
||||||
|
$timezones = array("Africa/Abidjan" => "Abidjan/Africa (UTC+00:00)",
|
||||||
|
"Africa/Accra" => "Accra/Africa (UTC+00:00)",
|
||||||
|
"America/Adak" => "Adak/America (UTC-09:00)",
|
||||||
|
"Africa/Addis_Ababa" => "Addis_Ababa/Africa (UTC+03:00)",
|
||||||
|
"Australia/Adelaide" => "Adelaide/Australia (UTC+09:30)",
|
||||||
|
"Asia/Aden" => "Aden/Asia (UTC+03:00)",
|
||||||
|
"Africa/Algiers" => "Algiers/Africa (UTC+01:00)",
|
||||||
|
"Asia/Almaty" => "Almaty/Asia (UTC+06:00)",
|
||||||
|
"Asia/Amman" => "Amman/Asia (UTC+03:00)",
|
||||||
|
"Europe/Amsterdam" => "Amsterdam/Europe (UTC+02:00)",
|
||||||
|
"Asia/Anadyr" => "Anadyr/Asia (UTC+12:00)",
|
||||||
|
"America/Anchorage" => "Anchorage/America (UTC-08:00)",
|
||||||
|
"Europe/Andorra" => "Andorra/Europe (UTC+02:00)",
|
||||||
|
"America/Anguilla" => "Anguilla/America (UTC-04:00)",
|
||||||
|
"Indian/Antananarivo" => "Antananarivo/Indian (UTC+03:00)",
|
||||||
|
"America/Antigua" => "Antigua/America (UTC-04:00)",
|
||||||
|
"Pacific/Apia" => "Apia/Pacific (UTC+13:00)",
|
||||||
|
"Asia/Aqtau" => "Aqtau/Asia (UTC+05:00)",
|
||||||
|
"Asia/Aqtobe" => "Aqtobe/Asia (UTC+05:00)",
|
||||||
|
"America/Araguaina" => "Araguaina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Buenos_Aires" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Rio_Gallegos" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/San_Luis" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Tucuman" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Ushuaia" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Salta" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Mendoza" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Cordoba" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Jujuy" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/La_Rioja" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/Catamarca" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Argentina/San_Juan" => "Argentina/America (UTC-03:00)",
|
||||||
|
"America/Aruba" => "Aruba/America (UTC-04:00)",
|
||||||
|
"Asia/Ashgabat" => "Ashgabat/Asia (UTC+05:00)",
|
||||||
|
"Africa/Asmara" => "Asmara/Africa (UTC+03:00)",
|
||||||
|
"America/Asuncion" => "Asuncion/America (UTC-04:00)",
|
||||||
|
"Europe/Athens" => "Athens/Europe (UTC+03:00)",
|
||||||
|
"America/Atikokan" => "Atikokan/America (UTC-05:00)",
|
||||||
|
"Pacific/Auckland" => "Auckland/Pacific (UTC+12:00)",
|
||||||
|
"Atlantic/Azores" => "Azores/Atlantic (UTC+00:00)",
|
||||||
|
"Asia/Baghdad" => "Baghdad/Asia (UTC+03:00)",
|
||||||
|
"America/Bahia" => "Bahia/America (UTC-03:00)",
|
||||||
|
"America/Bahia_Banderas" => "Bahia_Banderas/America (UTC-05:00)",
|
||||||
|
"Asia/Bahrain" => "Bahrain/Asia (UTC+03:00)",
|
||||||
|
"Asia/Baku" => "Baku/Asia (UTC+05:00)",
|
||||||
|
"Africa/Bamako" => "Bamako/Africa (UTC+00:00)",
|
||||||
|
"Asia/Bangkok" => "Bangkok/Asia (UTC+07:00)",
|
||||||
|
"Africa/Bangui" => "Bangui/Africa (UTC+01:00)",
|
||||||
|
"Africa/Banjul" => "Banjul/Africa (UTC+00:00)",
|
||||||
|
"America/Barbados" => "Barbados/America (UTC-04:00)",
|
||||||
|
"Asia/Beirut" => "Beirut/Asia (UTC+03:00)",
|
||||||
|
"America/Belem" => "Belem/America (UTC-03:00)",
|
||||||
|
"Europe/Belgrade" => "Belgrade/Europe (UTC+02:00)",
|
||||||
|
"America/Belize" => "Belize/America (UTC-06:00)",
|
||||||
|
"Europe/Berlin" => "Berlin/Europe (UTC+02:00)",
|
||||||
|
"Atlantic/Bermuda" => "Bermuda/Atlantic (UTC-03:00)",
|
||||||
|
"Asia/Bishkek" => "Bishkek/Asia (UTC+06:00)",
|
||||||
|
"Africa/Bissau" => "Bissau/Africa (UTC+00:00)",
|
||||||
|
"America/Blanc-Sablon" => "Blanc-Sablon/America (UTC-04:00)",
|
||||||
|
"Africa/Blantyre" => "Blantyre/Africa (UTC+02:00)",
|
||||||
|
"America/Boa_Vista" => "Boa_Vista/America (UTC-04:00)",
|
||||||
|
"America/Bogota" => "Bogota/America (UTC-05:00)",
|
||||||
|
"America/Boise" => "Boise/America (UTC-06:00)",
|
||||||
|
"Europe/Bratislava" => "Bratislava/Europe (UTC+02:00)",
|
||||||
|
"Africa/Brazzaville" => "Brazzaville/Africa (UTC+01:00)",
|
||||||
|
"Australia/Brisbane" => "Brisbane/Australia (UTC+10:00)",
|
||||||
|
"Australia/Broken_Hill" => "Broken_Hill/Australia (UTC+09:30)",
|
||||||
|
"Asia/Brunei" => "Brunei/Asia (UTC+08:00)",
|
||||||
|
"Europe/Brussels" => "Brussels/Europe (UTC+02:00)",
|
||||||
|
"Europe/Bucharest" => "Bucharest/Europe (UTC+03:00)",
|
||||||
|
"Europe/Budapest" => "Budapest/Europe (UTC+02:00)",
|
||||||
|
"Africa/Bujumbura" => "Bujumbura/Africa (UTC+02:00)",
|
||||||
|
"Europe/Busingen" => "Busingen/Europe (UTC+02:00)",
|
||||||
|
"Africa/Cairo" => "Cairo/Africa (UTC+03:00)",
|
||||||
|
"America/Cambridge_Bay" => "Cambridge_Bay/America (UTC-06:00)",
|
||||||
|
"America/Campo_Grande" => "Campo_Grande/America (UTC-04:00)",
|
||||||
|
"Atlantic/Canary" => "Canary/Atlantic (UTC+01:00)",
|
||||||
|
"America/Cancun" => "Cancun/America (UTC-05:00)",
|
||||||
|
"Atlantic/Cape_Verde" => "Cape_Verde/Atlantic (UTC-01:00)",
|
||||||
|
"America/Caracas" => "Caracas/America (UTC-04:30)",
|
||||||
|
"Africa/Casablanca" => "Casablanca/Africa (UTC+01:00)",
|
||||||
|
"Antarctica/Casey" => "Casey/Antarctica (UTC+08:00)",
|
||||||
|
"America/Cayenne" => "Cayenne/America (UTC-03:00)",
|
||||||
|
"America/Cayman" => "Cayman/America (UTC-05:00)",
|
||||||
|
"Africa/Ceuta" => "Ceuta/Africa (UTC+02:00)",
|
||||||
|
"Indian/Chagos" => "Chagos/Indian (UTC+06:00)",
|
||||||
|
"Pacific/Chatham" => "Chatham/Pacific (UTC+12:45)",
|
||||||
|
"America/Chicago" => "Chicago/America (UTC-05:00)",
|
||||||
|
"America/Chihuahua" => "Chihuahua/America (UTC-06:00)",
|
||||||
|
"Europe/Chisinau" => "Chisinau/Europe (UTC+03:00)",
|
||||||
|
"Asia/Choibalsan" => "Choibalsan/Asia (UTC+08:00)",
|
||||||
|
"Asia/Chongqing" => "Chongqing/Asia (UTC+08:00)",
|
||||||
|
"Indian/Christmas" => "Christmas/Indian (UTC+07:00)",
|
||||||
|
"Pacific/Chuuk" => "Chuuk/Pacific (UTC+10:00)",
|
||||||
|
"Indian/Cocos" => "Cocos/Indian (UTC+06:30)",
|
||||||
|
"Asia/Colombo" => "Colombo/Asia (UTC+05:30)",
|
||||||
|
"Indian/Comoro" => "Comoro/Indian (UTC+03:00)",
|
||||||
|
"Africa/Conakry" => "Conakry/Africa (UTC+00:00)",
|
||||||
|
"Europe/Copenhagen" => "Copenhagen/Europe (UTC+02:00)",
|
||||||
|
"America/Costa_Rica" => "Costa_Rica/America (UTC-06:00)",
|
||||||
|
"America/Creston" => "Creston/America (UTC-07:00)",
|
||||||
|
"America/Cuiaba" => "Cuiaba/America (UTC-04:00)",
|
||||||
|
"America/Curacao" => "Curacao/America (UTC-04:00)",
|
||||||
|
"Australia/Currie" => "Currie/Australia (UTC+10:00)",
|
||||||
|
"Africa/Dakar" => "Dakar/Africa (UTC+00:00)",
|
||||||
|
"Asia/Damascus" => "Damascus/Asia (UTC+03:00)",
|
||||||
|
"America/Danmarkshavn" => "Danmarkshavn/America (UTC+00:00)",
|
||||||
|
"Africa/Dar_es_Salaam" => "Dar_es_Salaam/Africa (UTC+03:00)",
|
||||||
|
"Australia/Darwin" => "Darwin/Australia (UTC+09:30)",
|
||||||
|
"Antarctica/Davis" => "Davis/Antarctica (UTC+07:00)",
|
||||||
|
"America/Dawson" => "Dawson/America (UTC-07:00)",
|
||||||
|
"America/Dawson_Creek" => "Dawson_Creek/America (UTC-07:00)",
|
||||||
|
"America/Denver" => "Denver/America (UTC-06:00)",
|
||||||
|
"America/Detroit" => "Detroit/America (UTC-04:00)",
|
||||||
|
"Asia/Dhaka" => "Dhaka/Asia (UTC+06:00)",
|
||||||
|
"Asia/Dili" => "Dili/Asia (UTC+09:00)",
|
||||||
|
"Africa/Djibouti" => "Djibouti/Africa (UTC+03:00)",
|
||||||
|
"America/Dominica" => "Dominica/America (UTC-04:00)",
|
||||||
|
"Africa/Douala" => "Douala/Africa (UTC+01:00)",
|
||||||
|
"Asia/Dubai" => "Dubai/Asia (UTC+04:00)",
|
||||||
|
"Europe/Dublin" => "Dublin/Europe (UTC+01:00)",
|
||||||
|
"Antarctica/DumontDUrville" => "DumontDUrville/Antarctica (UTC+10:00)",
|
||||||
|
"Asia/Dushanbe" => "Dushanbe/Asia (UTC+05:00)",
|
||||||
|
"Pacific/Easter" => "Easter/Pacific (UTC-06:00)",
|
||||||
|
"America/Edmonton" => "Edmonton/America (UTC-06:00)",
|
||||||
|
"Pacific/Efate" => "Efate/Pacific (UTC+11:00)",
|
||||||
|
"America/Eirunepe" => "Eirunepe/America (UTC-05:00)",
|
||||||
|
"Africa/El_Aaiun" => "El_Aaiun/Africa (UTC+01:00)",
|
||||||
|
"America/El_Salvador" => "El_Salvador/America (UTC-06:00)",
|
||||||
|
"Pacific/Enderbury" => "Enderbury/Pacific (UTC+13:00)",
|
||||||
|
"Australia/Eucla" => "Eucla/Australia (UTC+08:45)",
|
||||||
|
"Pacific/Fakaofo" => "Fakaofo/Pacific (UTC+13:00)",
|
||||||
|
"Atlantic/Faroe" => "Faroe/Atlantic (UTC+01:00)",
|
||||||
|
"Pacific/Fiji" => "Fiji/Pacific (UTC+12:00)",
|
||||||
|
"America/Fortaleza" => "Fortaleza/America (UTC-03:00)",
|
||||||
|
"Africa/Freetown" => "Freetown/Africa (UTC+00:00)",
|
||||||
|
"Pacific/Funafuti" => "Funafuti/Pacific (UTC+12:00)",
|
||||||
|
"Africa/Gaborone" => "Gaborone/Africa (UTC+02:00)",
|
||||||
|
"Pacific/Galapagos" => "Galapagos/Pacific (UTC-06:00)",
|
||||||
|
"Pacific/Gambier" => "Gambier/Pacific (UTC-09:00)",
|
||||||
|
"Asia/Gaza" => "Gaza/Asia (UTC+03:00)",
|
||||||
|
"Europe/Gibraltar" => "Gibraltar/Europe (UTC+02:00)",
|
||||||
|
"America/Glace_Bay" => "Glace_Bay/America (UTC-03:00)",
|
||||||
|
"America/Godthab" => "Godthab/America (UTC-02:00)",
|
||||||
|
"America/Goose_Bay" => "Goose_Bay/America (UTC-03:00)",
|
||||||
|
"America/Grand_Turk" => "Grand_Turk/America (UTC-04:00)",
|
||||||
|
"America/Grenada" => "Grenada/America (UTC-04:00)",
|
||||||
|
"Pacific/Guadalcanal" => "Guadalcanal/Pacific (UTC+11:00)",
|
||||||
|
"America/Guadeloupe" => "Guadeloupe/America (UTC-04:00)",
|
||||||
|
"Pacific/Guam" => "Guam/Pacific (UTC+10:00)",
|
||||||
|
"America/Guatemala" => "Guatemala/America (UTC-06:00)",
|
||||||
|
"America/Guayaquil" => "Guayaquil/America (UTC-05:00)",
|
||||||
|
"Europe/Guernsey" => "Guernsey/Europe (UTC+01:00)",
|
||||||
|
"America/Guyana" => "Guyana/America (UTC-04:00)",
|
||||||
|
"America/Halifax" => "Halifax/America (UTC-03:00)",
|
||||||
|
"Africa/Harare" => "Harare/Africa (UTC+02:00)",
|
||||||
|
"Asia/Harbin" => "Harbin/Asia (UTC+08:00)",
|
||||||
|
"America/Havana" => "Havana/America (UTC-04:00)",
|
||||||
|
"Asia/Hebron" => "Hebron/Asia (UTC+03:00)",
|
||||||
|
"Europe/Helsinki" => "Helsinki/Europe (UTC+03:00)",
|
||||||
|
"America/Hermosillo" => "Hermosillo/America (UTC-07:00)",
|
||||||
|
"Asia/Ho_Chi_Minh" => "Ho_Chi_Minh/Asia (UTC+07:00)",
|
||||||
|
"Australia/Hobart" => "Hobart/Australia (UTC+10:00)",
|
||||||
|
"Asia/Hong_Kong" => "Hong_Kong/Asia (UTC+08:00)",
|
||||||
|
"Pacific/Honolulu" => "Honolulu/Pacific (UTC-10:00)",
|
||||||
|
"Asia/Hovd" => "Hovd/Asia (UTC+07:00)",
|
||||||
|
"America/Indiana/Vincennes" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Winamac" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Indianapolis" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Marengo" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Petersburg" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Vevay" => "Indiana/America (UTC-04:00)",
|
||||||
|
"America/Indiana/Knox" => "Indiana/America (UTC-05:00)",
|
||||||
|
"America/Indiana/Tell_City" => "Indiana/America (UTC-05:00)",
|
||||||
|
"America/Inuvik" => "Inuvik/America (UTC-06:00)",
|
||||||
|
"America/Iqaluit" => "Iqaluit/America (UTC-04:00)",
|
||||||
|
"Asia/Irkutsk" => "Irkutsk/Asia (UTC+09:00)",
|
||||||
|
"Europe/Isle_of_Man" => "Isle_of_Man/Europe (UTC+01:00)",
|
||||||
|
"Europe/Istanbul" => "Istanbul/Europe (UTC+03:00)",
|
||||||
|
"Asia/Jakarta" => "Jakarta/Asia (UTC+07:00)",
|
||||||
|
"America/Jamaica" => "Jamaica/America (UTC-05:00)",
|
||||||
|
"Asia/Jayapura" => "Jayapura/Asia (UTC+09:00)",
|
||||||
|
"Europe/Jersey" => "Jersey/Europe (UTC+01:00)",
|
||||||
|
"Asia/Jerusalem" => "Jerusalem/Asia (UTC+03:00)",
|
||||||
|
"Africa/Johannesburg" => "Johannesburg/Africa (UTC+02:00)",
|
||||||
|
"Pacific/Johnston" => "Johnston/Pacific (UTC-10:00)",
|
||||||
|
"Africa/Juba" => "Juba/Africa (UTC+03:00)",
|
||||||
|
"America/Juneau" => "Juneau/America (UTC-08:00)",
|
||||||
|
"Asia/Kabul" => "Kabul/Asia (UTC+04:30)",
|
||||||
|
"Europe/Kaliningrad" => "Kaliningrad/Europe (UTC+03:00)",
|
||||||
|
"Asia/Kamchatka" => "Kamchatka/Asia (UTC+12:00)",
|
||||||
|
"Africa/Kampala" => "Kampala/Africa (UTC+03:00)",
|
||||||
|
"Asia/Karachi" => "Karachi/Asia (UTC+05:00)",
|
||||||
|
"Asia/Kashgar" => "Kashgar/Asia (UTC+08:00)",
|
||||||
|
"Asia/Kathmandu" => "Kathmandu/Asia (UTC+05:45)",
|
||||||
|
"America/Kentucky/Monticello" => "Kentucky/America (UTC-04:00)",
|
||||||
|
"America/Kentucky/Louisville" => "Kentucky/America (UTC-04:00)",
|
||||||
|
"Indian/Kerguelen" => "Kerguelen/Indian (UTC+05:00)",
|
||||||
|
"Asia/Khandyga" => "Khandyga/Asia (UTC+10:00)",
|
||||||
|
"Africa/Khartoum" => "Khartoum/Africa (UTC+03:00)",
|
||||||
|
"Europe/Kiev" => "Kiev/Europe (UTC+03:00)",
|
||||||
|
"Africa/Kigali" => "Kigali/Africa (UTC+02:00)",
|
||||||
|
"Africa/Kinshasa" => "Kinshasa/Africa (UTC+01:00)",
|
||||||
|
"Pacific/Kiritimati" => "Kiritimati/Pacific (UTC+14:00)",
|
||||||
|
"Asia/Kolkata" => "Kolkata/Asia (UTC+05:30)",
|
||||||
|
"Pacific/Kosrae" => "Kosrae/Pacific (UTC+11:00)",
|
||||||
|
"America/Kralendijk" => "Kralendijk/America (UTC-04:00)",
|
||||||
|
"Asia/Krasnoyarsk" => "Krasnoyarsk/Asia (UTC+08:00)",
|
||||||
|
"Asia/Kuala_Lumpur" => "Kuala_Lumpur/Asia (UTC+08:00)",
|
||||||
|
"Asia/Kuching" => "Kuching/Asia (UTC+08:00)",
|
||||||
|
"Asia/Kuwait" => "Kuwait/Asia (UTC+03:00)",
|
||||||
|
"Pacific/Kwajalein" => "Kwajalein/Pacific (UTC+12:00)",
|
||||||
|
"America/La_Paz" => "La_Paz/America (UTC-04:00)",
|
||||||
|
"Africa/Lagos" => "Lagos/Africa (UTC+01:00)",
|
||||||
|
"Africa/Libreville" => "Libreville/Africa (UTC+01:00)",
|
||||||
|
"America/Lima" => "Lima/America (UTC-05:00)",
|
||||||
|
"Australia/Lindeman" => "Lindeman/Australia (UTC+10:00)",
|
||||||
|
"Europe/Lisbon" => "Lisbon/Europe (UTC+01:00)",
|
||||||
|
"Europe/Ljubljana" => "Ljubljana/Europe (UTC+02:00)",
|
||||||
|
"Africa/Lome" => "Lome/Africa (UTC+00:00)",
|
||||||
|
"Europe/London" => "London/Europe (UTC+01:00)",
|
||||||
|
"Australia/Lord_Howe" => "Lord_Howe/Australia (UTC+10:30)",
|
||||||
|
"America/Los_Angeles" => "Los_Angeles/America (UTC-07:00)",
|
||||||
|
"America/Lower_Princes" => "Lower_Princes/America (UTC-04:00)",
|
||||||
|
"Africa/Luanda" => "Luanda/Africa (UTC+01:00)",
|
||||||
|
"Africa/Lubumbashi" => "Lubumbashi/Africa (UTC+02:00)",
|
||||||
|
"Africa/Lusaka" => "Lusaka/Africa (UTC+02:00)",
|
||||||
|
"Europe/Luxembourg" => "Luxembourg/Europe (UTC+02:00)",
|
||||||
|
"Asia/Macau" => "Macau/Asia (UTC+08:00)",
|
||||||
|
"America/Maceio" => "Maceio/America (UTC-03:00)",
|
||||||
|
"Antarctica/Macquarie" => "Macquarie/Antarctica (UTC+11:00)",
|
||||||
|
"Atlantic/Madeira" => "Madeira/Atlantic (UTC+01:00)",
|
||||||
|
"Europe/Madrid" => "Madrid/Europe (UTC+02:00)",
|
||||||
|
"Asia/Magadan" => "Magadan/Asia (UTC+12:00)",
|
||||||
|
"Indian/Mahe" => "Mahe/Indian (UTC+04:00)",
|
||||||
|
"Pacific/Majuro" => "Majuro/Pacific (UTC+12:00)",
|
||||||
|
"Asia/Makassar" => "Makassar/Asia (UTC+08:00)",
|
||||||
|
"Africa/Malabo" => "Malabo/Africa (UTC+01:00)",
|
||||||
|
"Indian/Maldives" => "Maldives/Indian (UTC+05:00)",
|
||||||
|
"Europe/Malta" => "Malta/Europe (UTC+02:00)",
|
||||||
|
"America/Managua" => "Managua/America (UTC-06:00)",
|
||||||
|
"America/Manaus" => "Manaus/America (UTC-04:00)",
|
||||||
|
"Asia/Manila" => "Manila/Asia (UTC+08:00)",
|
||||||
|
"Africa/Maputo" => "Maputo/Africa (UTC+02:00)",
|
||||||
|
"Europe/Mariehamn" => "Mariehamn/Europe (UTC+03:00)",
|
||||||
|
"America/Marigot" => "Marigot/America (UTC-04:00)",
|
||||||
|
"Pacific/Marquesas" => "Marquesas/Pacific (UTC-09:30)",
|
||||||
|
"America/Martinique" => "Martinique/America (UTC-04:00)",
|
||||||
|
"Africa/Maseru" => "Maseru/Africa (UTC+02:00)",
|
||||||
|
"America/Matamoros" => "Matamoros/America (UTC-05:00)",
|
||||||
|
"Indian/Mauritius" => "Mauritius/Indian (UTC+04:00)",
|
||||||
|
"Antarctica/Mawson" => "Mawson/Antarctica (UTC+05:00)",
|
||||||
|
"Indian/Mayotte" => "Mayotte/Indian (UTC+03:00)",
|
||||||
|
"America/Mazatlan" => "Mazatlan/America (UTC-06:00)",
|
||||||
|
"Africa/Mbabane" => "Mbabane/Africa (UTC+02:00)",
|
||||||
|
"Antarctica/McMurdo" => "McMurdo/Antarctica (UTC+12:00)",
|
||||||
|
"Australia/Melbourne" => "Melbourne/Australia (UTC+10:00)",
|
||||||
|
"America/Menominee" => "Menominee/America (UTC-05:00)",
|
||||||
|
"America/Merida" => "Merida/America (UTC-05:00)",
|
||||||
|
"America/Metlakatla" => "Metlakatla/America (UTC-08:00)",
|
||||||
|
"America/Mexico_City" => "Mexico_City/America (UTC-05:00)",
|
||||||
|
"Pacific/Midway" => "Midway/Pacific (UTC-11:00)",
|
||||||
|
"Europe/Minsk" => "Minsk/Europe (UTC+03:00)",
|
||||||
|
"America/Miquelon" => "Miquelon/America (UTC-02:00)",
|
||||||
|
"Africa/Mogadishu" => "Mogadishu/Africa (UTC+03:00)",
|
||||||
|
"Europe/Monaco" => "Monaco/Europe (UTC+02:00)",
|
||||||
|
"America/Moncton" => "Moncton/America (UTC-03:00)",
|
||||||
|
"Africa/Monrovia" => "Monrovia/Africa (UTC+00:00)",
|
||||||
|
"America/Monterrey" => "Monterrey/America (UTC-05:00)",
|
||||||
|
"America/Montevideo" => "Montevideo/America (UTC-03:00)",
|
||||||
|
"America/Montserrat" => "Montserrat/America (UTC-04:00)",
|
||||||
|
"Europe/Moscow" => "Moscow/Europe (UTC+04:00)",
|
||||||
|
"Asia/Muscat" => "Muscat/Asia (UTC+04:00)",
|
||||||
|
"Africa/Nairobi" => "Nairobi/Africa (UTC+03:00)",
|
||||||
|
"America/Nassau" => "Nassau/America (UTC-04:00)",
|
||||||
|
"Pacific/Nauru" => "Nauru/Pacific (UTC+12:00)",
|
||||||
|
"Africa/Ndjamena" => "Ndjamena/Africa (UTC+01:00)",
|
||||||
|
"America/New_York" => "New_York/America (UTC-04:00)",
|
||||||
|
"Africa/Niamey" => "Niamey/Africa (UTC+01:00)",
|
||||||
|
"Asia/Nicosia" => "Nicosia/Asia (UTC+03:00)",
|
||||||
|
"America/Nipigon" => "Nipigon/America (UTC-04:00)",
|
||||||
|
"Pacific/Niue" => "Niue/Pacific (UTC-11:00)",
|
||||||
|
"America/Nome" => "Nome/America (UTC-08:00)",
|
||||||
|
"Pacific/Norfolk" => "Norfolk/Pacific (UTC+11:30)",
|
||||||
|
"America/Noronha" => "Noronha/America (UTC-02:00)",
|
||||||
|
"America/North_Dakota/Center" => "North_Dakota/America (UTC-05:00)",
|
||||||
|
"America/North_Dakota/Beulah" => "North_Dakota/America (UTC-05:00)",
|
||||||
|
"America/North_Dakota/New_Salem" => "North_Dakota/America (UTC-05:00)",
|
||||||
|
"Africa/Nouakchott" => "Nouakchott/Africa (UTC+00:00)",
|
||||||
|
"Pacific/Noumea" => "Noumea/Pacific (UTC+11:00)",
|
||||||
|
"Asia/Novokuznetsk" => "Novokuznetsk/Asia (UTC+07:00)",
|
||||||
|
"Asia/Novosibirsk" => "Novosibirsk/Asia (UTC+07:00)",
|
||||||
|
"America/Ojinaga" => "Ojinaga/America (UTC-06:00)",
|
||||||
|
"Asia/Omsk" => "Omsk/Asia (UTC+07:00)",
|
||||||
|
"Asia/Oral" => "Oral/Asia (UTC+05:00)",
|
||||||
|
"Europe/Oslo" => "Oslo/Europe (UTC+02:00)",
|
||||||
|
"Africa/Ouagadougou" => "Ouagadougou/Africa (UTC+00:00)",
|
||||||
|
"Pacific/Pago_Pago" => "Pago_Pago/Pacific (UTC-11:00)",
|
||||||
|
"Pacific/Palau" => "Palau/Pacific (UTC+09:00)",
|
||||||
|
"Antarctica/Palmer" => "Palmer/Antarctica (UTC-04:00)",
|
||||||
|
"America/Panama" => "Panama/America (UTC-05:00)",
|
||||||
|
"America/Pangnirtung" => "Pangnirtung/America (UTC-04:00)",
|
||||||
|
"America/Paramaribo" => "Paramaribo/America (UTC-03:00)",
|
||||||
|
"Europe/Paris" => "Paris/Europe (UTC+02:00)",
|
||||||
|
"Australia/Perth" => "Perth/Australia (UTC+08:00)",
|
||||||
|
"Asia/Phnom_Penh" => "Phnom_Penh/Asia (UTC+07:00)",
|
||||||
|
"America/Phoenix" => "Phoenix/America (UTC-07:00)",
|
||||||
|
"Pacific/Pitcairn" => "Pitcairn/Pacific (UTC-08:00)",
|
||||||
|
"Europe/Podgorica" => "Podgorica/Europe (UTC+02:00)",
|
||||||
|
"Pacific/Pohnpei" => "Pohnpei/Pacific (UTC+11:00)",
|
||||||
|
"Asia/Pontianak" => "Pontianak/Asia (UTC+07:00)",
|
||||||
|
"America/Port-au-Prince" => "Port-au-Prince/America (UTC-04:00)",
|
||||||
|
"Pacific/Port_Moresby" => "Port_Moresby/Pacific (UTC+10:00)",
|
||||||
|
"America/Port_of_Spain" => "Port_of_Spain/America (UTC-04:00)",
|
||||||
|
"Africa/Porto-Novo" => "Porto-Novo/Africa (UTC+01:00)",
|
||||||
|
"America/Porto_Velho" => "Porto_Velho/America (UTC-04:00)",
|
||||||
|
"Europe/Prague" => "Prague/Europe (UTC+02:00)",
|
||||||
|
"America/Puerto_Rico" => "Puerto_Rico/America (UTC-04:00)",
|
||||||
|
"Asia/Pyongyang" => "Pyongyang/Asia (UTC+09:00)",
|
||||||
|
"Asia/Qatar" => "Qatar/Asia (UTC+03:00)",
|
||||||
|
"Asia/Qyzylorda" => "Qyzylorda/Asia (UTC+06:00)",
|
||||||
|
"America/Rainy_River" => "Rainy_River/America (UTC-05:00)",
|
||||||
|
"Asia/Rangoon" => "Rangoon/Asia (UTC+06:30)",
|
||||||
|
"America/Rankin_Inlet" => "Rankin_Inlet/America (UTC-05:00)",
|
||||||
|
"Pacific/Rarotonga" => "Rarotonga/Pacific (UTC-10:00)",
|
||||||
|
"America/Recife" => "Recife/America (UTC-03:00)",
|
||||||
|
"America/Regina" => "Regina/America (UTC-06:00)",
|
||||||
|
"America/Resolute" => "Resolute/America (UTC-05:00)",
|
||||||
|
"Indian/Reunion" => "Reunion/Indian (UTC+04:00)",
|
||||||
|
"Atlantic/Reykjavik" => "Reykjavik/Atlantic (UTC+00:00)",
|
||||||
|
"Europe/Riga" => "Riga/Europe (UTC+03:00)",
|
||||||
|
"America/Rio_Branco" => "Rio_Branco/America (UTC-05:00)",
|
||||||
|
"Asia/Riyadh" => "Riyadh/Asia (UTC+03:00)",
|
||||||
|
"Europe/Rome" => "Rome/Europe (UTC+02:00)",
|
||||||
|
"Antarctica/Rothera" => "Rothera/Antarctica (UTC-03:00)",
|
||||||
|
"Pacific/Saipan" => "Saipan/Pacific (UTC+10:00)",
|
||||||
|
"Asia/Sakhalin" => "Sakhalin/Asia (UTC+11:00)",
|
||||||
|
"Europe/Samara" => "Samara/Europe (UTC+04:00)",
|
||||||
|
"Asia/Samarkand" => "Samarkand/Asia (UTC+05:00)",
|
||||||
|
"Europe/San_Marino" => "San_Marino/Europe (UTC+02:00)",
|
||||||
|
"America/Santa_Isabel" => "Santa_Isabel/America (UTC-07:00)",
|
||||||
|
"America/Santarem" => "Santarem/America (UTC-03:00)",
|
||||||
|
"America/Santiago" => "Santiago/America (UTC-04:00)",
|
||||||
|
"America/Santo_Domingo" => "Santo_Domingo/America (UTC-04:00)",
|
||||||
|
"America/Sao_Paulo" => "Sao_Paulo/America (UTC-03:00)",
|
||||||
|
"Africa/Sao_Tome" => "Sao_Tome/Africa (UTC+00:00)",
|
||||||
|
"Europe/Sarajevo" => "Sarajevo/Europe (UTC+02:00)",
|
||||||
|
"America/Scoresbysund" => "Scoresbysund/America (UTC+00:00)",
|
||||||
|
"Asia/Seoul" => "Seoul/Asia (UTC+09:00)",
|
||||||
|
"Asia/Shanghai" => "Shanghai/Asia (UTC+08:00)",
|
||||||
|
"Europe/Simferopol" => "Simferopol/Europe (UTC+04:00)",
|
||||||
|
"Asia/Singapore" => "Singapore/Asia (UTC+08:00)",
|
||||||
|
"America/Sitka" => "Sitka/America (UTC-08:00)",
|
||||||
|
"Europe/Skopje" => "Skopje/Europe (UTC+02:00)",
|
||||||
|
"Europe/Sofia" => "Sofia/Europe (UTC+03:00)",
|
||||||
|
"Atlantic/South_Georgia" => "South_Georgia/Atlantic (UTC-02:00)",
|
||||||
|
"America/St_Barthelemy" => "St_Barthelemy/America (UTC-04:00)",
|
||||||
|
"Atlantic/St_Helena" => "St_Helena/Atlantic (UTC+00:00)",
|
||||||
|
"America/St_Johns" => "St_Johns/America (UTC-02:30)",
|
||||||
|
"America/St_Kitts" => "St_Kitts/America (UTC-04:00)",
|
||||||
|
"America/St_Lucia" => "St_Lucia/America (UTC-04:00)",
|
||||||
|
"America/St_Thomas" => "St_Thomas/America (UTC-04:00)",
|
||||||
|
"America/St_Vincent" => "St_Vincent/America (UTC-04:00)",
|
||||||
|
"Atlantic/Stanley" => "Stanley/Atlantic (UTC-03:00)",
|
||||||
|
"Europe/Stockholm" => "Stockholm/Europe (UTC+02:00)",
|
||||||
|
"America/Swift_Current" => "Swift_Current/America (UTC-06:00)",
|
||||||
|
"Australia/Sydney" => "Sydney/Australia (UTC+10:00)",
|
||||||
|
"Antarctica/Syowa" => "Syowa/Antarctica (UTC+03:00)",
|
||||||
|
"Pacific/Tahiti" => "Tahiti/Pacific (UTC-10:00)",
|
||||||
|
"Asia/Taipei" => "Taipei/Asia (UTC+08:00)",
|
||||||
|
"Europe/Tallinn" => "Tallinn/Europe (UTC+03:00)",
|
||||||
|
"Pacific/Tarawa" => "Tarawa/Pacific (UTC+12:00)",
|
||||||
|
"Asia/Tashkent" => "Tashkent/Asia (UTC+05:00)",
|
||||||
|
"Asia/Tbilisi" => "Tbilisi/Asia (UTC+04:00)",
|
||||||
|
"America/Tegucigalpa" => "Tegucigalpa/America (UTC-06:00)",
|
||||||
|
"Asia/Tehran" => "Tehran/Asia (UTC+04:30)",
|
||||||
|
"Asia/Thimphu" => "Thimphu/Asia (UTC+06:00)",
|
||||||
|
"America/Thule" => "Thule/America (UTC-03:00)",
|
||||||
|
"America/Thunder_Bay" => "Thunder_Bay/America (UTC-04:00)",
|
||||||
|
"America/Tijuana" => "Tijuana/America (UTC-07:00)",
|
||||||
|
"Europe/Tirane" => "Tirane/Europe (UTC+02:00)",
|
||||||
|
"Asia/Tokyo" => "Tokyo/Asia (UTC+09:00)",
|
||||||
|
"Pacific/Tongatapu" => "Tongatapu/Pacific (UTC+13:00)",
|
||||||
|
"America/Toronto" => "Toronto/America (UTC-04:00)",
|
||||||
|
"America/Tortola" => "Tortola/America (UTC-04:00)",
|
||||||
|
"Africa/Tripoli" => "Tripoli/Africa (UTC+02:00)",
|
||||||
|
"Antarctica/Troll" => "Troll/Antarctica (UTC+02:00)",
|
||||||
|
"Africa/Tunis" => "Tunis/Africa (UTC+01:00)",
|
||||||
|
"Asia/Ulaanbaatar" => "Ulaanbaatar/Asia (UTC+08:00)",
|
||||||
|
"Asia/Urumqi" => "Urumqi/Asia (UTC+08:00)",
|
||||||
|
"Asia/Ust-Nera" => "Ust-Nera/Asia (UTC+11:00)",
|
||||||
|
"Europe/Uzhgorod" => "Uzhgorod/Europe (UTC+03:00)",
|
||||||
|
"Europe/Vaduz" => "Vaduz/Europe (UTC+02:00)",
|
||||||
|
"America/Vancouver" => "Vancouver/America (UTC-07:00)",
|
||||||
|
"Europe/Vatican" => "Vatican/Europe (UTC+02:00)",
|
||||||
|
"Europe/Vienna" => "Vienna/Europe (UTC+02:00)",
|
||||||
|
"Asia/Vientiane" => "Vientiane/Asia (UTC+07:00)",
|
||||||
|
"Europe/Vilnius" => "Vilnius/Europe (UTC+03:00)",
|
||||||
|
"Asia/Vladivostok" => "Vladivostok/Asia (UTC+11:00)",
|
||||||
|
"Europe/Volgograd" => "Volgograd/Europe (UTC+04:00)",
|
||||||
|
"Antarctica/Vostok" => "Vostok/Antarctica (UTC+06:00)",
|
||||||
|
"Pacific/Wake" => "Wake/Pacific (UTC+12:00)",
|
||||||
|
"Pacific/Wallis" => "Wallis/Pacific (UTC+12:00)",
|
||||||
|
"Europe/Warsaw" => "Warsaw/Europe (UTC+02:00)",
|
||||||
|
"America/Whitehorse" => "Whitehorse/America (UTC-07:00)",
|
||||||
|
"Africa/Windhoek" => "Windhoek/Africa (UTC+01:00)",
|
||||||
|
"America/Winnipeg" => "Winnipeg/America (UTC-05:00)",
|
||||||
|
"America/Yakutat" => "Yakutat/America (UTC-08:00)",
|
||||||
|
"Asia/Yakutsk" => "Yakutsk/Asia (UTC+10:00)",
|
||||||
|
"Asia/Yekaterinburg" => "Yekaterinburg/Asia (UTC+06:00)",
|
||||||
|
"America/Yellowknife" => "Yellowknife/America (UTC-06:00)",
|
||||||
|
"Asia/Yerevan" => "Yerevan/Asia (UTC+04:00)",
|
||||||
|
"Europe/Zagreb" => "Zagreb/Europe (UTC+02:00)",
|
||||||
|
"Europe/Zaporozhye" => "Zaporozhye/Europe (UTC+03:00)",
|
||||||
|
"Europe/Zurich" => "Zurich/Europe (UTC+02:00)",
|
||||||
|
);
|
26
sources/app/models/cache/Cache.php
vendored
Normal file
26
sources/app/models/cache/Cache.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Cache extends Model{
|
||||||
|
public $session;
|
||||||
|
public $name;
|
||||||
|
public $data;
|
||||||
|
public $timestamp;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"session" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"name" :
|
||||||
|
{"type":"string", "size":32, "key":true },
|
||||||
|
"data" :
|
||||||
|
{"type":"text", "mandatory":true },
|
||||||
|
"timestamp" :
|
||||||
|
{"type":"date", "mandatory":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
}
|
63
sources/app/models/cache/CacheDAO.php
vendored
Normal file
63
sources/app/models/cache/CacheDAO.php
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class CacheDAO extends SQL {
|
||||||
|
function get($session, $key) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from cache
|
||||||
|
where
|
||||||
|
session = :session
|
||||||
|
and name = :name';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Cache',
|
||||||
|
array(
|
||||||
|
'session' => $session,
|
||||||
|
'name' => $key
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Cache', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(Cache $cache) {
|
||||||
|
$this->_sql = '
|
||||||
|
update cache
|
||||||
|
set data = :data,
|
||||||
|
timestamp = :timestamp
|
||||||
|
where session = :session
|
||||||
|
and name = :name';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Cache',
|
||||||
|
array(
|
||||||
|
'session' => $cache->session,
|
||||||
|
'data' => $cache->data,
|
||||||
|
'timestamp' => $cache->timestamp,
|
||||||
|
'name' => $cache->name
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Cache');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into cache
|
||||||
|
(session, name, data, timestamp)
|
||||||
|
values (:session, :name, :data, :timestamp)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Cache',
|
||||||
|
array(
|
||||||
|
'session' => $cache->session,
|
||||||
|
'name' => $cache->name,
|
||||||
|
'data' => $cache->data,
|
||||||
|
'timestamp' => $cache->timestamp
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Cache');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
sources/app/models/caps/Caps.php
Normal file
53
sources/app/models/caps/Caps.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Caps extends Model {
|
||||||
|
public $node;
|
||||||
|
public $category;
|
||||||
|
public $type;
|
||||||
|
public $name;
|
||||||
|
public $features;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":128, "key":true },
|
||||||
|
"category" :
|
||||||
|
{"type":"string", "size":16, "mandatory":true },
|
||||||
|
"type" :
|
||||||
|
{"type":"string", "size":16, "mandatory":true },
|
||||||
|
"name" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true },
|
||||||
|
"features" :
|
||||||
|
{"type":"text", "mandatory":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($query, $node = false) {
|
||||||
|
if(!$node)
|
||||||
|
$this->node = (string)$query->query->attributes()->node;
|
||||||
|
else
|
||||||
|
$this->node = $node;
|
||||||
|
|
||||||
|
if(isset($query->query)) {
|
||||||
|
foreach($query->query->identity as $i) {
|
||||||
|
if($i->attributes()
|
||||||
|
&& $i->attributes()->name) {
|
||||||
|
$this->category = (string)$i->attributes()->category;
|
||||||
|
$this->type = (string)$i->attributes()->type;
|
||||||
|
$this->name = (string)$i->attributes()->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fet = array();
|
||||||
|
foreach($query->query->feature as $f) {
|
||||||
|
array_push($fet, (string)$f->attributes()->var);
|
||||||
|
}
|
||||||
|
$this->features = serialize($fet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
sources/app/models/caps/CapsDAO.php
Normal file
117
sources/app/models/caps/CapsDAO.php
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class CapsDAO extends SQL {
|
||||||
|
function get($node) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from caps
|
||||||
|
where
|
||||||
|
node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps',
|
||||||
|
array(
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Caps', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClients() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from caps
|
||||||
|
where category = :category';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps',
|
||||||
|
array(
|
||||||
|
'category' => 'client'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Caps');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServers() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from caps
|
||||||
|
where category = :category';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps',
|
||||||
|
array(
|
||||||
|
'category' => 'server'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Caps');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from caps';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Caps');
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(Caps $caps) {
|
||||||
|
$this->_sql = '
|
||||||
|
update caps
|
||||||
|
set category = :category,
|
||||||
|
type = :type,
|
||||||
|
name = :name,
|
||||||
|
features = :features
|
||||||
|
where node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps',
|
||||||
|
array(
|
||||||
|
'node' => $caps->node,
|
||||||
|
'category' => $caps->category,
|
||||||
|
'type' => $caps->type,
|
||||||
|
'name' => $caps->name,
|
||||||
|
'features' => $caps->features,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Caps');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into caps
|
||||||
|
(
|
||||||
|
node,
|
||||||
|
category,
|
||||||
|
type,
|
||||||
|
name,
|
||||||
|
features
|
||||||
|
)
|
||||||
|
values(
|
||||||
|
:node,
|
||||||
|
:category,
|
||||||
|
:type,
|
||||||
|
:name,
|
||||||
|
:features
|
||||||
|
)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Caps',
|
||||||
|
array(
|
||||||
|
'node' => $caps->node,
|
||||||
|
'category' => $caps->category,
|
||||||
|
'type' => $caps->type,
|
||||||
|
'name' => $caps->name,
|
||||||
|
'features' => $caps->features,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Caps');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
sources/app/models/conference/Conference.php
Normal file
34
sources/app/models/conference/Conference.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Conference extends Model {
|
||||||
|
public $jid;
|
||||||
|
protected $conference;
|
||||||
|
protected $name;
|
||||||
|
protected $nick;
|
||||||
|
public $autojoin;
|
||||||
|
public $status;
|
||||||
|
|
||||||
|
public $connected = false;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":128, "key":true },
|
||||||
|
"conference" :
|
||||||
|
{"type":"string", "size":128, "key":true },
|
||||||
|
"name" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true },
|
||||||
|
"nick" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"autojoin" :
|
||||||
|
{"type":"int", "size":1 },
|
||||||
|
"status" :
|
||||||
|
{"type":"int", "size":1 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
}
|
163
sources/app/models/conference/ConferenceDAO.php
Normal file
163
sources/app/models/conference/ConferenceDAO.php
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class ConferenceDAO extends SQL {
|
||||||
|
function set(Conference $c) {
|
||||||
|
$this->_sql = '
|
||||||
|
update conference
|
||||||
|
set name = :name,
|
||||||
|
nick = :nick,
|
||||||
|
autojoin = :autojoin,
|
||||||
|
status = :status
|
||||||
|
where jid = :jid
|
||||||
|
and conference= :conference';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $c->jid,
|
||||||
|
'conference' => $c->conference,
|
||||||
|
'name' => $c->name,
|
||||||
|
'nick' => $c->nick,
|
||||||
|
'autojoin' => $c->autojoin,
|
||||||
|
'status' => $c->status
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Conference');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into conference
|
||||||
|
(jid, conference, name, nick, autojoin, status)
|
||||||
|
values (:jid, :conference, :name, :nick, :autojoin, :status)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $c->jid,
|
||||||
|
'conference' => $c->conference,
|
||||||
|
'name' => $c->name,
|
||||||
|
'nick' => $c->nick,
|
||||||
|
'autojoin' => $c->autojoin,
|
||||||
|
'status' => $c->status
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Conference');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($conference) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from conference
|
||||||
|
where jid = :jid
|
||||||
|
and conference= :conference';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'conference' => $conference,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Conference', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from conference
|
||||||
|
where jid = :jid
|
||||||
|
order by conference';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Conference');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConnected() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from conference
|
||||||
|
where jid = :jid
|
||||||
|
and status= 1';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Conference');
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
function getSubscribed() {
|
||||||
|
$this->_sql = '
|
||||||
|
select
|
||||||
|
subscription.jid,
|
||||||
|
subscription.server,
|
||||||
|
subscription.node,
|
||||||
|
subscription,
|
||||||
|
name
|
||||||
|
from subscription
|
||||||
|
left outer join item
|
||||||
|
on item.server = subscription.server
|
||||||
|
and item.node = subscription.node
|
||||||
|
where subscription.jid = :jid
|
||||||
|
group by
|
||||||
|
subscription.server,
|
||||||
|
subscription.node,
|
||||||
|
subscription.jid,
|
||||||
|
subscription, item.name
|
||||||
|
order by
|
||||||
|
subscription.server';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
function delete() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from conference
|
||||||
|
where jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('conference');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNode($conference) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from conference
|
||||||
|
where jid = :jid
|
||||||
|
and conference= :conference';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Conference',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'conference' => $conference
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Conference');
|
||||||
|
}
|
||||||
|
}
|
63
sources/app/models/config/Config.php
Normal file
63
sources/app/models/config/Config.php
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modl;
|
||||||
|
|
||||||
|
class Config extends Model {
|
||||||
|
public $description;
|
||||||
|
public $theme;
|
||||||
|
public $locale;
|
||||||
|
public $maxusers;
|
||||||
|
public $loglevel;
|
||||||
|
public $timezone;
|
||||||
|
public $xmppwhitelist;
|
||||||
|
public $info;
|
||||||
|
public $unregister;
|
||||||
|
public $username;
|
||||||
|
public $password;
|
||||||
|
public $sizelimit;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
{"type":"text" },
|
||||||
|
"theme" :
|
||||||
|
{"type":"string", "size":32, "mandatory":true },
|
||||||
|
"locale" :
|
||||||
|
{"type":"string", "size":8, "mandatory":true },
|
||||||
|
"maxusers" :
|
||||||
|
{"type":"int", "size":16 },
|
||||||
|
"loglevel" :
|
||||||
|
{"type":"string", "size":16, "mandatory":true },
|
||||||
|
"timezone" :
|
||||||
|
{"type":"string", "size":32, "mandatory":true },
|
||||||
|
"xmppwhitelist" :
|
||||||
|
{"type":"text" },
|
||||||
|
"info" :
|
||||||
|
{"type":"text" },
|
||||||
|
"unregister" :
|
||||||
|
{"type":"int", "size":1 },
|
||||||
|
"username" :
|
||||||
|
{"type":"string", "size":32, "mandatory":true },
|
||||||
|
"password" :
|
||||||
|
{"type":"string", "size":64, "mandatory":true },
|
||||||
|
"sizelimit" :
|
||||||
|
{"type":"int", "size":16 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->description = 'Description';//__('global.description');
|
||||||
|
$this->theme = 'material';
|
||||||
|
$this->locale = 'en';
|
||||||
|
$this->maxusers = -1;
|
||||||
|
$this->loglevel = 'empty';
|
||||||
|
$this->timezone = 'Etc/GMT';
|
||||||
|
$this->xmppwhitelist = '';
|
||||||
|
$this->info = '';
|
||||||
|
$this->unregister = false;
|
||||||
|
$this->username = 'admin';
|
||||||
|
$this->password = sha1('password');
|
||||||
|
$this->sizelimit = 20240001;
|
||||||
|
}
|
||||||
|
}
|
122
sources/app/models/config/ConfigDAO.php
Normal file
122
sources/app/models/config/ConfigDAO.php
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modl;
|
||||||
|
|
||||||
|
class ConfigDAO extends SQL {
|
||||||
|
function set(Config $c) {
|
||||||
|
$this->_sql = '
|
||||||
|
update config
|
||||||
|
set description = :description,
|
||||||
|
theme = :theme,
|
||||||
|
locale = :locale,
|
||||||
|
maxusers = :maxusers,
|
||||||
|
loglevel = :loglevel,
|
||||||
|
timezone = :timezone,
|
||||||
|
xmppwhitelist = :xmppwhitelist,
|
||||||
|
info = :info,
|
||||||
|
unregister = :unregister,
|
||||||
|
username = :username,
|
||||||
|
password = :password,
|
||||||
|
sizelimit = :sizelimit';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Config',
|
||||||
|
array(
|
||||||
|
'description' => $c->description,
|
||||||
|
'theme' => $c->theme,
|
||||||
|
'locale' => $c->locale,
|
||||||
|
'maxusers' => $c->maxusers,
|
||||||
|
'loglevel' => $c->loglevel,
|
||||||
|
'timezone' => $c->timezone,
|
||||||
|
'xmppwhitelist'=> $c->xmppwhitelist,
|
||||||
|
'info' => $c->info,
|
||||||
|
'unregister' => $c->unregister,
|
||||||
|
'username' => $c->username,
|
||||||
|
'password' => $c->password,
|
||||||
|
'sizelimit' => $c->sizelimit
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Config');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
truncate table config;';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Config',
|
||||||
|
array(
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Config');
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
insert into config
|
||||||
|
(
|
||||||
|
description,
|
||||||
|
theme,
|
||||||
|
locale,
|
||||||
|
maxusers,
|
||||||
|
loglevel,
|
||||||
|
timezone,
|
||||||
|
xmppwhitelist,
|
||||||
|
info,
|
||||||
|
unregister,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
sizelimit
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
:description,
|
||||||
|
:theme,
|
||||||
|
:locale,
|
||||||
|
:maxusers,
|
||||||
|
:loglevel,
|
||||||
|
:timezone,
|
||||||
|
:xmppwhitelist,
|
||||||
|
:info,
|
||||||
|
:unregister,
|
||||||
|
:username,
|
||||||
|
:password,
|
||||||
|
:sizelimit
|
||||||
|
)
|
||||||
|
';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Config',
|
||||||
|
array(
|
||||||
|
'description' => $c->description,
|
||||||
|
'theme' => $c->theme,
|
||||||
|
'locale' => $c->locale,
|
||||||
|
'maxusers' => $c->maxusers,
|
||||||
|
'loglevel' => $c->loglevel,
|
||||||
|
'timezone' => $c->timezone,
|
||||||
|
'xmppwhitelist'=> $c->xmppwhitelist,
|
||||||
|
'info' => $c->info,
|
||||||
|
'unregister' => $c->unregister,
|
||||||
|
'username' => $c->username,
|
||||||
|
'password' => $c->password,
|
||||||
|
'sizelimit' => $c->sizelimit
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Config');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from config';
|
||||||
|
|
||||||
|
$this->prepare('Config');
|
||||||
|
|
||||||
|
$conf = $this->run('Config', 'item');
|
||||||
|
|
||||||
|
if(!isset($conf))
|
||||||
|
return new Config;
|
||||||
|
|
||||||
|
return $conf;
|
||||||
|
}
|
||||||
|
}
|
585
sources/app/models/contact/Contact.php
Normal file
585
sources/app/models/contact/Contact.php
Normal file
|
@ -0,0 +1,585 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
use Respect\Validation\Validator;
|
||||||
|
|
||||||
|
class Contact extends Model {
|
||||||
|
public $jid;
|
||||||
|
|
||||||
|
protected $fn;
|
||||||
|
protected $name;
|
||||||
|
protected $date;
|
||||||
|
protected $url;
|
||||||
|
|
||||||
|
public $email;
|
||||||
|
|
||||||
|
protected $adrlocality;
|
||||||
|
protected $adrpostalcode;
|
||||||
|
protected $adrcountry;
|
||||||
|
|
||||||
|
protected $gender;
|
||||||
|
protected $marital;
|
||||||
|
|
||||||
|
protected $photobin;
|
||||||
|
|
||||||
|
protected $description;
|
||||||
|
|
||||||
|
protected $protected;
|
||||||
|
protected $privacy;
|
||||||
|
|
||||||
|
// User Mood (contain serialized array) - XEP 0107
|
||||||
|
protected $mood;
|
||||||
|
|
||||||
|
// User Activity (contain serialized array) - XEP 0108
|
||||||
|
protected $activity;
|
||||||
|
|
||||||
|
// User Nickname - XEP 0172
|
||||||
|
protected $nickname;
|
||||||
|
|
||||||
|
// User Tune - XEP 0118
|
||||||
|
protected $tuneartist;
|
||||||
|
protected $tunelenght;
|
||||||
|
protected $tunerating;
|
||||||
|
protected $tunesource;
|
||||||
|
protected $tunetitle;
|
||||||
|
protected $tunetrack;
|
||||||
|
|
||||||
|
// User Location
|
||||||
|
protected $loclatitude;
|
||||||
|
protected $loclongitude;
|
||||||
|
protected $localtitude;
|
||||||
|
protected $loccountry;
|
||||||
|
protected $loccountrycode;
|
||||||
|
protected $locregion;
|
||||||
|
protected $locpostalcode;
|
||||||
|
protected $loclocality;
|
||||||
|
protected $locstreet;
|
||||||
|
protected $locbuilding;
|
||||||
|
protected $loctext;
|
||||||
|
protected $locuri;
|
||||||
|
protected $loctimestamp;
|
||||||
|
|
||||||
|
// Accounts
|
||||||
|
protected $twitter;
|
||||||
|
protected $skype;
|
||||||
|
protected $yahoo;
|
||||||
|
|
||||||
|
protected $avatarhash;
|
||||||
|
|
||||||
|
// Datetime
|
||||||
|
public $created;
|
||||||
|
public $updated;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"fn" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"name" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"date" :
|
||||||
|
{"type":"date", "size":11 },
|
||||||
|
"url" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"email" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"adrlocality" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"adrpostalcode" :
|
||||||
|
{"type":"string", "size":12 },
|
||||||
|
"adrcountry" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"gender" :
|
||||||
|
{"type":"string", "size":1 },
|
||||||
|
"marital" :
|
||||||
|
{"type":"string", "size":16 },
|
||||||
|
"description" :
|
||||||
|
{"type":"text"},
|
||||||
|
"mood" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"activity" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"nickname" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"tuneartist" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"tunelenght" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"tunerating" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"tunesource" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"tunetitle" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"tunetrack" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"loclatitude" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"loclongitude" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"localtitude" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"loccountry" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"loccountrycode" :
|
||||||
|
{"type":"string", "size":2 },
|
||||||
|
"locregion" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"locpostalcode" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"loclocality" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"locstreet" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"locbuilding" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"loctext" :
|
||||||
|
{"type":"text" },
|
||||||
|
"locuri" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"loctimestamp" :
|
||||||
|
{"type":"date", "size":11 },
|
||||||
|
"twitter" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"skype" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"yahoo" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"avatarhash" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"created" :
|
||||||
|
{"type":"date", "mandatory":true },
|
||||||
|
"updated" :
|
||||||
|
{"type":"date", "mandatory":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($vcard, $jid) {
|
||||||
|
$this->__set('jid', \echapJid($jid));
|
||||||
|
|
||||||
|
$validate_date = Validator::date('Y-m-d');
|
||||||
|
if(isset($vcard->vCard->BDAY)
|
||||||
|
&& $validate_date->validate($vcard->vCard->BDAY))
|
||||||
|
$this->__set('date', (string)$vcard->vCard->BDAY);
|
||||||
|
|
||||||
|
$this->__set('date', date(DATE_ISO8601, strtotime($this->date)));
|
||||||
|
|
||||||
|
$this->__set('name', (string)$vcard->vCard->NICKNAME);
|
||||||
|
$this->__set('fn', (string)$vcard->vCard->FN);
|
||||||
|
$this->__set('url', (string)$vcard->vCard->URL);
|
||||||
|
|
||||||
|
$this->__set('gender', (string)$vcard->vCard->{'X-GENDER'});
|
||||||
|
$this->__set('marital', (string)$vcard->vCard->MARITAL->STATUS);
|
||||||
|
|
||||||
|
$this->__set('email', (string)$vcard->vCard->EMAIL->USERID);
|
||||||
|
|
||||||
|
$this->__set('adrlocality', (string)$vcard->vCard->ADR->LOCALITY);
|
||||||
|
$this->__set('adrpostalcode', (string)$vcard->vCard->ADR->PCODE);
|
||||||
|
$this->__set('adrcountry', (string)$vcard->vCard->ADR->CTRY);
|
||||||
|
|
||||||
|
if(filter_var((string)$vcard->vCard->PHOTO, FILTER_VALIDATE_URL)) {
|
||||||
|
$this->__set('photobin', base64_encode(
|
||||||
|
requestUrl((string)$vcard->vCard->PHOTO, 1)));
|
||||||
|
} else {
|
||||||
|
$this->__set('photobin', (string)$vcard->vCard->PHOTO->BINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->__set('description', (string)$vcard->vCard->DESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createThumbnails() {
|
||||||
|
$p = new \Picture;
|
||||||
|
$p->fromBase($this->photobin);
|
||||||
|
$p->set($this->jid);
|
||||||
|
|
||||||
|
if(isset($this->email) && $this->email != '') {
|
||||||
|
\createEmailPic(strtolower($this->jid), $this->email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPhoto($jid = false, $x = false, $y = false) {
|
||||||
|
if(!$jid) return false;
|
||||||
|
|
||||||
|
$p = new \Picture;
|
||||||
|
$url = $p->get($jid, $sizes[$size][0], $sizes[$size][1]);
|
||||||
|
if($url) return $url;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPhoto($size = 'l', $jid = false) {
|
||||||
|
if($size == 'email') {
|
||||||
|
return BASE_URI.'cache/'.strtolower($this->jid).'_email.png';
|
||||||
|
} else {
|
||||||
|
$sizes = array(
|
||||||
|
'wall' => array(1920, 1080),
|
||||||
|
'xxl' => array(1280, 300),
|
||||||
|
'l' => array(210 , false),
|
||||||
|
'm' => array(120 , false),
|
||||||
|
's' => array(50 , false),
|
||||||
|
'xs' => array(28 , false),
|
||||||
|
'xxs' => array(24 , false)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$p = new \Picture;
|
||||||
|
return $p->get($this->jid, $sizes[$size][0], $sizes[$size][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocation($stanza) {
|
||||||
|
$this->loclatitude = (string)$stanza->items->item->geoloc->lat;
|
||||||
|
$this->loclongitude = (string)$stanza->items->item->geoloc->lon;
|
||||||
|
$this->localtitude = (int)$stanza->items->item->geoloc->alt;
|
||||||
|
$this->loccountry = (string)$stanza->items->item->geoloc->country;
|
||||||
|
$this->loccountrycode = (string)$stanza->items->item->geoloc->countrycode;
|
||||||
|
$this->locregion = (string)$stanza->items->item->geoloc->region;
|
||||||
|
$this->locpostalcode = (string)$stanza->items->item->geoloc->postalcode;
|
||||||
|
$this->loclocality = (string)$stanza->items->item->geoloc->locality;
|
||||||
|
$this->locstreet = (string)$stanza->items->item->geoloc->street;
|
||||||
|
$this->locbuilding = (string)$stanza->items->item->geoloc->building;
|
||||||
|
$this->loctext = (string)$stanza->items->item->geoloc->text;
|
||||||
|
$this->locuri = (string)$stanza->items->item->geoloc->uri;
|
||||||
|
$this->loctimestamp = date(
|
||||||
|
'Y-m-d H:i:s',
|
||||||
|
strtotime((string)$stanza->items->item->geoloc->timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTune($stanza) {
|
||||||
|
$this->__set('tuneartist', (string)$stanza->items->item->tune->artist);
|
||||||
|
$this->__set('tunelenght', (int)$stanza->items->item->tune->lenght);
|
||||||
|
$this->__set('tunerating', (int)$stanza->items->item->tune->rating);
|
||||||
|
$this->__set('tunesource', (string)$stanza->items->item->tune->source);
|
||||||
|
$this->__set('tunetitle', (string)$stanza->items->item->tune->title);
|
||||||
|
$this->__set('tunetrack', (string)$stanza->items->item->tune->track);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setVcard4($vcard) {
|
||||||
|
$validate_date = Validator::date('Y-m-d');
|
||||||
|
if(isset($vcard->bday->date)
|
||||||
|
&& $validate_date->validate($vcard->bday->date))
|
||||||
|
$this->__set('date', (string)$vcard->bday->date);
|
||||||
|
|
||||||
|
$this->__set('name', (string)$vcard->nickname->text);
|
||||||
|
$this->__set('fn', (string)$vcard->fn->text);
|
||||||
|
$this->__set('url', (string)$vcard->url->uri);
|
||||||
|
|
||||||
|
if(isset($vcard->gender))
|
||||||
|
$this->__set('gender ', (string)$vcard->gender->sex->text);
|
||||||
|
if(isset($vcard->marital))
|
||||||
|
$this->__set('marital', (string)$vcard->marital->status->text);
|
||||||
|
|
||||||
|
$this->__set('adrlocality', (string)$vcard->adr->locality);
|
||||||
|
$this->__set('adrcountry', (string)$vcard->adr->country);
|
||||||
|
$this->__set('adrpostalcode', (string)$vcard->adr->code);
|
||||||
|
|
||||||
|
if(isset($vcard->impp)) {
|
||||||
|
foreach($vcard->impp->children() as $c) {
|
||||||
|
list($key, $value) = explode(':', (string)$c);
|
||||||
|
|
||||||
|
switch($key) {
|
||||||
|
case 'twitter' :
|
||||||
|
$this->__set('twitter', str_replace('@', '', $value));
|
||||||
|
break;
|
||||||
|
case 'skype' :
|
||||||
|
$this->__set('skype', (string)$value);
|
||||||
|
break;
|
||||||
|
case 'ymsgr' :
|
||||||
|
$this->__set('yahoo', (string)$value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->__set('email', (string)$vcard->email->text);
|
||||||
|
$this->__set('description', trim((string)$vcard->note->text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlace() {
|
||||||
|
$place = null;
|
||||||
|
|
||||||
|
if($this->loctext != '')
|
||||||
|
$place .= $this->loctext.' ';
|
||||||
|
else {
|
||||||
|
if($this->locbuilding != '')
|
||||||
|
$place .= $this->locbuilding.' ';
|
||||||
|
if($this->locstreet != '')
|
||||||
|
$place .= $this->locstreet.'<br />';
|
||||||
|
if($this->locpostalcode != '')
|
||||||
|
$place .= $this->locpostalcode.' ';
|
||||||
|
if($this->loclocality != '')
|
||||||
|
$place .= $this->loclocality.'<br />';
|
||||||
|
if($this->locregion != '')
|
||||||
|
$place .= $this->locregion.' - ';
|
||||||
|
if($this->loccountry != '')
|
||||||
|
$place .= $this->loccountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTrueName() {
|
||||||
|
$truename = '';
|
||||||
|
|
||||||
|
if(isset($this->rostername))
|
||||||
|
$rostername = str_replace('\40', '', $this->rostername);
|
||||||
|
else
|
||||||
|
$rostername = '';
|
||||||
|
|
||||||
|
if(
|
||||||
|
isset($this->rostername)
|
||||||
|
&& $rostername != ''
|
||||||
|
&& !filter_var($rostername, FILTER_VALIDATE_EMAIL)
|
||||||
|
)
|
||||||
|
$truename = $rostername;
|
||||||
|
elseif(
|
||||||
|
isset($this->fn)
|
||||||
|
&& $this->fn != ''
|
||||||
|
&& !filter_var($this->fn, FILTER_VALIDATE_EMAIL)
|
||||||
|
)
|
||||||
|
$truename = $this->fn;
|
||||||
|
elseif(
|
||||||
|
isset($this->nickname)
|
||||||
|
&& $this->nickname != ''
|
||||||
|
&& !filter_var($this->nickname, FILTER_VALIDATE_EMAIL)
|
||||||
|
)
|
||||||
|
$truename = $this->nickname;
|
||||||
|
elseif(
|
||||||
|
isset($this->name)
|
||||||
|
&& $this->name != ''
|
||||||
|
&& !filter_var($this->name, FILTER_VALIDATE_EMAIL)
|
||||||
|
)
|
||||||
|
$truename = $this->name;
|
||||||
|
else {
|
||||||
|
$truename = explodeJid($this->jid);
|
||||||
|
$truename = $truename['username'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $truename;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAge() {
|
||||||
|
if(isset($this->date)
|
||||||
|
&& $this->date != '0000-00-00T00:00:00+0000'
|
||||||
|
&& $this->date != '1970-01-01 00:00:00'
|
||||||
|
&& $this->date != '1970-01-01 01:00:00'
|
||||||
|
&& $this->date != '1970-01-01T00:00:00+0000') {
|
||||||
|
$age = intval(substr(date('Ymd') - date('Ymd', strtotime($this->date)), 0, -4));
|
||||||
|
if($age != 0)
|
||||||
|
return $age;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGender() {
|
||||||
|
$gender = getGender();
|
||||||
|
|
||||||
|
if($this->gender != null && $this->gender != 'N') {
|
||||||
|
return $gender[$this->gender];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMarital() {
|
||||||
|
$marital = getMarital();
|
||||||
|
|
||||||
|
if($this->marital != null && $this->marital != 'none') {
|
||||||
|
return $marital[$this->marital];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAlbum()
|
||||||
|
{
|
||||||
|
$uri = str_replace(
|
||||||
|
' ',
|
||||||
|
'%20',
|
||||||
|
'http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=80c1aa3abfa9e3d06f404a2e781e38f9&artist='.
|
||||||
|
$this->tuneartist.
|
||||||
|
'&album='.
|
||||||
|
$this->tunesource.
|
||||||
|
'&format=json'
|
||||||
|
);
|
||||||
|
|
||||||
|
$json = json_decode(requestURL($uri, 2));
|
||||||
|
|
||||||
|
if(isset($json->album)) {
|
||||||
|
$json->album->url = $json->album->image[2]->{'#text'};
|
||||||
|
return $json->album;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toRoster() {
|
||||||
|
return array(
|
||||||
|
'jid' => $this->jid,
|
||||||
|
'rostername' => $this->rostername,
|
||||||
|
'rostername' => $this->rostername,
|
||||||
|
'groupname' => $this->groupname,
|
||||||
|
'status' => $this->status,
|
||||||
|
'resource' => $this->resource,
|
||||||
|
'value' => $this->value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEmpty() {
|
||||||
|
if($this->fn == null
|
||||||
|
&& $this->name == null
|
||||||
|
&& $this->date == null
|
||||||
|
&& $this->url == null
|
||||||
|
&& $this->email == null
|
||||||
|
&& $this->description == null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOld() {
|
||||||
|
if(strtotime($this->updated) < mktime( // We update the 1 day old vcards
|
||||||
|
gmdate("H"),
|
||||||
|
gmdate("i")-10,
|
||||||
|
gmdate("s"),
|
||||||
|
gmdate("m"),
|
||||||
|
gmdate("d"),
|
||||||
|
gmdate("Y")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PresenceContact extends Contact {
|
||||||
|
// General presence informations
|
||||||
|
protected $resource;
|
||||||
|
protected $value;
|
||||||
|
protected $priority;
|
||||||
|
protected $status;
|
||||||
|
|
||||||
|
// Client Informations
|
||||||
|
protected $node;
|
||||||
|
protected $ver;
|
||||||
|
|
||||||
|
// Delay - XEP 0203
|
||||||
|
protected $delay;
|
||||||
|
|
||||||
|
// Last Activity - XEP 0256
|
||||||
|
protected $last;
|
||||||
|
|
||||||
|
// Current Jabber OpenPGP Usage - XEP-0027
|
||||||
|
protected $publickey;
|
||||||
|
protected $muc;
|
||||||
|
protected $mucjid;
|
||||||
|
protected $mucaffiliation;
|
||||||
|
protected $mucrole;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"resource" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"value" :
|
||||||
|
{"type":"int", "size":11, "mandatory":true },
|
||||||
|
"priority" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"status" :
|
||||||
|
{"type":"text"},
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"ver" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"delay" :
|
||||||
|
{"type":"date"},
|
||||||
|
"last" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"publickey" :
|
||||||
|
{"type":"text"},
|
||||||
|
"muc" :
|
||||||
|
{"type":"int", "size":1 },
|
||||||
|
"mucjid" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"mucaffiliation" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"mucrole" :
|
||||||
|
{"type":"string", "size":32 }
|
||||||
|
}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RosterContact extends Contact {
|
||||||
|
protected $rostername;
|
||||||
|
protected $groupname;
|
||||||
|
protected $status;
|
||||||
|
protected $resource;
|
||||||
|
protected $value;
|
||||||
|
protected $delay;
|
||||||
|
protected $chaton;
|
||||||
|
protected $last;
|
||||||
|
protected $publickey;
|
||||||
|
protected $muc;
|
||||||
|
protected $rosterask;
|
||||||
|
protected $rostersubscription;
|
||||||
|
protected $node;
|
||||||
|
protected $ver;
|
||||||
|
protected $category;
|
||||||
|
//protected $type;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
$this->_struct = "
|
||||||
|
{
|
||||||
|
'rostername' :
|
||||||
|
{'type':'string', 'size':128 },
|
||||||
|
'rosterask' :
|
||||||
|
{'type':'string', 'size':128 },
|
||||||
|
'rostersubscription' :
|
||||||
|
{'type':'string', 'size':8 },
|
||||||
|
'groupname' :
|
||||||
|
{'type':'string', 'size':128 },
|
||||||
|
'resource' :
|
||||||
|
{'type':'string', 'size':128, 'key':true },
|
||||||
|
'value' :
|
||||||
|
{'type':'int', 'size':11, 'mandatory':true },
|
||||||
|
'chaton' :
|
||||||
|
{'type':'int', 'size':11 },
|
||||||
|
'status' :
|
||||||
|
{'type':'text'},
|
||||||
|
'node' :
|
||||||
|
{'type':'string', 'size':128 },
|
||||||
|
'ver' :
|
||||||
|
{'type':'string', 'size':128 },
|
||||||
|
'delay' :
|
||||||
|
{'type':'date'},
|
||||||
|
'last' :
|
||||||
|
{'type':'int', 'size':11 },
|
||||||
|
'publickey' :
|
||||||
|
{'type':'text'},
|
||||||
|
'muc' :
|
||||||
|
{'type':'int', 'size':1 },
|
||||||
|
'mucaffiliation' :
|
||||||
|
{'type':'string', 'size':32 },
|
||||||
|
'mucrole' :
|
||||||
|
{'type':'string', 'size':32 }
|
||||||
|
}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is only use on the connection
|
||||||
|
public function setPresence($p) {
|
||||||
|
$this->resource = $p->resource;
|
||||||
|
$this->value = $p->value;
|
||||||
|
$this->status = $p->status;
|
||||||
|
$this->delay = $p->delay;
|
||||||
|
$this->last = $p->last;
|
||||||
|
$this->publickey = $p->publickey;
|
||||||
|
$this->muc = $p->muc;
|
||||||
|
$this->mucaffiliation = $p->mucaffiliation;
|
||||||
|
$this->mucrole = $p->mucrole;
|
||||||
|
}
|
||||||
|
}
|
624
sources/app/models/contact/ContactDAO.php
Normal file
624
sources/app/models/contact/ContactDAO.php
Normal file
|
@ -0,0 +1,624 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class ContactDAO extends SQL {
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($jid = null, $empty = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, privacy.value as privacy from contact
|
||||||
|
left outer join privacy
|
||||||
|
on contact.jid = privacy.pkey
|
||||||
|
where jid = :jid';
|
||||||
|
|
||||||
|
if($jid == null) $jid = $this->_user;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'jid' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$contact = $this->run('Contact', 'item');
|
||||||
|
|
||||||
|
// If we cannot find the contact
|
||||||
|
if($contact == null && $empty == false) {
|
||||||
|
$contact = new Contact;
|
||||||
|
$contact->jid = $jid;
|
||||||
|
return $contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(Contact $contact) {
|
||||||
|
if(!isset($contact->created)) {
|
||||||
|
$contact->created = date(DATE_ISO8601);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
update contact
|
||||||
|
set fn = :fn,
|
||||||
|
name = :name,
|
||||||
|
date = :date,
|
||||||
|
url = :url,
|
||||||
|
|
||||||
|
email = :email,
|
||||||
|
|
||||||
|
adrlocality = :adrlocality,
|
||||||
|
adrpostalcode = :adrpostalcode,
|
||||||
|
adrcountry = :adrcountry,
|
||||||
|
|
||||||
|
gender = :gender,
|
||||||
|
marital = :marital,
|
||||||
|
|
||||||
|
description = :description,
|
||||||
|
|
||||||
|
mood = :mood,
|
||||||
|
|
||||||
|
activity = :activity,
|
||||||
|
|
||||||
|
nickname = :nickname,
|
||||||
|
|
||||||
|
tuneartist = :tuneartist,
|
||||||
|
tunelenght = :tunelenght,
|
||||||
|
tunerating = :tunerating,
|
||||||
|
tunesource = :tunesource,
|
||||||
|
tunetitle = :tunetitle,
|
||||||
|
tunetrack = :tunetrack,
|
||||||
|
|
||||||
|
loclatitude = :loclatitude,
|
||||||
|
loclongitude = :loclongitude,
|
||||||
|
localtitude = :localtitude,
|
||||||
|
loccountry = :loccountry,
|
||||||
|
loccountrycode = :loccountrycode,
|
||||||
|
locregion = :locregion,
|
||||||
|
locpostalcode = :locpostalcode,
|
||||||
|
loclocality = :loclocality,
|
||||||
|
locstreet = :locstreet,
|
||||||
|
locbuilding = :locbuilding,
|
||||||
|
loctext = :loctext,
|
||||||
|
locuri = :locuri,
|
||||||
|
loctimestamp = :loctimestamp,
|
||||||
|
twitter = :twitter,
|
||||||
|
skype = :skype,
|
||||||
|
yahoo = :yahoo,
|
||||||
|
avatarhash = :avatarhash,
|
||||||
|
created = :created,
|
||||||
|
updated = :updated
|
||||||
|
where contact.jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'fn' => $contact->fn,
|
||||||
|
'name' => $contact->name,
|
||||||
|
'date' => $contact->date,
|
||||||
|
'url' => $contact->url,
|
||||||
|
|
||||||
|
'email' => $contact->email,
|
||||||
|
|
||||||
|
'adrlocality' => $contact->adrlocality,
|
||||||
|
'adrpostalcode' => $contact->adrpostalcode,
|
||||||
|
'adrcountry' => $contact->adrcountry,
|
||||||
|
|
||||||
|
'gender' => $contact->gender,
|
||||||
|
'marital' => $contact->marital,
|
||||||
|
|
||||||
|
'description' => $contact->description,
|
||||||
|
|
||||||
|
// User Mood (contain serialized array) - XEP 0107
|
||||||
|
'mood' => $contact->mood,
|
||||||
|
|
||||||
|
// User Activity (contain serialized array) - XEP 0108
|
||||||
|
'activity' => $contact->activity,
|
||||||
|
|
||||||
|
// User Nickname - XEP 0172
|
||||||
|
'nickname' => $contact->nickname,
|
||||||
|
|
||||||
|
// User Tune - XEP 0118
|
||||||
|
'tuneartist' => $contact->tuneartist,
|
||||||
|
'tunelenght' => $contact->tunelenght,
|
||||||
|
'tunerating' => $contact->tunerating,
|
||||||
|
'tunesource' => $contact->tunesource,
|
||||||
|
'tunetitle' => $contact->tunetitle,
|
||||||
|
'tunetrack' => $contact->tunetrack,
|
||||||
|
|
||||||
|
// User Location
|
||||||
|
'loclatitude' => $contact->loclatitude,
|
||||||
|
'loclongitude' => $contact->loclongitude,
|
||||||
|
'localtitude' => $contact->localtitude,
|
||||||
|
'loccountry' => $contact->loccountry,
|
||||||
|
'loccountrycode' => $contact->loccountrycode,
|
||||||
|
'locregion' => $contact->locregion,
|
||||||
|
'locpostalcode' => $contact->locpostalcode,
|
||||||
|
'loclocality' => $contact->loclocality,
|
||||||
|
'locstreet' => $contact->locstreet,
|
||||||
|
'locbuilding' => $contact->locbuilding,
|
||||||
|
'loctext' => $contact->loctext,
|
||||||
|
'locuri' => $contact->locuri,
|
||||||
|
'loctimestamp' => $contact->loctimestamp,
|
||||||
|
|
||||||
|
'twitter' => $contact->twitter,
|
||||||
|
'skype' => $contact->skype,
|
||||||
|
'yahoo' => $contact->yahoo,
|
||||||
|
|
||||||
|
'avatarhash' => $contact->avatarhash,
|
||||||
|
|
||||||
|
'created' => $contact->created,
|
||||||
|
'updated' => date(DATE_ISO8601),
|
||||||
|
|
||||||
|
'jid' => $contact->jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Contact');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into contact
|
||||||
|
(
|
||||||
|
fn,
|
||||||
|
name,
|
||||||
|
date,
|
||||||
|
url,
|
||||||
|
|
||||||
|
email,
|
||||||
|
|
||||||
|
adrlocality,
|
||||||
|
adrpostalcode,
|
||||||
|
adrcountry,
|
||||||
|
|
||||||
|
gender,
|
||||||
|
marital,
|
||||||
|
|
||||||
|
description,
|
||||||
|
|
||||||
|
mood,
|
||||||
|
|
||||||
|
activity,
|
||||||
|
|
||||||
|
nickname,
|
||||||
|
|
||||||
|
tuneartist,
|
||||||
|
tunelenght,
|
||||||
|
tunerating,
|
||||||
|
tunesource,
|
||||||
|
tunetitle,
|
||||||
|
tunetrack,
|
||||||
|
|
||||||
|
loclatitude,
|
||||||
|
loclongitude,
|
||||||
|
localtitude,
|
||||||
|
loccountry,
|
||||||
|
loccountrycode,
|
||||||
|
locregion,
|
||||||
|
locpostalcode,
|
||||||
|
loclocality,
|
||||||
|
locstreet,
|
||||||
|
locbuilding,
|
||||||
|
loctext,
|
||||||
|
locuri,
|
||||||
|
loctimestamp,
|
||||||
|
|
||||||
|
twitter,
|
||||||
|
skype,
|
||||||
|
yahoo,
|
||||||
|
|
||||||
|
avatarhash,
|
||||||
|
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
|
||||||
|
jid)
|
||||||
|
values (
|
||||||
|
:fn,
|
||||||
|
:name,
|
||||||
|
:date,
|
||||||
|
:url,
|
||||||
|
|
||||||
|
:email,
|
||||||
|
|
||||||
|
:adrlocality,
|
||||||
|
:adrpostalcode,
|
||||||
|
:adrcountry,
|
||||||
|
|
||||||
|
:gender,
|
||||||
|
:marital,
|
||||||
|
|
||||||
|
:description,
|
||||||
|
|
||||||
|
:mood,
|
||||||
|
|
||||||
|
:activity,
|
||||||
|
|
||||||
|
:nickname,
|
||||||
|
|
||||||
|
:tuneartist,
|
||||||
|
:tunelenght,
|
||||||
|
:tunerating,
|
||||||
|
:tunesource,
|
||||||
|
:tunetitle,
|
||||||
|
:tunetrack,
|
||||||
|
|
||||||
|
:loclatitude,
|
||||||
|
:loclongitude,
|
||||||
|
:localtitude,
|
||||||
|
:loccountry,
|
||||||
|
:loccountrycode,
|
||||||
|
:locregion,
|
||||||
|
:locpostalcode,
|
||||||
|
:loclocality,
|
||||||
|
:locstreet,
|
||||||
|
:locbuilding,
|
||||||
|
:loctext,
|
||||||
|
:locuri,
|
||||||
|
:loctimestamp,
|
||||||
|
|
||||||
|
:twitter,
|
||||||
|
:skype,
|
||||||
|
:yahoo,
|
||||||
|
|
||||||
|
:avatarhash,
|
||||||
|
|
||||||
|
:created,
|
||||||
|
:updated,
|
||||||
|
|
||||||
|
:jid)';
|
||||||
|
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'fn' => $contact->fn,
|
||||||
|
'name' => $contact->name,
|
||||||
|
'date' => $contact->date,
|
||||||
|
'url' => $contact->url,
|
||||||
|
|
||||||
|
'email' => $contact->email,
|
||||||
|
|
||||||
|
'adrlocality' => $contact->adrlocality,
|
||||||
|
'adrpostalcode' => $contact->adrpostalcode,
|
||||||
|
'adrcountry' => $contact->adrcountry,
|
||||||
|
|
||||||
|
'gender' => $contact->gender,
|
||||||
|
'marital' => $contact->marital,
|
||||||
|
|
||||||
|
'description' => $contact->description,
|
||||||
|
|
||||||
|
// User Mood (contain serialized array) - XEP 0107
|
||||||
|
'mood' => $contact->mood,
|
||||||
|
|
||||||
|
// User Activity (contain serialized array) - XEP 0108
|
||||||
|
'activity' => $contact->activity,
|
||||||
|
|
||||||
|
// User Nickname - XEP 0172
|
||||||
|
'nickname' => $contact->nickname,
|
||||||
|
|
||||||
|
// User Tune - XEP 0118
|
||||||
|
'tuneartist' => $contact->tuneartist,
|
||||||
|
'tunelenght' => $contact->tunelenght,
|
||||||
|
'tunerating' => $contact->tunerating,
|
||||||
|
'tunesource' => $contact->tunesource,
|
||||||
|
'tunetitle' => $contact->tunetitle,
|
||||||
|
'tunetrack' => $contact->tunetrack,
|
||||||
|
|
||||||
|
// User Location
|
||||||
|
'loclatitude' => $contact->loclatitude,
|
||||||
|
'loclongitude' => $contact->loclongitude,
|
||||||
|
'localtitude' => $contact->localtitude,
|
||||||
|
'loccountry' => $contact->loccountry,
|
||||||
|
'loccountrycode' => $contact->loccountrycode,
|
||||||
|
'locregion' => $contact->locregion,
|
||||||
|
'locpostalcode' => $contact->locpostalcode,
|
||||||
|
'loclocality' => $contact->loclocality,
|
||||||
|
'locstreet' => $contact->locstreet,
|
||||||
|
'locbuilding' => $contact->locbuilding,
|
||||||
|
'loctext' => $contact->loctext,
|
||||||
|
'locuri' => $contact->locuri,
|
||||||
|
'loctimestamp' => $contact->loctimestamp,
|
||||||
|
|
||||||
|
'twitter' => $contact->twitter,
|
||||||
|
'skype' => $contact->skype,
|
||||||
|
'yahoo' => $contact->yahoo,
|
||||||
|
|
||||||
|
'avatarhash' => $contact->avatarhash,
|
||||||
|
|
||||||
|
'created' => date(DATE_ISO8601),
|
||||||
|
'updated' => date(DATE_ISO8601),
|
||||||
|
|
||||||
|
'jid' => $contact->jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Contact');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$this->_sql =
|
||||||
|
'select *, privacy.value as privacy from contact
|
||||||
|
left outer join privacy
|
||||||
|
on contact.jid = privacy.pkey';
|
||||||
|
|
||||||
|
$this->prepare('Contact');
|
||||||
|
return $this->run('Contact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchJid($search) {
|
||||||
|
$this->_sql =
|
||||||
|
'select *, privacy.value as privacy from contact
|
||||||
|
left outer join privacy
|
||||||
|
on contact.jid = privacy.pkey
|
||||||
|
where jid like :jid
|
||||||
|
and privacy.value = 1
|
||||||
|
order by jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'jid' => '%'.$search.'%'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return $this->run('Contact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllPublic($limitf = false, $limitr = false) {
|
||||||
|
$this->_sql =
|
||||||
|
'select *, privacy.value as privacy from contact
|
||||||
|
left outer join privacy
|
||||||
|
on contact.jid = privacy.pkey
|
||||||
|
where privacy.value = 1
|
||||||
|
and contact.jid not in (select jid from rosterlink where session = :jid)
|
||||||
|
and contact.jid != :jid
|
||||||
|
order by jid desc';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Contact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function countAllPublic() {
|
||||||
|
$this->_sql =
|
||||||
|
'select count(*) from contact
|
||||||
|
left outer join privacy
|
||||||
|
on contact.jid = privacy.pkey
|
||||||
|
where privacy.value = 1
|
||||||
|
and contact.jid not in (select jid from rosterlink where session = :jid)
|
||||||
|
and contact.jid != :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = $this->run(null, 'array');
|
||||||
|
$results = array_values($results[0]);
|
||||||
|
|
||||||
|
return (int)$results[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoster() {
|
||||||
|
$this->_sql = '
|
||||||
|
select
|
||||||
|
rosterlink.jid,
|
||||||
|
contact.fn,
|
||||||
|
contact.name,
|
||||||
|
contact.nickname,
|
||||||
|
contact.tuneartist,
|
||||||
|
contact.tunetitle,
|
||||||
|
rosterlink.rostername,
|
||||||
|
rosterlink.rostersubscription,
|
||||||
|
rosterlink.groupname,
|
||||||
|
rosterlink.chaton,
|
||||||
|
presence.status,
|
||||||
|
presence.resource,
|
||||||
|
presence.value,
|
||||||
|
presence.delay,
|
||||||
|
presence.node,
|
||||||
|
presence.ver,
|
||||||
|
presence.last
|
||||||
|
from rosterlink
|
||||||
|
left outer join presence
|
||||||
|
on rosterlink.jid = presence.jid and rosterlink.session = presence.session
|
||||||
|
left outer join contact
|
||||||
|
on rosterlink.jid = contact.jid
|
||||||
|
where rosterlink.session = :session
|
||||||
|
order by groupname, rosterlink.jid, presence.value';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterContact');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the roster without the presences
|
||||||
|
function getRosterSimple() {
|
||||||
|
$this->_sql = '
|
||||||
|
select
|
||||||
|
rosterlink.jid,
|
||||||
|
contact.fn,
|
||||||
|
contact.name,
|
||||||
|
contact.nickname,
|
||||||
|
contact.tuneartist,
|
||||||
|
contact.tunetitle,
|
||||||
|
rosterlink.rostername,
|
||||||
|
rosterlink.rostersubscription,
|
||||||
|
rosterlink.groupname,
|
||||||
|
rosterlink.chaton
|
||||||
|
from rosterlink
|
||||||
|
left outer join contact
|
||||||
|
on rosterlink.jid = contact.jid
|
||||||
|
where rosterlink.session = :session
|
||||||
|
order by groupname, rosterlink.jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterContact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRosterFrom() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from rosterlink
|
||||||
|
left outer join contact
|
||||||
|
on rosterlink.jid = contact.jid
|
||||||
|
where rosterlink.session = :session
|
||||||
|
and rosterlink.rostersubscription = :rostersubscription';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'rostersubscription' => 'from'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterContact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRosterItem($jid, $item = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select
|
||||||
|
rosterlink.jid,
|
||||||
|
contact.fn,
|
||||||
|
contact.name,
|
||||||
|
contact.nickname,
|
||||||
|
contact.tuneartist,
|
||||||
|
contact.tunetitle,
|
||||||
|
rosterlink.rostername,
|
||||||
|
rosterlink.rostersubscription,
|
||||||
|
rosterlink.groupname,
|
||||||
|
rosterlink.chaton,
|
||||||
|
presence.status,
|
||||||
|
presence.resource,
|
||||||
|
presence.value,
|
||||||
|
presence.delay,
|
||||||
|
presence.node,
|
||||||
|
presence.ver,
|
||||||
|
presence.last
|
||||||
|
from rosterlink
|
||||||
|
left outer join presence
|
||||||
|
on rosterlink.jid = presence.jid and rosterlink.session = presence.session
|
||||||
|
left outer join contact
|
||||||
|
on rosterlink.jid = contact.jid
|
||||||
|
where rosterlink.session = :session
|
||||||
|
and rosterlink.jid = :jid
|
||||||
|
order by groupname, rosterlink.jid, presence.value';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if($item)
|
||||||
|
return $this->run('RosterContact');
|
||||||
|
else
|
||||||
|
return $this->run('RosterContact', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPresence($jid, $resource) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from contact
|
||||||
|
right outer join presence on contact.jid = presence.mucjid
|
||||||
|
where presence.session = :session
|
||||||
|
and presence.jid = :jid
|
||||||
|
and presence.resource = :resource
|
||||||
|
order by mucaffiliation desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid,
|
||||||
|
'resource' => $resource
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('PresenceContact', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPresences($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from contact
|
||||||
|
right outer join presence on contact.jid = presence.mucjid
|
||||||
|
where presence.session = :session
|
||||||
|
and presence.jid = :jid
|
||||||
|
order by mucaffiliation desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('PresenceContact');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTop($limit = 6) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, jidfrom from (
|
||||||
|
select jidfrom, count(*) as count from message
|
||||||
|
where jidfrom not like :jid
|
||||||
|
and session = :jid
|
||||||
|
and type != \'groupchat\'
|
||||||
|
group by jidfrom
|
||||||
|
order by count desc
|
||||||
|
) as top
|
||||||
|
join (
|
||||||
|
select *
|
||||||
|
from rosterlink
|
||||||
|
where session = :jid
|
||||||
|
) as rosterlink on jidfrom = rosterlink.jid
|
||||||
|
left outer join contact on jidfrom = contact.jid
|
||||||
|
left outer join (
|
||||||
|
select a.*
|
||||||
|
from presence a
|
||||||
|
join (
|
||||||
|
select jid, min( id ) as id
|
||||||
|
from presence
|
||||||
|
where session = :jid
|
||||||
|
group by jid
|
||||||
|
) as b on ( a.id = b.id )
|
||||||
|
) presence on jidfrom = presence.jid
|
||||||
|
order by presence.value, count desc
|
||||||
|
limit :tunelenght';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Contact',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'tunelenght' => $limit // And an another hack…
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterContact');
|
||||||
|
}
|
||||||
|
}
|
93
sources/app/models/item/Item.php
Normal file
93
sources/app/models/item/Item.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Item extends Model {
|
||||||
|
public $server;
|
||||||
|
public $jid;
|
||||||
|
public $name;
|
||||||
|
public $node;
|
||||||
|
public $creator;
|
||||||
|
public $created;
|
||||||
|
public $updated;
|
||||||
|
public $description;
|
||||||
|
public $subscription;
|
||||||
|
public $num;
|
||||||
|
public $sub;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"server" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":96, "key":true },
|
||||||
|
"creator" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"name" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"created" :
|
||||||
|
{"type":"date"},
|
||||||
|
"description" :
|
||||||
|
{"type":"text" },
|
||||||
|
"updated" :
|
||||||
|
{"type":"date", "mandatory":true}
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($item, $from) {
|
||||||
|
$this->server = $from;
|
||||||
|
$this->node = (string)$item->attributes()->node;
|
||||||
|
$this->jid = (string)$item->attributes()->jid;
|
||||||
|
if($this->jid == null)
|
||||||
|
$this->jid = $this->node;
|
||||||
|
$this->name = (string)$item->attributes()->name;
|
||||||
|
$this->updated = date('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMetadata($metadata, $from, $node) {
|
||||||
|
$this->server = $from;
|
||||||
|
$this->jid = $from;
|
||||||
|
$this->node = $node;
|
||||||
|
|
||||||
|
foreach($metadata->children() as $i) {
|
||||||
|
$key = (string)$i->attributes()->var;
|
||||||
|
|
||||||
|
switch ($key) {
|
||||||
|
case 'pubsub#title':
|
||||||
|
$this->name = (string)$i->value;
|
||||||
|
break;
|
||||||
|
case 'pubsub#creator':
|
||||||
|
$this->creator = (string)$i->value;
|
||||||
|
break;
|
||||||
|
case 'pubsub#creation_date':
|
||||||
|
$this->created = (string)$i->value;
|
||||||
|
break;
|
||||||
|
case 'pubsub#description':
|
||||||
|
$this->description = (string)$i->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->updated = date('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
if($this->name != null)
|
||||||
|
return $this->name;
|
||||||
|
elseif($this->node != null)
|
||||||
|
return $this->node;
|
||||||
|
else
|
||||||
|
return $this->jid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Server extends Model {
|
||||||
|
public $server;
|
||||||
|
public $number;
|
||||||
|
public $name;
|
||||||
|
}
|
278
sources/app/models/item/ItemDAO.php
Normal file
278
sources/app/models/item/ItemDAO.php
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class ItemDAO extends SQL {
|
||||||
|
function set(Item $item, $insert_only = false) {
|
||||||
|
if(!$insert_only) {
|
||||||
|
$this->_sql = '
|
||||||
|
update item
|
||||||
|
set name = :name,
|
||||||
|
creator = :creator,
|
||||||
|
created = :created,
|
||||||
|
updated = :updated,
|
||||||
|
description = :description
|
||||||
|
where server = :server
|
||||||
|
and jid = :jid
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'name' => $item->name,
|
||||||
|
'created' => $item->created,
|
||||||
|
'updated' => $item->updated,
|
||||||
|
'server' => $item->server,
|
||||||
|
'jid' => $item->jid,
|
||||||
|
'node' => $item->node,
|
||||||
|
'creator' => $item->creator,
|
||||||
|
'description' => $item->description
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->_effective || $insert_only) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into item
|
||||||
|
(server,
|
||||||
|
creator,
|
||||||
|
node,
|
||||||
|
jid,
|
||||||
|
name,
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
description
|
||||||
|
)
|
||||||
|
values(
|
||||||
|
:server,
|
||||||
|
:creator,
|
||||||
|
:node,
|
||||||
|
:jid,
|
||||||
|
:name,
|
||||||
|
:created,
|
||||||
|
:updated,
|
||||||
|
:description
|
||||||
|
)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'name' => $item->name,
|
||||||
|
'creator' => $item->creator,
|
||||||
|
'created' => $item->created,
|
||||||
|
'updated' => $item->updated,
|
||||||
|
'server' => $item->server,
|
||||||
|
'jid' => $item->jid,
|
||||||
|
'node' => $item->node,
|
||||||
|
'description' => $item->description
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Item');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServers() {
|
||||||
|
$this->_sql = '
|
||||||
|
select server, count(node) as number
|
||||||
|
from item
|
||||||
|
where node not like :node
|
||||||
|
group by server
|
||||||
|
order by number desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'node' => 'urn:xmpp:microblog:0:comments%'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Server');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConferenceServers() {
|
||||||
|
$this->_sql = '
|
||||||
|
select server, count(node) as number
|
||||||
|
from item
|
||||||
|
where node not like :node
|
||||||
|
and node = :name
|
||||||
|
group by server
|
||||||
|
order by number desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'node' => 'urn:xmpp:microblog:0:comments%',
|
||||||
|
// It's a hack to affect an empty string
|
||||||
|
'name' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Server');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupServers() {
|
||||||
|
$this->_sql = '
|
||||||
|
select server, count(item.node) as number, caps.name
|
||||||
|
from item
|
||||||
|
left outer join caps on caps.node = item.server
|
||||||
|
where item.node not like :node
|
||||||
|
and item.node != :name
|
||||||
|
group by server, caps.name
|
||||||
|
order by number desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'node' => 'urn:xmpp:microblog:0:comments%',
|
||||||
|
// Little hack here too
|
||||||
|
'name' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Server');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItems($server) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from item
|
||||||
|
left outer join (
|
||||||
|
select node, count(node) as num from postn
|
||||||
|
where origin = :server
|
||||||
|
group by node) as p
|
||||||
|
on p.node = item.node
|
||||||
|
left outer join (
|
||||||
|
select node, count(node) as sub from subscription
|
||||||
|
where server = :server
|
||||||
|
group by node) as sub
|
||||||
|
on sub.node = item.node
|
||||||
|
left outer join (select server, node, subscription from subscription where jid = :node)
|
||||||
|
as s on s.server = item.server
|
||||||
|
and s.node = item.node
|
||||||
|
where item.server = :server
|
||||||
|
and item.node != \'\'
|
||||||
|
order by name, item.node
|
||||||
|
';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
// Dirty hack, using node param to inject the session key
|
||||||
|
'node' => $this->_user,
|
||||||
|
'server' => $server
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGateways($server) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from item
|
||||||
|
left outer join caps on caps.node = item.jid
|
||||||
|
where server = :server
|
||||||
|
and category = \'gateway\'';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'server' => $server
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUpload($server) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from item
|
||||||
|
left outer join caps on caps.node = item.jid
|
||||||
|
where server = :server
|
||||||
|
and category = \'store\'
|
||||||
|
and type = \'file\'';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'server' => $server
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUpdatedItems($limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from item natural join (
|
||||||
|
select distinct node, max(updated) as num from postn
|
||||||
|
where node not like :node
|
||||||
|
group by node
|
||||||
|
order by node) as post
|
||||||
|
order by num desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'node' => 'urn:xmpp:microblog%'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteItems($server) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from item
|
||||||
|
where server= :server';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'server' => $server
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteItem($server, $item) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from item
|
||||||
|
where server = :server
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'server' => $server,
|
||||||
|
'node' => $item
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItem($server, $item) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from item
|
||||||
|
where
|
||||||
|
node = :node
|
||||||
|
and server = :server';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Item',
|
||||||
|
array(
|
||||||
|
'node' => $item,
|
||||||
|
'server' => $server
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Item', 'item');
|
||||||
|
}
|
||||||
|
}
|
143
sources/app/models/message/Message.php
Normal file
143
sources/app/models/message/Message.php
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Message extends Model {
|
||||||
|
public $id;
|
||||||
|
public $newid;
|
||||||
|
|
||||||
|
public $session;
|
||||||
|
public $jidto;
|
||||||
|
public $jidfrom;
|
||||||
|
|
||||||
|
protected $resource;
|
||||||
|
|
||||||
|
public $type;
|
||||||
|
|
||||||
|
protected $subject;
|
||||||
|
protected $thread;
|
||||||
|
protected $body;
|
||||||
|
protected $html;
|
||||||
|
|
||||||
|
public $published;
|
||||||
|
public $delivered;
|
||||||
|
|
||||||
|
public $color; // Only for chatroom purpose
|
||||||
|
public $publishedPrepared; // Only for chat purpose
|
||||||
|
public $edited;
|
||||||
|
|
||||||
|
public $sticker; // The sticker code
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"session" :
|
||||||
|
{"type":"string", "size":96, "mandatory":true },
|
||||||
|
"id" :
|
||||||
|
{"type":"string", "size":64},
|
||||||
|
"jidto" :
|
||||||
|
{"type":"string", "size":96, "mandatory":true },
|
||||||
|
"jidfrom" :
|
||||||
|
{"type":"string", "size":96, "mandatory":true },
|
||||||
|
"resource" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true },
|
||||||
|
"type" :
|
||||||
|
{"type":"string", "size":16, "mandatory":true },
|
||||||
|
"subject" :
|
||||||
|
{"type":"text"},
|
||||||
|
"thread" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"body" :
|
||||||
|
{"type":"text"},
|
||||||
|
"html" :
|
||||||
|
{"type":"text"},
|
||||||
|
"published" :
|
||||||
|
{"type":"date", "mandatory":true},
|
||||||
|
"delivered" :
|
||||||
|
{"type":"date"},
|
||||||
|
"edited" :
|
||||||
|
{"type":"int", "size":1},
|
||||||
|
"sticker" :
|
||||||
|
{"type":"string", "size":128 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($stanza, $parent = false)
|
||||||
|
{
|
||||||
|
if($stanza->body || $stanza->subject) {
|
||||||
|
$jid = explode('/',(string)$stanza->attributes()->from);
|
||||||
|
$to = current(explode('/',(string)$stanza->attributes()->to));
|
||||||
|
|
||||||
|
if(isset($stanza->attributes()->id)) {
|
||||||
|
$this->id = (string)$stanza->attributes()->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is not very beautiful
|
||||||
|
$user = new \User;
|
||||||
|
$this->session = $user->getLogin();
|
||||||
|
|
||||||
|
$this->jidto = $to;
|
||||||
|
$this->jidfrom = $jid[0];
|
||||||
|
|
||||||
|
if(isset($jid[1]))
|
||||||
|
$this->__set('resource', $jid[1]);
|
||||||
|
|
||||||
|
$this->type = 'chat';
|
||||||
|
if($stanza->attributes()->type) {
|
||||||
|
$this->type = (string)$stanza->attributes()->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($stanza->body)
|
||||||
|
$this->__set('body', (string)$stanza->body);
|
||||||
|
|
||||||
|
if($stanza->subject)
|
||||||
|
$this->__set('subject', (string)$stanza->subject);
|
||||||
|
|
||||||
|
$images = (bool)($this->type == 'chat');
|
||||||
|
|
||||||
|
if($stanza->html) {
|
||||||
|
$xhtml = new \SimpleXMLElement('<body xmlns="http://www.w3.org/1999/xhtml">'.(string)$stanza->html->body.'</body>');
|
||||||
|
$xhtml->registerXPathNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
|
||||||
|
$img = $xhtml->xpath('//xhtml:img/@src')[0];
|
||||||
|
if($img) {
|
||||||
|
$this->sticker = getCid((string)$img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if($stanza->html) {
|
||||||
|
$this->html = \cleanHTMLTags($stanza->html->body->asXML());
|
||||||
|
$this->html = \fixSelfClosing($this->html);
|
||||||
|
$this->html = \prepareString($this->html, false, $images);
|
||||||
|
} else {*/
|
||||||
|
// $this->html = \prepareString($this->body, false, $images);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if($stanza->replace) {
|
||||||
|
$this->newid = $this->id;
|
||||||
|
$this->id = (string)$stanza->replace->attributes()->id;
|
||||||
|
$this->edited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($stanza->delay)
|
||||||
|
$this->published = gmdate('Y-m-d H:i:s', strtotime($stanza->delay->attributes()->stamp));
|
||||||
|
elseif($parent && $parent->delay)
|
||||||
|
$this->published = gmdate('Y-m-d H:i:s', strtotime($parent->delay->attributes()->stamp));
|
||||||
|
else
|
||||||
|
$this->published = gmdate('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function convertEmojis()
|
||||||
|
{
|
||||||
|
$emoji = \MovimEmoji::getInstance();
|
||||||
|
$this->body = addHFR($emoji->replace($this->body));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUrls()
|
||||||
|
{
|
||||||
|
$this->body = addUrls($this->body);
|
||||||
|
}
|
||||||
|
}
|
255
sources/app/models/message/MessageDAO.php
Normal file
255
sources/app/models/message/MessageDAO.php
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class MessageDAO extends SQL {
|
||||||
|
function set(Message $message) {
|
||||||
|
$this->_sql = '
|
||||||
|
update message
|
||||||
|
set id = :thread,
|
||||||
|
body = :body,
|
||||||
|
html = :html,
|
||||||
|
published = :published,
|
||||||
|
delivered = :delivered,
|
||||||
|
edited = :edited
|
||||||
|
|
||||||
|
where session = :session
|
||||||
|
and id = :id
|
||||||
|
and jidto = :jidto
|
||||||
|
and jidfrom = :jidfrom';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'thread' => $message->newid, // FIXME
|
||||||
|
'id' => $message->id,
|
||||||
|
'session' => $message->session,
|
||||||
|
'jidto' => $message->jidto,
|
||||||
|
'edited' => $message->edited,
|
||||||
|
'jidfrom' => $message->jidfrom,
|
||||||
|
'body' => $message->body,
|
||||||
|
'html' => $message->html,
|
||||||
|
'published' => $message->published,
|
||||||
|
'delivered' => $message->delivered
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Message');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into message
|
||||||
|
(
|
||||||
|
id,
|
||||||
|
session,
|
||||||
|
jidto,
|
||||||
|
jidfrom,
|
||||||
|
resource,
|
||||||
|
type,
|
||||||
|
subject,
|
||||||
|
thread,
|
||||||
|
body,
|
||||||
|
html,
|
||||||
|
published,
|
||||||
|
delivered,
|
||||||
|
sticker)
|
||||||
|
values(
|
||||||
|
:id,
|
||||||
|
:session,
|
||||||
|
:jidto,
|
||||||
|
:jidfrom,
|
||||||
|
:resource,
|
||||||
|
:type,
|
||||||
|
:subject,
|
||||||
|
:thread,
|
||||||
|
:body,
|
||||||
|
:html,
|
||||||
|
:published,
|
||||||
|
:delivered,
|
||||||
|
:sticker
|
||||||
|
)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'id' => $message->id,
|
||||||
|
'session' => $message->session,
|
||||||
|
'jidto' => $message->jidto,
|
||||||
|
'jidfrom' => $message->jidfrom,
|
||||||
|
'resource' => $message->resource,
|
||||||
|
'type' => $message->type,
|
||||||
|
'subject' => $message->subject,
|
||||||
|
'thread' => $message->thread,
|
||||||
|
'body' => $message->body,
|
||||||
|
'html' => $message->html,
|
||||||
|
'published' => $message->published,
|
||||||
|
'delivered' => $message->delivered,
|
||||||
|
'sticker' => $message->sticker
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getId($id)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where session = :session
|
||||||
|
and id = :id
|
||||||
|
limit 1';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'id' => $id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastItem($to)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where session = :session
|
||||||
|
and jidto = :jidto
|
||||||
|
and jidfrom = :jidfrom
|
||||||
|
order by published desc
|
||||||
|
limit 1';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jidto' => $to,
|
||||||
|
'jidfrom' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll($limitf = false, $limitr = false)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where session = :session
|
||||||
|
order by published desc';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContact($jid, $limitf = false, $limitr = false)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where session = :session
|
||||||
|
and (jidfrom = :jidfrom
|
||||||
|
or jidto = :jidto)
|
||||||
|
order by published desc';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jidfrom' => $jid,
|
||||||
|
'jidto' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteContact($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from message
|
||||||
|
where session = :session
|
||||||
|
and (jidfrom = :jidfrom
|
||||||
|
or jidto = :jidto)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'jidfrom' => $jid,
|
||||||
|
'jidto' => $jid,
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHistory($jid, $date, $limit = 30) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where session = :session
|
||||||
|
and (jidfrom = :jidfrom
|
||||||
|
or jidto = :jidto)
|
||||||
|
and published < :published
|
||||||
|
order by published desc';
|
||||||
|
|
||||||
|
$this->_sql .= ' limit '.(string)$limit;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jidfrom' => $jid,
|
||||||
|
'jidto' => $jid,
|
||||||
|
'published' => $date
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoomSubject($room) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from message
|
||||||
|
where jidfrom = :jidfrom
|
||||||
|
and subject != \'\'
|
||||||
|
order by published desc
|
||||||
|
limit 1';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'jidfrom' => $room
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMessage() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from message
|
||||||
|
where session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Message',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Message');
|
||||||
|
}
|
||||||
|
}
|
415
sources/app/models/postn/Postn.php
Normal file
415
sources/app/models/postn/Postn.php
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modl;
|
||||||
|
|
||||||
|
use Respect\Validation\Validator;
|
||||||
|
|
||||||
|
class Postn extends Model {
|
||||||
|
public $origin; // Where the post is comming from (jid or server)
|
||||||
|
public $node; // microblog or pubsub
|
||||||
|
public $nodeid; // the ID if the item
|
||||||
|
|
||||||
|
public $aname; // author name
|
||||||
|
public $aid; // author id
|
||||||
|
public $aemail; // author email
|
||||||
|
|
||||||
|
public $title; //
|
||||||
|
public $content; // The content
|
||||||
|
public $contentraw; // The raw content
|
||||||
|
public $contentcleaned; // The cleanned content
|
||||||
|
|
||||||
|
public $commentplace;
|
||||||
|
|
||||||
|
public $published; //
|
||||||
|
public $updated; //
|
||||||
|
public $delay; //
|
||||||
|
|
||||||
|
public $picture; // Tell if the post contain embeded pictures
|
||||||
|
|
||||||
|
public $lat;
|
||||||
|
public $lon;
|
||||||
|
|
||||||
|
public $links;
|
||||||
|
|
||||||
|
public $privacy;
|
||||||
|
|
||||||
|
public $hash;
|
||||||
|
|
||||||
|
private $youtube;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->hash = md5(openssl_random_pseudo_bytes(5));
|
||||||
|
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"origin" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":96, "key":true },
|
||||||
|
"nodeid" :
|
||||||
|
{"type":"string", "size":96, "key":true },
|
||||||
|
"aname" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"aid" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"aemail" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"title" :
|
||||||
|
{"type":"text" },
|
||||||
|
"content" :
|
||||||
|
{"type":"text" },
|
||||||
|
"contentraw" :
|
||||||
|
{"type":"text" },
|
||||||
|
"contentcleaned" :
|
||||||
|
{"type":"text" },
|
||||||
|
"commentplace" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
|
||||||
|
"published" :
|
||||||
|
{"type":"date" },
|
||||||
|
"updated" :
|
||||||
|
{"type":"date" },
|
||||||
|
"delay" :
|
||||||
|
{"type":"date" },
|
||||||
|
|
||||||
|
"lat" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"lon" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
|
||||||
|
"links" :
|
||||||
|
{"type":"text" },
|
||||||
|
"picture" :
|
||||||
|
{"type":"int", "size":4 },
|
||||||
|
"hash" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContent($contents) {
|
||||||
|
$content = '';
|
||||||
|
foreach($contents as $c) {
|
||||||
|
switch($c->attributes()->type) {
|
||||||
|
case 'html':
|
||||||
|
case 'xhtml':
|
||||||
|
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||||
|
$import = @dom_import_simplexml($c->children());
|
||||||
|
if($import == null) {
|
||||||
|
$import = dom_import_simplexml($c);
|
||||||
|
}
|
||||||
|
$element = $dom->importNode($import, true);
|
||||||
|
$dom->appendChild($element);
|
||||||
|
return (string)$dom->saveHTML();
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
if(trim($c) != '') {
|
||||||
|
$this->__set('contentraw', trim($c));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
$content = (string)$c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($item, $from, $delay = false, $node = false) {
|
||||||
|
if($item->item)
|
||||||
|
$entry = $item->item;
|
||||||
|
else
|
||||||
|
$entry = $item;
|
||||||
|
|
||||||
|
if($from != '')
|
||||||
|
$this->__set('origin', $from);
|
||||||
|
|
||||||
|
if($node)
|
||||||
|
$this->__set('node', $node);
|
||||||
|
else
|
||||||
|
$this->__set('node', (string)$item->attributes()->node);
|
||||||
|
|
||||||
|
$this->__set('nodeid', (string)$entry->attributes()->id);
|
||||||
|
|
||||||
|
if($entry->entry->id)
|
||||||
|
$this->__set('nodeid', (string)$entry->entry->id);
|
||||||
|
|
||||||
|
// Get some informations on the author
|
||||||
|
if($entry->entry->author->name)
|
||||||
|
$this->__set('aname', (string)$entry->entry->author->name);
|
||||||
|
if($entry->entry->author->uri)
|
||||||
|
$this->__set('aid', substr((string)$entry->entry->author->uri, 5));
|
||||||
|
if($entry->entry->author->email)
|
||||||
|
$this->__set('aemail', (string)$entry->entry->author->email);
|
||||||
|
|
||||||
|
// Non standard support
|
||||||
|
if($entry->entry->source && $entry->entry->source->author->name)
|
||||||
|
$this->__set('aname', (string)$entry->entry->source->author->name);
|
||||||
|
if($entry->entry->source && $entry->entry->source->author->uri)
|
||||||
|
$this->__set('aid', substr((string)$entry->entry->source->author->uri, 5));
|
||||||
|
|
||||||
|
$this->__set('title', (string)$entry->entry->title);
|
||||||
|
|
||||||
|
// Content
|
||||||
|
if($entry->entry->summary && (string)$entry->entry->summary != '')
|
||||||
|
$summary = '<p class="summary">'.(string)$entry->entry->summary.'</p>';
|
||||||
|
else
|
||||||
|
$summary = '';
|
||||||
|
|
||||||
|
if($entry->entry && $entry->entry->content) {
|
||||||
|
$content = $this->getContent($entry->entry->content);
|
||||||
|
} elseif($summary == '')
|
||||||
|
$content = __('');
|
||||||
|
else
|
||||||
|
$content = '';
|
||||||
|
|
||||||
|
$content = $summary.$content;
|
||||||
|
|
||||||
|
if($entry->entry->updated)
|
||||||
|
$this->__set('updated', (string)$entry->entry->updated);
|
||||||
|
else
|
||||||
|
$this->__set('updated', gmdate(DATE_ISO8601));
|
||||||
|
|
||||||
|
if($entry->entry->published)
|
||||||
|
$this->__set('published', (string)$entry->entry->published);
|
||||||
|
elseif($entry->entry->updated)
|
||||||
|
$this->__set('published', (string)$entry->entry->updated);
|
||||||
|
else
|
||||||
|
$this->__set('published', gmdate(DATE_ISO8601));
|
||||||
|
|
||||||
|
if($delay)
|
||||||
|
$this->__set('delay', $delay);
|
||||||
|
|
||||||
|
$contentimg = $this->setAttachements($entry->entry->link);
|
||||||
|
|
||||||
|
// Tags parsing
|
||||||
|
if($entry->entry->category) {
|
||||||
|
$td = new \Modl\TagDAO;
|
||||||
|
$td->delete($this->__get('nodeid'));
|
||||||
|
|
||||||
|
if($entry->entry->category->count() == 1
|
||||||
|
&& isset($entry->entry->category->attributes()->term)) {
|
||||||
|
$tag = new \Modl\Tag;
|
||||||
|
$tag->nodeid = $this->__get('nodeid');
|
||||||
|
$tag->tag = (string)$entry->entry->category->attributes()->term;
|
||||||
|
$td->set($tag);
|
||||||
|
} else {
|
||||||
|
foreach($entry->entry->category as $cat) {
|
||||||
|
$tag = new \Modl\Tag;
|
||||||
|
$tag->nodeid = $this->__get('nodeid');
|
||||||
|
$tag->tag = (string)$cat->attributes()->term;
|
||||||
|
$td->set($tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($contentimg != '')
|
||||||
|
$content .= '<br />'.$contentimg;
|
||||||
|
|
||||||
|
if(!isset($this->commentplace))
|
||||||
|
$this->__set('commentplace', $this->origin);
|
||||||
|
|
||||||
|
$this->__set('content', trim($content));
|
||||||
|
$this->contentcleaned = purifyHTML(html_entity_decode($this->content));
|
||||||
|
|
||||||
|
if($entry->entry->geoloc) {
|
||||||
|
if($entry->entry->geoloc->lat != 0)
|
||||||
|
$this->__set('lat', (string)$entry->entry->geoloc->lat);
|
||||||
|
if($entry->entry->geoloc->lon != 0)
|
||||||
|
$this->__set('lon', (string)$entry->entry->geoloc->lon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function typeIsPicture($type) {
|
||||||
|
return in_array($type, array('image/jpeg', 'image/png', 'image/jpg', 'image/gif'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function typeIsLink($type) {
|
||||||
|
return $type == 'text/html';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setAttachements($links) {
|
||||||
|
$contentimg = '';
|
||||||
|
|
||||||
|
$l = array();
|
||||||
|
|
||||||
|
foreach($links as $attachment) {
|
||||||
|
$enc = array();
|
||||||
|
$enc = (array)$attachment->attributes();
|
||||||
|
$enc = $enc['@attributes'];
|
||||||
|
array_push($l, $enc);
|
||||||
|
|
||||||
|
if(array_key_exists('type', $enc)
|
||||||
|
&& $this->typeIsPicture($enc['type'])) {
|
||||||
|
$this->picture = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((string)$attachment->attributes()->title == 'comments') {
|
||||||
|
$substr = explode('?',substr((string)$attachment->attributes()->href, 5));
|
||||||
|
$this->commentplace = reset($substr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($l))
|
||||||
|
$this->links = serialize($l);
|
||||||
|
|
||||||
|
return $contentimg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAttachements()
|
||||||
|
{
|
||||||
|
$attachements = null;
|
||||||
|
$this->picture = null;
|
||||||
|
|
||||||
|
if(isset($this->links)) {
|
||||||
|
$attachements = array('pictures' => array(), 'files' => array(), 'links' => array());
|
||||||
|
|
||||||
|
$links = unserialize($this->links);
|
||||||
|
foreach($links as $l) {
|
||||||
|
if(isset($l['type']) && $this->typeIsPicture($l['type'])) {
|
||||||
|
if($this->picture == null) {
|
||||||
|
$this->picture = $l['href'];
|
||||||
|
}
|
||||||
|
array_push($attachements['pictures'], $l);
|
||||||
|
} elseif((isset($l['type']) && $this->typeIsLink($l['type'])
|
||||||
|
|| in_array($l['rel'], array('related', 'alternate')))
|
||||||
|
&& Validator::url()->validate($l['href'])) {
|
||||||
|
if($this->youtube == null
|
||||||
|
&& preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $l['href'], $match)) {
|
||||||
|
$this->youtube = $match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attachements['links'], array('href' => $l['href'], 'url' => parse_url($l['href'])));
|
||||||
|
} elseif(isset($l['rel']) && $l['rel'] == 'enclosure') {
|
||||||
|
array_push($attachements['files'], $l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($attachements['pictures'])) unset($attachements['pictures']);
|
||||||
|
if(empty($attachements['files'])) unset($attachements['files']);
|
||||||
|
if(empty($attachements['links'])) unset($attachements['links']);
|
||||||
|
|
||||||
|
return $attachements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAttachement()
|
||||||
|
{
|
||||||
|
$attachements = $this->getAttachements();
|
||||||
|
if(isset($attachements['pictures']) && !isset($attachements['links'])) {
|
||||||
|
return $attachements['pictures'][0];
|
||||||
|
}
|
||||||
|
if(isset($attachements['files'])) {
|
||||||
|
return $attachements['files'][0];
|
||||||
|
}
|
||||||
|
if(isset($attachements['links'])) {
|
||||||
|
return $attachements['links'][0];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPicture()
|
||||||
|
{
|
||||||
|
return $this->picture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getYoutube()
|
||||||
|
{
|
||||||
|
return $this->youtube;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlace()
|
||||||
|
{
|
||||||
|
return (isset($this->lat, $this->lon) && $this->lat != '' && $this->lon != '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isMine()
|
||||||
|
{
|
||||||
|
$user = new \User();
|
||||||
|
|
||||||
|
return ($this->aid == $user->getLogin()
|
||||||
|
|| $this->origin == $user->getLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUUID()
|
||||||
|
{
|
||||||
|
if(substr($this->nodeid, 10) == 'urn:uuid:') {
|
||||||
|
return $this->nodeid;
|
||||||
|
} else {
|
||||||
|
return 'urn:uuid:'.generateUUID($this->nodeid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isMicroblog()
|
||||||
|
{
|
||||||
|
return ($this->node == "urn:xmpp:microblog:0");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEditable()
|
||||||
|
{
|
||||||
|
return ($this->contentraw != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isShort()
|
||||||
|
{
|
||||||
|
return (strlen($this->contentcleaned) < 700);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicUrl()
|
||||||
|
{
|
||||||
|
if($this->isMicroblog()) {
|
||||||
|
return \Route::urlize('blog', array($this->origin, $this->nodeid));
|
||||||
|
} else {
|
||||||
|
return \Route::urlize('node', array($this->origin, $this->node, $this->nodeid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTags()
|
||||||
|
{
|
||||||
|
$td = new \Modl\TagDAO;
|
||||||
|
$tags = $td->getTags($this->nodeid);
|
||||||
|
if(is_array($tags)) {
|
||||||
|
return array_map(function($tag) { return $tag->tag; }, $tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTagsImploded()
|
||||||
|
{
|
||||||
|
$tags = $this->getTags();
|
||||||
|
if(is_array($tags)) {
|
||||||
|
return implode(', ', $tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPublic() {
|
||||||
|
return (isset($this->privacy) && $this->privacy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContactPostn extends Postn {
|
||||||
|
public $jid;
|
||||||
|
|
||||||
|
public $fn;
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
public $privacy;
|
||||||
|
|
||||||
|
public $phototype;
|
||||||
|
public $photobin;
|
||||||
|
|
||||||
|
public $nickname;
|
||||||
|
|
||||||
|
function getContact() {
|
||||||
|
$c = new Contact();
|
||||||
|
$c->jid = $this->aid;
|
||||||
|
$c->fn = $this->fn;
|
||||||
|
$c->name = $this->name;
|
||||||
|
$c->nickname = $this->nickname;
|
||||||
|
$c->phototype = $this->phototype;
|
||||||
|
$c->photobin = $this->photobin;
|
||||||
|
|
||||||
|
return $c;
|
||||||
|
}
|
||||||
|
}
|
625
sources/app/models/postn/PostnDAO.php
Normal file
625
sources/app/models/postn/PostnDAO.php
Normal file
|
@ -0,0 +1,625 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class PostnDAO extends SQL {
|
||||||
|
function set(Postn $post) {
|
||||||
|
$this->_sql = '
|
||||||
|
update postn
|
||||||
|
set aname = :aname,
|
||||||
|
aid = :aid,
|
||||||
|
aemail = :aemail,
|
||||||
|
|
||||||
|
title = :title,
|
||||||
|
content = :content,
|
||||||
|
contentraw = :contentraw,
|
||||||
|
contentcleaned = :contentcleaned,
|
||||||
|
|
||||||
|
commentplace = :commentplace,
|
||||||
|
|
||||||
|
published = :published,
|
||||||
|
updated = :updated,
|
||||||
|
delay = :delay,
|
||||||
|
|
||||||
|
lat = :lat,
|
||||||
|
lon = :lon,
|
||||||
|
|
||||||
|
links = :links,
|
||||||
|
picture = :picture,
|
||||||
|
|
||||||
|
hash = :hash
|
||||||
|
|
||||||
|
where origin = :origin
|
||||||
|
and node = :node
|
||||||
|
and nodeid = :nodeid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'aname' => $post->aname,
|
||||||
|
'aid' => $post->aid,
|
||||||
|
'aemail' => $post->aemail,
|
||||||
|
|
||||||
|
'title' => $post->title,
|
||||||
|
'content' => $post->content,
|
||||||
|
'contentraw' => $post->contentraw,
|
||||||
|
'contentcleaned' => $post->contentcleaned,
|
||||||
|
|
||||||
|
'commentplace' => $post->commentplace,
|
||||||
|
|
||||||
|
'published' => $post->published,
|
||||||
|
'updated' => $post->updated,
|
||||||
|
'delay' => $post->delay,
|
||||||
|
|
||||||
|
'lat' => $post->lat,
|
||||||
|
'lon' => $post->lon,
|
||||||
|
|
||||||
|
'links' => $post->links,
|
||||||
|
'picture' => $post->picture,
|
||||||
|
|
||||||
|
'hash' => $post->hash,
|
||||||
|
|
||||||
|
'origin' => $post->origin,
|
||||||
|
'node' => $post->node,
|
||||||
|
'nodeid' => $post->nodeid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Postn');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql ='
|
||||||
|
insert into postn
|
||||||
|
(
|
||||||
|
origin,
|
||||||
|
node,
|
||||||
|
nodeid,
|
||||||
|
|
||||||
|
aname,
|
||||||
|
aid,
|
||||||
|
aemail,
|
||||||
|
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
contentraw,
|
||||||
|
contentcleaned,
|
||||||
|
|
||||||
|
commentplace,
|
||||||
|
|
||||||
|
published,
|
||||||
|
updated,
|
||||||
|
delay,
|
||||||
|
|
||||||
|
lat,
|
||||||
|
lon,
|
||||||
|
|
||||||
|
links,
|
||||||
|
picture,
|
||||||
|
|
||||||
|
hash)
|
||||||
|
values(
|
||||||
|
:origin,
|
||||||
|
:node,
|
||||||
|
:nodeid,
|
||||||
|
|
||||||
|
:aname,
|
||||||
|
:aid,
|
||||||
|
:aemail,
|
||||||
|
|
||||||
|
:title,
|
||||||
|
:content,
|
||||||
|
:contentraw,
|
||||||
|
:contentcleaned,
|
||||||
|
|
||||||
|
:commentplace,
|
||||||
|
|
||||||
|
:published,
|
||||||
|
:updated,
|
||||||
|
:delay,
|
||||||
|
|
||||||
|
:lat,
|
||||||
|
:lon,
|
||||||
|
|
||||||
|
:links,
|
||||||
|
:picture,
|
||||||
|
|
||||||
|
:hash
|
||||||
|
)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'aname' => $post->aname,
|
||||||
|
'aid' => $post->aid,
|
||||||
|
'aemail' => $post->aemail,
|
||||||
|
|
||||||
|
'title' => $post->title,
|
||||||
|
'content' => $post->content,
|
||||||
|
'contentraw' => $post->contentraw,
|
||||||
|
'contentcleaned' => $post->contentcleaned,
|
||||||
|
|
||||||
|
'commentplace' => $post->commentplace,
|
||||||
|
|
||||||
|
'published' => $post->published,
|
||||||
|
'updated' => $post->updated,
|
||||||
|
'delay' => $post->delay,
|
||||||
|
|
||||||
|
'lat' => $post->lat,
|
||||||
|
'lon' => $post->lon,
|
||||||
|
|
||||||
|
'links' => $post->links,
|
||||||
|
'picture' => $post->picture,
|
||||||
|
|
||||||
|
'hash' => $post->hash,
|
||||||
|
|
||||||
|
'origin' => $post->origin,
|
||||||
|
'node' => $post->node,
|
||||||
|
'nodeid' => $post->nodeid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Postn');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($nodeid) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from postn
|
||||||
|
where nodeid = :nodeid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'nodeid' => $nodeid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Postn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNode($origin, $node) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from postn
|
||||||
|
where origin = :origin
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $origin,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Postn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNode($from, $node, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where ((postn.origin, node) in (select server, node from subscription where jid = :aid))
|
||||||
|
and postn.origin = :origin
|
||||||
|
and postn.node = :node
|
||||||
|
and postn.node != \'urn:xmpp:microblog:0\'
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
if($limitr !== false)
|
||||||
|
$this->_sql = $this->_sql.' limit '.(int)$limitr.' offset '.(int)$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'aid' => $this->_user, // TODO: Little hack to bypass the check, need to fix it in Modl
|
||||||
|
'origin' => $from,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPublicTag($tag, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where nodeid in (select nodeid from tag where tag = :title)
|
||||||
|
and privacy.value = 1
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
if($limitr !== false)
|
||||||
|
$this->_sql = $this->_sql.' limit '.(int)$limitr.' offset '.(int)$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'title' => $tag # Hack
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodeUnfiltered($from, $node, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.origin = :origin
|
||||||
|
and postn.node = :node
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
if($limitr !== false)
|
||||||
|
$this->_sql = $this->_sql.' limit '.(int)$limitr.' offset '.(int)$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $from,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGallery($from, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.aid = :aid
|
||||||
|
and postn.picture = 1
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
if($limitr !== false)
|
||||||
|
$this->_sql = $this->_sql.' limit '.(int)$limitr.' offset '.(int)$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'aid' => $from // Another hack
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItem($id) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.nodeid = :nodeid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'nodeid' => $id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllPosts($jid = false, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where (
|
||||||
|
(postn.origin in (select jid from rosterlink where session = :origin and rostersubscription in (\'both\', \'to\')) and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or (postn.origin = :origin and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or ((postn.origin, node) in (select server, node from subscription where jid = :origin))
|
||||||
|
)
|
||||||
|
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
|
||||||
|
and postn.node not like \'urn:xmpp:inbox\'
|
||||||
|
order by postn.published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
if($jid == false)
|
||||||
|
$jid = $this->_user;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFeed($limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where ((postn.origin in (select jid from rosterlink where session = :origin and rostersubscription in (\'both\', \'to\')) and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or (postn.origin = :origin and node = \'urn:xmpp:microblog:0\'))
|
||||||
|
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
|
||||||
|
and postn.node not like \'urn:xmpp:inbox\'
|
||||||
|
order by postn.published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNews($limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where ((postn.origin, node) in (select server, node from subscription where jid = :origin))
|
||||||
|
order by postn.published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getMe($limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.origin = :origin and postn.node = \'urn:xmpp:microblog:0\'
|
||||||
|
order by postn.published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
function getPublic($origin, $node, $limitf = false, $limitr = false) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.origin = :origin
|
||||||
|
and postn.node = :node
|
||||||
|
and privacy.value = 1
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
if($limitr !== false)
|
||||||
|
$this->_sql = $this->_sql.' limit '.(int)$limitr.' offset '.(int)$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $origin,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPublicItem($origin, $node, $nodeid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid, privacy.value as privacy from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where postn.origin = :origin
|
||||||
|
and postn.node = :node
|
||||||
|
and privacy.value = 1
|
||||||
|
and postn.nodeid = :nodeid
|
||||||
|
order by postn.published desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $origin,
|
||||||
|
'node' => $node,
|
||||||
|
'nodeid' => $nodeid,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fixme
|
||||||
|
function getComments($posts) {
|
||||||
|
$commentsid = '';
|
||||||
|
if(is_array($posts)) {
|
||||||
|
$i = 0;
|
||||||
|
foreach($posts as $post) {
|
||||||
|
if($i == 0)
|
||||||
|
$commentsid = "'urn:xmpp:microblog:0:comments/".$post->nodeid."'";
|
||||||
|
else
|
||||||
|
$commentsid .= ",'urn:xmpp:microblog:0:comments/".$post->nodeid."'";
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$commentsid = "'urn:xmpp:microblog:0:comments/".$posts->nodeid."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
// We request all the comments relative to our messages
|
||||||
|
$this->_sql = '
|
||||||
|
select *, postn.aid as jid from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
where postn.node in ('.$commentsid.')
|
||||||
|
order by postn.published';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPost() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from postn
|
||||||
|
where session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Postn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCountSince($date) {
|
||||||
|
$this->_sql = '
|
||||||
|
select count(*) from postn
|
||||||
|
where (
|
||||||
|
(postn.origin in (select jid from rosterlink where session = :origin and rostersubscription in (\'both\', \'to\')) and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or (postn.origin = :origin and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or ((postn.origin, node) in (select server, node from subscription where jid = :origin))
|
||||||
|
)
|
||||||
|
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
|
||||||
|
and postn.node not like \'urn:xmpp:inbox\'
|
||||||
|
and published > :published
|
||||||
|
';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user,
|
||||||
|
'published' => $date
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$arr = $this->run(null, 'array');
|
||||||
|
if(is_array($arr) && isset($arr[0])) {
|
||||||
|
$arr = array_values($arr[0]);
|
||||||
|
return (int)$arr[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastDate() {
|
||||||
|
$this->_sql = '
|
||||||
|
select published from postn
|
||||||
|
where (
|
||||||
|
(postn.origin in (select jid from rosterlink where session = :origin and rostersubscription in (\'both\', \'to\')) and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or (postn.origin = :origin and node = \'urn:xmpp:microblog:0\')
|
||||||
|
or ((postn.origin, node) in (select server, node from subscription where jid = :origin))
|
||||||
|
)
|
||||||
|
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
|
||||||
|
and postn.node not like \'urn:xmpp:inbox\'
|
||||||
|
order by postn.published desc
|
||||||
|
limit 1 offset 0';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$arr = $this->run(null, 'array');
|
||||||
|
if(is_array($arr) && isset($arr[0]))
|
||||||
|
return $arr[0]['published'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastPublished($limitf = false, $limitr = false)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from postn
|
||||||
|
where
|
||||||
|
node != \'urn:xmpp:microblog:0\'
|
||||||
|
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
|
||||||
|
and postn.node not like \'urn:xmpp:inbox\'
|
||||||
|
and postn.origin not like \'nsfw%\'
|
||||||
|
and ((postn.origin, node) not in (select server, node from subscription where jid = :origin))
|
||||||
|
order by published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Postn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastBlogPublic($limitf = false, $limitr = false)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select * from postn
|
||||||
|
left outer join contact on postn.aid = contact.jid
|
||||||
|
left outer join privacy on postn.nodeid = privacy.pkey
|
||||||
|
where
|
||||||
|
node = \'urn:xmpp:microblog:0\'
|
||||||
|
and postn.origin not in (select jid from rosterlink where session = :origin)
|
||||||
|
and privacy.value = 1
|
||||||
|
order by published desc
|
||||||
|
';
|
||||||
|
|
||||||
|
if($limitr)
|
||||||
|
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'origin' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('ContactPostn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function exist($id) {
|
||||||
|
$this->_sql = '
|
||||||
|
select count(*) from postn
|
||||||
|
where postn.nodeid = :nodeid
|
||||||
|
';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Postn',
|
||||||
|
array(
|
||||||
|
'nodeid' => $id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$arr = $this->run(null, 'array');
|
||||||
|
if(is_array($arr) && isset($arr[0])) {
|
||||||
|
$arr = array_values($arr[0]);
|
||||||
|
return (bool)$arr[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
185
sources/app/models/presence/Presence.php
Normal file
185
sources/app/models/presence/Presence.php
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modl;
|
||||||
|
|
||||||
|
class Presence extends Model {
|
||||||
|
protected $id;
|
||||||
|
|
||||||
|
protected $session;
|
||||||
|
protected $jid;
|
||||||
|
|
||||||
|
// General presence informations
|
||||||
|
protected $resource;
|
||||||
|
protected $value;
|
||||||
|
protected $priority;
|
||||||
|
protected $status;
|
||||||
|
|
||||||
|
// Client Informations
|
||||||
|
protected $node;
|
||||||
|
protected $ver;
|
||||||
|
|
||||||
|
// Delay - XEP 0203
|
||||||
|
protected $delay;
|
||||||
|
|
||||||
|
// Last Activity - XEP 0256
|
||||||
|
protected $last;
|
||||||
|
|
||||||
|
// Current Jabber OpenPGP Usage - XEP-0027
|
||||||
|
protected $publickey;
|
||||||
|
protected $muc;
|
||||||
|
protected $mucjid;
|
||||||
|
protected $mucaffiliation;
|
||||||
|
protected $mucrole;
|
||||||
|
|
||||||
|
// vcard-temp:x:update, not saved in the DB
|
||||||
|
public $photo = false;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"id" :
|
||||||
|
{"type":"string", "size":64, "mandatory":true },
|
||||||
|
"session" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"resource" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"value" :
|
||||||
|
{"type":"int", "size":11, "mandatory":true },
|
||||||
|
"priority" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"status" :
|
||||||
|
{"type":"text"},
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"ver" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"delay" :
|
||||||
|
{"type":"date"},
|
||||||
|
"last" :
|
||||||
|
{"type":"int", "size":11 },
|
||||||
|
"publickey" :
|
||||||
|
{"type":"text"},
|
||||||
|
"muc" :
|
||||||
|
{"type":"int", "size":1 },
|
||||||
|
"mucjid" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"mucaffiliation" :
|
||||||
|
{"type":"string", "size":32 },
|
||||||
|
"mucrole" :
|
||||||
|
{"type":"string", "size":32 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPresence($stanza) {
|
||||||
|
$jid = explode('/',(string)$stanza->attributes()->from);
|
||||||
|
|
||||||
|
if($stanza->attributes()->to)
|
||||||
|
$to = current(explode('/',(string)$stanza->attributes()->to));
|
||||||
|
else
|
||||||
|
$to = $jid[0];
|
||||||
|
|
||||||
|
$this->__set('session', $to);
|
||||||
|
$this->__set('jid', $jid[0]);
|
||||||
|
if(isset($jid[1]))
|
||||||
|
$this->__set('resource', $jid[1]);
|
||||||
|
else
|
||||||
|
$this->__set('resource', 'default');
|
||||||
|
|
||||||
|
$this->__set('status', (string)$stanza->status);
|
||||||
|
|
||||||
|
if($stanza->c) {
|
||||||
|
$this->__set('node', (string)$stanza->c->attributes()->node);
|
||||||
|
$this->__set('ver', (string)$stanza->c->attributes()->ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($stanza->priority)
|
||||||
|
$this->__set('priority', (string)$stanza->priority);
|
||||||
|
|
||||||
|
if((string)$stanza->attributes()->type == 'error') {
|
||||||
|
$this->__set('value', 6);
|
||||||
|
} elseif((string)$stanza->attributes()->type == 'unavailable') {
|
||||||
|
$this->__set('value', 5);
|
||||||
|
} elseif((string)$stanza->show == 'away') {
|
||||||
|
$this->__set('value', 2);
|
||||||
|
} elseif((string)$stanza->show == 'dnd') {
|
||||||
|
$this->__set('value', 3);
|
||||||
|
} elseif((string)$stanza->show == 'xa') {
|
||||||
|
$this->__set('value', 4);
|
||||||
|
} else {
|
||||||
|
$this->__set('value', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific XEP
|
||||||
|
if($stanza->x) {
|
||||||
|
foreach($stanza->children() as $name => $c) {
|
||||||
|
switch($c->attributes()->xmlns) {
|
||||||
|
case 'jabber:x:signed' :
|
||||||
|
$this->__set('publickey', (string)$c);
|
||||||
|
break;
|
||||||
|
case 'http://jabber.org/protocol/muc#user' :
|
||||||
|
$this->__set('muc ', true);
|
||||||
|
if($c->item->attributes()->jid)
|
||||||
|
$this->__set('mucjid', cleanJid((string)$c->item->attributes()->jid));
|
||||||
|
else
|
||||||
|
$this->__set('mucjid', (string)$stanza->attributes()->from);
|
||||||
|
|
||||||
|
$this->__set('mucrole', (string)$c->item->attributes()->role);
|
||||||
|
$this->__set('mucaffiliation', (string)$c->item->attributes()->affiliation);
|
||||||
|
break;
|
||||||
|
case 'vcard-temp:x:update' :
|
||||||
|
$this->__set('photo', true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($stanza->delay) {
|
||||||
|
$this->__set('delay',
|
||||||
|
gmdate(
|
||||||
|
'Y-m-d H:i:s',
|
||||||
|
strtotime(
|
||||||
|
(string)$stanza->delay->attributes()->stamp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($stanza->query) {
|
||||||
|
$this->__set('last', (int)$stanza->query->attributes()->seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPresence() {
|
||||||
|
$txt = array(
|
||||||
|
1 => 'online',
|
||||||
|
2 => 'away',
|
||||||
|
3 => 'dnd',
|
||||||
|
4 => 'xa',
|
||||||
|
5 => 'offline',
|
||||||
|
6 => 'server_error'
|
||||||
|
);
|
||||||
|
|
||||||
|
$arr = array();
|
||||||
|
$arr['jid'] = $this->jid;
|
||||||
|
$arr['resource'] = $this->resource;
|
||||||
|
$arr['presence'] = $this->value;
|
||||||
|
$arr['presence_txt'] = $txt[$this->value];
|
||||||
|
$arr['priority'] = $this->priority;
|
||||||
|
$arr['status'] = $this->status;
|
||||||
|
$arr['node'] = $this->node;
|
||||||
|
$arr['ver'] = $this->ver;
|
||||||
|
|
||||||
|
return $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isChatroom() {
|
||||||
|
if(filter_var($this->jid, FILTER_VALIDATE_EMAIL))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
239
sources/app/models/presence/PresenceDAO.php
Normal file
239
sources/app/models/presence/PresenceDAO.php
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modl;
|
||||||
|
|
||||||
|
class PresenceDAO extends SQL {
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(Presence $presence) {
|
||||||
|
$id = sha1(
|
||||||
|
$presence->session.
|
||||||
|
$presence->jid.
|
||||||
|
$presence->resource
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
update presence
|
||||||
|
set value = :value,
|
||||||
|
priority = :priority,
|
||||||
|
status = :status,
|
||||||
|
node = :node,
|
||||||
|
ver = :ver,
|
||||||
|
delay = :delay,
|
||||||
|
last = :last,
|
||||||
|
publickey = :publickey,
|
||||||
|
muc = :muc,
|
||||||
|
mucjid = :mucjid,
|
||||||
|
mucaffiliation = :mucaffiliation,
|
||||||
|
mucrole = :mucrole
|
||||||
|
where id = :id';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'value' => $presence->value,
|
||||||
|
'priority' => $presence->priority,
|
||||||
|
'status' => $presence->status,
|
||||||
|
'node' => $presence->node,
|
||||||
|
'ver' => $presence->ver,
|
||||||
|
'delay' => $presence->delay,
|
||||||
|
'last' => $presence->last,
|
||||||
|
'publickey' => $presence->publickey,
|
||||||
|
'muc' => $presence->muc,
|
||||||
|
'mucjid' => $presence->mucjid,
|
||||||
|
'mucaffiliation' => $presence->mucaffiliation,
|
||||||
|
'mucrole' => $presence->mucrole,
|
||||||
|
'id' => $id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Presence');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into presence
|
||||||
|
(id,
|
||||||
|
session,
|
||||||
|
jid,
|
||||||
|
resource,
|
||||||
|
value,
|
||||||
|
priority,
|
||||||
|
status,
|
||||||
|
node,
|
||||||
|
ver,
|
||||||
|
delay,
|
||||||
|
last,
|
||||||
|
publickey,
|
||||||
|
muc,
|
||||||
|
mucjid,
|
||||||
|
mucaffiliation,
|
||||||
|
mucrole)
|
||||||
|
values(
|
||||||
|
:id,
|
||||||
|
:session,
|
||||||
|
:jid,
|
||||||
|
:resource,
|
||||||
|
:value,
|
||||||
|
:priority,
|
||||||
|
:status,
|
||||||
|
:node,
|
||||||
|
:ver,
|
||||||
|
:delay,
|
||||||
|
:last,
|
||||||
|
:publickey,
|
||||||
|
:muc,
|
||||||
|
:mucjid,
|
||||||
|
:mucaffiliation,
|
||||||
|
:mucrole)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'id' => $id,
|
||||||
|
'session' => $presence->session,
|
||||||
|
'jid' => $presence->jid,
|
||||||
|
'resource' => $presence->resource,
|
||||||
|
'value' => $presence->value,
|
||||||
|
'priority' => $presence->priority,
|
||||||
|
'status' => $presence->status,
|
||||||
|
'node' => $presence->node,
|
||||||
|
'ver' => $presence->ver,
|
||||||
|
'delay' => $presence->delay,
|
||||||
|
'last' => $presence->last,
|
||||||
|
'publickey' => $presence->publickey,
|
||||||
|
'muc' => $presence->muc,
|
||||||
|
'mucjid' => $presence->mucjid,
|
||||||
|
'mucaffiliation' => $presence->mucaffiliation,
|
||||||
|
'mucrole' => $presence->mucrole
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Presence');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete(Presence $presence)
|
||||||
|
{
|
||||||
|
$id = sha1(
|
||||||
|
$presence->session.
|
||||||
|
$presence->jid.
|
||||||
|
$presence->resource
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
delete from presence
|
||||||
|
where id = :id';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'id' => $id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from presence;
|
||||||
|
';
|
||||||
|
|
||||||
|
$this->prepare('Presence');
|
||||||
|
return $this->run('Presence');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPresence($jid, $resource) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from presence
|
||||||
|
where
|
||||||
|
session = :session
|
||||||
|
and jid = :jid
|
||||||
|
and resource = :resource';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid,
|
||||||
|
'resource' => $resource
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMyPresenceRoom($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from presence
|
||||||
|
where
|
||||||
|
session = :session
|
||||||
|
and jid = :jid
|
||||||
|
and mucjid = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJid($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from presence
|
||||||
|
where
|
||||||
|
session = :session
|
||||||
|
and jid = :jid
|
||||||
|
order by mucaffiliation desc';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPresence($session) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from presence
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMuc($muc) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from presence
|
||||||
|
where
|
||||||
|
session = :session
|
||||||
|
and jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Presence',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $muc
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Presence');
|
||||||
|
}
|
||||||
|
}
|
38
sources/app/models/privacy/Privacy.php
Normal file
38
sources/app/models/privacy/Privacy.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Privacy extends Model {
|
||||||
|
public $pkey;
|
||||||
|
public $value;
|
||||||
|
protected $hash;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"pkey" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true, "key":true },
|
||||||
|
"value" :
|
||||||
|
{"type":"int", "size":4, "mandatory":true },
|
||||||
|
"hash" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
static function set($key, $value) {
|
||||||
|
$p = new Privacy();
|
||||||
|
$p->pkey = $key;
|
||||||
|
$p->value = $value;
|
||||||
|
$p->hash = md5(openssl_random_pseudo_bytes(5));
|
||||||
|
|
||||||
|
$pd = new PrivacyDAO();
|
||||||
|
$pd->set($p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function get($key) {
|
||||||
|
$pd = new PrivacyDAO();
|
||||||
|
return (int)$pd->get($key)->value;
|
||||||
|
}
|
||||||
|
}
|
58
sources/app/models/privacy/PrivacyDAO.php
Normal file
58
sources/app/models/privacy/PrivacyDAO.php
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class PrivacyDAO extends SQL {
|
||||||
|
function set(Privacy $p) {
|
||||||
|
$this->_sql = '
|
||||||
|
update privacy
|
||||||
|
set value = :value,
|
||||||
|
hash = :hash
|
||||||
|
where pkey = :pkey';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Privacy',
|
||||||
|
array(
|
||||||
|
'pkey' => $p->pkey,
|
||||||
|
'value' => $p->value,
|
||||||
|
'hash' => $p->hash
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Privacy');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into privacy
|
||||||
|
(pkey, value, hash)
|
||||||
|
values (:pkey,:value,:hash)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Privacy',
|
||||||
|
array(
|
||||||
|
'pkey' => $p->pkey,
|
||||||
|
'value' => $p->value,
|
||||||
|
'hash' => $p->hash
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Privacy');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($key) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from privacy
|
||||||
|
where
|
||||||
|
pkey = :pkey';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Privacy',
|
||||||
|
array(
|
||||||
|
'pkey' => $key
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Privacy', 'item');
|
||||||
|
}
|
||||||
|
}
|
54
sources/app/models/rosterlink/RosterLink.php
Normal file
54
sources/app/models/rosterlink/RosterLink.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class RosterLink extends Model {
|
||||||
|
public $session;
|
||||||
|
public $jid;
|
||||||
|
|
||||||
|
protected $rostername;
|
||||||
|
public $rosterask;
|
||||||
|
public $rostersubscription;
|
||||||
|
|
||||||
|
protected $groupname;
|
||||||
|
|
||||||
|
public $chaton;
|
||||||
|
|
||||||
|
public $publickey;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"session" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":96, "key":true },
|
||||||
|
"rostername" :
|
||||||
|
{"type":"string", "size":96 },
|
||||||
|
"rosterask" :
|
||||||
|
{"type":"string", "size":16 },
|
||||||
|
"rostersubscription" :
|
||||||
|
{"type":"string", "size":4, "mandatory":true },
|
||||||
|
"groupname" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"chaton" :
|
||||||
|
{"type":"int", "size":11 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function set($stanza) {
|
||||||
|
$this->jid = (string)$stanza->attributes()->jid;
|
||||||
|
|
||||||
|
if(isset($stanza->attributes()->name)
|
||||||
|
&& (string)$stanza->attributes()->name != '')
|
||||||
|
$this->__set('rostername', (string)$stanza->attributes()->name);
|
||||||
|
else
|
||||||
|
$this->__set('rostername', (string)$stanza->attributes()->jid);
|
||||||
|
$this->__set('rosterask', (string)$stanza->attributes()->ask);
|
||||||
|
$this->__set('rostersubscription', (string)$stanza->attributes()->subscription);
|
||||||
|
$this->__set('groupname', (string)$stanza->group);
|
||||||
|
}
|
||||||
|
}
|
230
sources/app/models/rosterlink/RosterLinkDAO.php
Normal file
230
sources/app/models/rosterlink/RosterLinkDAO.php
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class RosterLinkDAO extends SQL {
|
||||||
|
function set(RosterLink $r) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into rosterlink
|
||||||
|
(
|
||||||
|
session,
|
||||||
|
jid,
|
||||||
|
rostername,
|
||||||
|
rosterask,
|
||||||
|
rostersubscription,
|
||||||
|
groupname,
|
||||||
|
chaton)
|
||||||
|
values (
|
||||||
|
:session,
|
||||||
|
:jid,
|
||||||
|
:rostername,
|
||||||
|
:rosterask,
|
||||||
|
:rostersubscription,
|
||||||
|
:groupname,
|
||||||
|
:chaton
|
||||||
|
)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $r->jid,
|
||||||
|
'rostername' => $r->rostername,
|
||||||
|
'rosterask' => $r->rosterask,
|
||||||
|
'rostersubscription' => $r->rostersubscription,
|
||||||
|
'groupname' => $r->groupname,
|
||||||
|
'chaton' => $r->chaton
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setList($arr) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into rosterlink
|
||||||
|
(
|
||||||
|
session,
|
||||||
|
jid,
|
||||||
|
rostername,
|
||||||
|
rosterask,
|
||||||
|
rostersubscription,
|
||||||
|
groupname,
|
||||||
|
chaton)
|
||||||
|
values
|
||||||
|
';
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
foreach($arr as $r) {
|
||||||
|
$this->_sql .= "
|
||||||
|
(
|
||||||
|
:session_$i,
|
||||||
|
:jid_$i,
|
||||||
|
:rostername_$i,
|
||||||
|
:rosterask_$i,
|
||||||
|
:rostersubscription_$i,
|
||||||
|
:groupname_$i,
|
||||||
|
:chaton_$i
|
||||||
|
),";
|
||||||
|
|
||||||
|
$params = array_merge(
|
||||||
|
$params,
|
||||||
|
array(
|
||||||
|
"session_$i" => $this->_user,
|
||||||
|
"jid_$i" => $r->jid,
|
||||||
|
"rostername_$i" => $r->rostername,
|
||||||
|
"rosterask_$i" => $r->rosterask,
|
||||||
|
"rostersubscription_$i" => $r->rostersubscription,
|
||||||
|
"groupname_$i" => $r->groupname,
|
||||||
|
"chaton_$i" => $r->chaton
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_sql = substr($this->_sql, 0, -1);
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
$params
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(RosterLink $r) {
|
||||||
|
$this->_sql = '
|
||||||
|
update rosterlink
|
||||||
|
set rostername = :rostername,
|
||||||
|
rosterask = :rosterask,
|
||||||
|
rostersubscription = :rostersubscription,
|
||||||
|
groupname = :groupname,
|
||||||
|
chaton = :chaton
|
||||||
|
where session = :session
|
||||||
|
and jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $r->jid,
|
||||||
|
'rostername' => $r->rostername,
|
||||||
|
'rosterask' => $r->rosterask,
|
||||||
|
'rostersubscription' => $r->rostersubscription,
|
||||||
|
'groupname' => $r->groupname,
|
||||||
|
'chaton' => $r->chaton
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNow(RosterLink $r) {
|
||||||
|
$this->update($r);
|
||||||
|
|
||||||
|
if(!$this->_effective)
|
||||||
|
$this->set($r);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select *
|
||||||
|
from rosterlink
|
||||||
|
where session=:session
|
||||||
|
and jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroups() {
|
||||||
|
$this->_sql = '
|
||||||
|
select groupname
|
||||||
|
from rosterlink
|
||||||
|
where session = :session
|
||||||
|
group by groupname';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = $this->run('RosterLink');
|
||||||
|
|
||||||
|
if(is_array($results)) {
|
||||||
|
$arr = array();
|
||||||
|
|
||||||
|
foreach($results as $r)
|
||||||
|
array_push($arr, $r->groupname);
|
||||||
|
|
||||||
|
return $arr;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoster($to = null) {
|
||||||
|
if($to != null)
|
||||||
|
$session = $to;
|
||||||
|
else
|
||||||
|
$session = $this->_user;
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
select *
|
||||||
|
from rosterlink
|
||||||
|
where session=:session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearRosterLink() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from rosterlink
|
||||||
|
where session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($jid) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from rosterlink
|
||||||
|
where session = :session
|
||||||
|
and jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'RosterLink',
|
||||||
|
array(
|
||||||
|
'session' => $this->_user,
|
||||||
|
'jid' => $jid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('RosterLink');
|
||||||
|
}
|
||||||
|
}
|
62
sources/app/models/sessionx/Sessionx.php
Normal file
62
sources/app/models/sessionx/Sessionx.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Sessionx extends Model {
|
||||||
|
public $session;
|
||||||
|
public $username;
|
||||||
|
public $password;
|
||||||
|
public $hash;
|
||||||
|
public $resource;
|
||||||
|
public $rid;
|
||||||
|
public $sid;
|
||||||
|
public $id;
|
||||||
|
public $port;
|
||||||
|
public $host;
|
||||||
|
public $domain;
|
||||||
|
public $config;
|
||||||
|
public $active;
|
||||||
|
public $start;
|
||||||
|
public $timestamp;
|
||||||
|
public $mechanism;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"session" :
|
||||||
|
{"type":"string", "size":32, "key":true },
|
||||||
|
"username" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"password" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"hash" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"resource" :
|
||||||
|
{"type":"string", "size":16 },
|
||||||
|
"rid" :
|
||||||
|
{"type":"int", "size":8, "mandatory":true },
|
||||||
|
"sid" :
|
||||||
|
{"type":"string", "size":64 },
|
||||||
|
"id" :
|
||||||
|
{"type":"int", "size":8, "mandatory":true },
|
||||||
|
"port" :
|
||||||
|
{"type":"int", "size":5, "mandatory":true },
|
||||||
|
"host" :
|
||||||
|
{"type":"string", "size":64, "mandatory":true },
|
||||||
|
"domain" :
|
||||||
|
{"type":"string", "size":64, "mandatory":true },
|
||||||
|
"config" :
|
||||||
|
{"type":"text" },
|
||||||
|
"active" :
|
||||||
|
{"type":"int", "size":4 },
|
||||||
|
"start" :
|
||||||
|
{"type":"date" },
|
||||||
|
"timestamp" :
|
||||||
|
{"type":"date" },
|
||||||
|
"mechanism" :
|
||||||
|
{"type":"string", "size":16 }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
}
|
349
sources/app/models/sessionx/SessionxDAO.php
Normal file
349
sources/app/models/sessionx/SessionxDAO.php
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class SessionxDAO extends SQL {
|
||||||
|
function init(Sessionx $s) {
|
||||||
|
$this->_sql = '
|
||||||
|
update sessionx
|
||||||
|
set username = :username,
|
||||||
|
password = :password,
|
||||||
|
hash = :hash,
|
||||||
|
resource = :resource,
|
||||||
|
rid = :rid,
|
||||||
|
sid = :sid,
|
||||||
|
id = :id,
|
||||||
|
port = :port,
|
||||||
|
host = :host,
|
||||||
|
domain = :domain,
|
||||||
|
config = :config,
|
||||||
|
active = :active,
|
||||||
|
start = :start,
|
||||||
|
timestamp = :timestamp,
|
||||||
|
mechanism = :mechanism
|
||||||
|
where session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $s->session,
|
||||||
|
'username' => $s->username,
|
||||||
|
'password' => $s->password,
|
||||||
|
'hash' => $s->hash,
|
||||||
|
'resource' => $s->resource,
|
||||||
|
'rid' => $s->rid,
|
||||||
|
'sid' => $s->sid,
|
||||||
|
'id' => $s->id,
|
||||||
|
'port' => $s->port,
|
||||||
|
'host' => $s->host,
|
||||||
|
'domain' => $s->domain,
|
||||||
|
'config' => $s->config,
|
||||||
|
'active' => $s->active,
|
||||||
|
'start' => $s->start,
|
||||||
|
'timestamp' => $s->timestamp,
|
||||||
|
'mechanism' => $s->mechanism
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Sessionx');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into sessionx
|
||||||
|
(session,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
hash,
|
||||||
|
resource,
|
||||||
|
rid,
|
||||||
|
sid,
|
||||||
|
id,
|
||||||
|
port,
|
||||||
|
host,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
active,
|
||||||
|
start,
|
||||||
|
timestamp,
|
||||||
|
mechanism)
|
||||||
|
values
|
||||||
|
(:session,
|
||||||
|
:username,
|
||||||
|
:password,
|
||||||
|
:hash,
|
||||||
|
:resource,
|
||||||
|
:rid,
|
||||||
|
:sid,
|
||||||
|
:id,
|
||||||
|
:port,
|
||||||
|
:host,
|
||||||
|
:domain,
|
||||||
|
:config,
|
||||||
|
:active,
|
||||||
|
:start,
|
||||||
|
:timestamp,
|
||||||
|
:mechanism)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $s->session,
|
||||||
|
'username' => $s->username,
|
||||||
|
'password' => $s->password,
|
||||||
|
'hash' => $s->hash,
|
||||||
|
'resource' => $s->resource,
|
||||||
|
'rid' => $s->rid,
|
||||||
|
'sid' => $s->sid,
|
||||||
|
'id' => $s->id,
|
||||||
|
'port' => $s->port,
|
||||||
|
'host' => $s->host,
|
||||||
|
'domain' => $s->domain,
|
||||||
|
'config' => $s->config,
|
||||||
|
'active' => $s->active,
|
||||||
|
'start' => $s->start,
|
||||||
|
'timestamp' => $s->timestamp,
|
||||||
|
'mechanism' => $s->mechanism
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Sessionx');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update($session, $key, $value) {
|
||||||
|
$this->_sql = '
|
||||||
|
update sessionx
|
||||||
|
set
|
||||||
|
'.$key.' = :'.$key.',
|
||||||
|
timestamp = :timestamp
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session,
|
||||||
|
$key => $value,
|
||||||
|
'timestamp' => date(DATE_ISO8601)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Sessionx');
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($session) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from sessionx
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Sessionx', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHash($hash) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from sessionx
|
||||||
|
where
|
||||||
|
hash = :hash';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'hash' => $hash
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Sessionx', 'item');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getId($session) {
|
||||||
|
$this->_sql = '
|
||||||
|
select id from sessionx
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$value = $this->run(null, 'array');
|
||||||
|
$value = $value[0]['id'];
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
update sessionx
|
||||||
|
set
|
||||||
|
id = :id,
|
||||||
|
timestamp = :timestamp
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session,
|
||||||
|
'id' => $value+1,
|
||||||
|
'timestamp' => date(DATE_ISO8601)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run();
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRid($session) {
|
||||||
|
$this->_sql = '
|
||||||
|
select rid from sessionx
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$value = $this->run(null, 'array');
|
||||||
|
$value = $value[0]['rid'];
|
||||||
|
|
||||||
|
$this->_sql = '
|
||||||
|
update sessionx
|
||||||
|
set
|
||||||
|
rid = :rid,
|
||||||
|
timestamp = :timestamp
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session,
|
||||||
|
'rid' => $value+1,
|
||||||
|
'timestamp' => date(DATE_ISO8601)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run();
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($session) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from sessionx
|
||||||
|
where
|
||||||
|
session = :session';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'session' => $session
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Sessionx');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteEmpty() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from sessionx
|
||||||
|
where
|
||||||
|
active = 0';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Sessionx');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*function clean() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from sessionx
|
||||||
|
where timestamp < :timestamp';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'timestamp' => date(DATE_ISO8601, time() - 3600)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Sessionx');
|
||||||
|
}*/
|
||||||
|
function clear() {
|
||||||
|
$this->_sql = '
|
||||||
|
truncate table sessionx';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Sessionx');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from sessionx';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Sessionx');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConnected() {
|
||||||
|
$this->_sql = '
|
||||||
|
select count(*) from sessionx';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = $this->run(null, 'array');
|
||||||
|
$results = array_values($results[0]);
|
||||||
|
|
||||||
|
return (int)$results[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkConnected($username, $host)
|
||||||
|
{
|
||||||
|
$this->_sql = '
|
||||||
|
select count(*) from sessionx
|
||||||
|
where
|
||||||
|
username = :username
|
||||||
|
and host = :host';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Sessionx',
|
||||||
|
array(
|
||||||
|
'username' => $username,
|
||||||
|
'host' => $host
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = $this->run(null, 'array');
|
||||||
|
$results = array_values($results[0]);
|
||||||
|
|
||||||
|
return (int)$results[0];
|
||||||
|
}
|
||||||
|
}
|
54
sources/app/models/subscription/Subscription.php
Normal file
54
sources/app/models/subscription/Subscription.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Subscription extends Model {
|
||||||
|
public $jid;
|
||||||
|
protected $server;
|
||||||
|
protected $node;
|
||||||
|
protected $subscription;
|
||||||
|
protected $subid;
|
||||||
|
protected $title;
|
||||||
|
public $description;
|
||||||
|
public $tags;
|
||||||
|
public $timestamp;
|
||||||
|
public $name;
|
||||||
|
public $servicename;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"jid" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"server" :
|
||||||
|
{"type":"string", "size":64, "key":true },
|
||||||
|
"node" :
|
||||||
|
{"type":"string", "size":128, "key":true },
|
||||||
|
"subscription" :
|
||||||
|
{"type":"string", "size":128, "mandatory":true },
|
||||||
|
"subid" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"title" :
|
||||||
|
{"type":"string", "size":128 },
|
||||||
|
"tags" :
|
||||||
|
{"type":"text" },
|
||||||
|
"timestamp" :
|
||||||
|
{"type":"date" }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
function set($jid, $server, $node, $s) {
|
||||||
|
$this->__set('jid', $jid);
|
||||||
|
$this->__set('server', $server);
|
||||||
|
$this->__set('node', $node);
|
||||||
|
$this->__set('jid', (string)$s->attributes()->jid);
|
||||||
|
$this->__set('subscription', (string)$s->attributes()->subscription);
|
||||||
|
$this->__set('subid', (string)$s->attributes()->subid);
|
||||||
|
$this->__set('tags', serialize(array()));
|
||||||
|
|
||||||
|
if($this->subid = '')
|
||||||
|
$this->subid = 'default';
|
||||||
|
}
|
||||||
|
}
|
166
sources/app/models/subscription/SubscriptionDAO.php
Normal file
166
sources/app/models/subscription/SubscriptionDAO.php
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class SubscriptionDAO extends SQL {
|
||||||
|
function set(Subscription $s) {
|
||||||
|
$this->_sql = '
|
||||||
|
update subscription
|
||||||
|
set subscription = :subscription,
|
||||||
|
timestamp = :timestamp,
|
||||||
|
tags = :tags,
|
||||||
|
subid = :subid
|
||||||
|
where jid = :jid
|
||||||
|
and server = :server
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'subscription' => $s->subscription,
|
||||||
|
'timestamp' => date(DATE_ISO8601),
|
||||||
|
'jid' => $s->jid,
|
||||||
|
'server'=> $s->server,
|
||||||
|
'node' => $s->node,
|
||||||
|
'tags' => $s->tags,
|
||||||
|
'subid' => $s->subid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Subscription');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into subscription
|
||||||
|
(jid, server, node, subscription, subid, tags, timestamp)
|
||||||
|
values (:jid, :server, :node, :subscription, :subid, :tags, :timestamp)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'subscription' => $s->subscription,
|
||||||
|
'timestamp' => date(DATE_ISO8601),
|
||||||
|
'jid' => $s->jid,
|
||||||
|
'server'=> $s->server,
|
||||||
|
'node' => $s->node,
|
||||||
|
'tags' => $s->tags,
|
||||||
|
'subid' => $s->subid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Subscription');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($server, $node) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from subscription
|
||||||
|
where jid = :jid
|
||||||
|
and server = :server
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'server' => $server,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubscribed() {
|
||||||
|
$this->_sql = '
|
||||||
|
select
|
||||||
|
subscription.jid,
|
||||||
|
subscription.server,
|
||||||
|
subscription.node,
|
||||||
|
subscription,
|
||||||
|
item.name,
|
||||||
|
item.description,
|
||||||
|
caps.name as servicename
|
||||||
|
from subscription
|
||||||
|
left outer join item
|
||||||
|
on item.server = subscription.server
|
||||||
|
and item.node = subscription.node
|
||||||
|
left outer join caps
|
||||||
|
on caps.node = subscription.server
|
||||||
|
where subscription.jid = :jid
|
||||||
|
group by
|
||||||
|
subscription.server,
|
||||||
|
subscription.node,
|
||||||
|
subscription.jid,
|
||||||
|
subscription,
|
||||||
|
caps.name,
|
||||||
|
item.name,
|
||||||
|
item.description
|
||||||
|
order by
|
||||||
|
subscription.server';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete() {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from subscription
|
||||||
|
where jid = :jid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNode($server, $node) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from subscription
|
||||||
|
where jid = :jid
|
||||||
|
and server = :server
|
||||||
|
and node = :node';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'server' => $server,
|
||||||
|
'node' => $node
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNodeSubid($server, $node, $subid) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from subscription
|
||||||
|
where jid = :jid
|
||||||
|
and server = :server
|
||||||
|
and node = :node
|
||||||
|
and subid = :subid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Subscription',
|
||||||
|
array(
|
||||||
|
'jid' => $this->_user,
|
||||||
|
'server' => $server,
|
||||||
|
'node' => $node,
|
||||||
|
'subid' => $subid,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Subscription');
|
||||||
|
}
|
||||||
|
}
|
20
sources/app/models/tag/Tag.php
Normal file
20
sources/app/models/tag/Tag.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class Tag extends Model {
|
||||||
|
public $tag;
|
||||||
|
public $nodeid;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->_struct = '
|
||||||
|
{
|
||||||
|
"tag" :
|
||||||
|
{"type":"string", "size":64, "mandatory":true, "key":true },
|
||||||
|
"nodeid" :
|
||||||
|
{"type":"string", "size":96, "mandatory":true, "key":true }
|
||||||
|
}';
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
}
|
71
sources/app/models/tag/TagDAO.php
Normal file
71
sources/app/models/tag/TagDAO.php
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace modl;
|
||||||
|
|
||||||
|
class TagDAO extends SQL {
|
||||||
|
function set(Tag $t) {
|
||||||
|
$this->_sql = '
|
||||||
|
update tag
|
||||||
|
set nodeid = :nodeid,
|
||||||
|
tag = :tag
|
||||||
|
where nodeid = :nodeid
|
||||||
|
and tag = :tag';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Tag',
|
||||||
|
array(
|
||||||
|
'nodeid' => $t->nodeid,
|
||||||
|
'tag' => $t->tag
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Tag');
|
||||||
|
|
||||||
|
if(!$this->_effective) {
|
||||||
|
$this->_sql = '
|
||||||
|
insert into tag
|
||||||
|
(nodeid, tag)
|
||||||
|
values (:nodeid, :tag)';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Tag',
|
||||||
|
array(
|
||||||
|
'nodeid' => $t->nodeid,
|
||||||
|
'tag' => $t->tag
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->run('Tag');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($nodeid) {
|
||||||
|
$this->_sql = '
|
||||||
|
delete from tag
|
||||||
|
where nodeid = :nodeid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Tag',
|
||||||
|
array(
|
||||||
|
'nodeid' => $nodeid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Tag');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTags($nodeid) {
|
||||||
|
$this->_sql = '
|
||||||
|
select * from tag
|
||||||
|
where nodeid = :nodeid';
|
||||||
|
|
||||||
|
$this->prepare(
|
||||||
|
'Tag',
|
||||||
|
array(
|
||||||
|
'nodeid' => $nodeid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->run('Tag');
|
||||||
|
}
|
||||||
|
}
|
12
sources/app/views/about.tpl
Normal file
12
sources/app/views/about.tpl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Tabs');?>
|
||||||
|
|
||||||
|
<?php $this->widget('About');?>
|
||||||
|
<?php $this->widget('Help');?>
|
||||||
|
<?php $this->widget('Caps');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
6
sources/app/views/account.tpl
Normal file
6
sources/app/views/account.tpl
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('Subscribe');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
6
sources/app/views/accountnext.tpl
Normal file
6
sources/app/views/accountnext.tpl
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('AccountNext');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
13
sources/app/views/admin.tpl
Normal file
13
sources/app/views/admin.tpl
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Tabs');?>
|
||||||
|
<?php $this->widget('AdminTest');?>
|
||||||
|
<?php $this->widget('AdminMain');?>
|
||||||
|
<?php $this->widget('AdminDB');?>
|
||||||
|
<?php $this->widget('Statistics');?>
|
||||||
|
<?php $this->widget('Api');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
6
sources/app/views/adminlogin.tpl
Normal file
6
sources/app/views/adminlogin.tpl
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header');?>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('AdminLogin');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
7
sources/app/views/blog.tpl
Normal file
7
sources/app/views/blog.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div style="background-color: #EEE;">
|
||||||
|
<?php $this->widget('Blog');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
16
sources/app/views/chat.tpl
Normal file
16
sources/app/views/chat.tpl
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php $this->widget('Stickers');?>
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Chats');?>
|
||||||
|
<?php $this->widget('Rooms');?>
|
||||||
|
</div>
|
||||||
|
<?php $this->widget('Upload');?>
|
||||||
|
<?php $this->widget('Chat');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
20
sources/app/views/conf.tpl
Normal file
20
sources/app/views/conf.tpl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Tabs');?>
|
||||||
|
<?php $this->widget('Vcard4');?>
|
||||||
|
<?php $this->widget('Avatar');?>
|
||||||
|
<?php $this->widget('Config');?>
|
||||||
|
<?php $this->widget('Account');?>
|
||||||
|
<?php $this->widget('AdHoc');?>
|
||||||
|
<?php //$this->widget('ConfigData');?>
|
||||||
|
<?php //$this->widget('PubsubSubscriptionConfig');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
16
sources/app/views/contact.tpl
Normal file
16
sources/app/views/contact.tpl
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div style="background-color: #EEE;">
|
||||||
|
<?php $this->widget('Notifs');?>
|
||||||
|
<?php $this->widget('Roster');?>
|
||||||
|
</div>
|
||||||
|
<div id="contact_widget">
|
||||||
|
<?php $this->widget('Contact');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
0
sources/app/views/disconnect.tpl
Normal file
0
sources/app/views/disconnect.tpl
Normal file
1
sources/app/views/feed.tpl
Normal file
1
sources/app/views/feed.tpl
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?php $this->widget('Syndication');?>
|
15
sources/app/views/group.tpl
Normal file
15
sources/app/views/group.tpl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php $this->widget('Upload'); ?>
|
||||||
|
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('Groups'); ?>
|
||||||
|
<?php $this->widget('Group'); ?>
|
||||||
|
<?php $this->widget('Publish'); ?>
|
||||||
|
</section>
|
||||||
|
</main>
|
15
sources/app/views/help.tpl
Normal file
15
sources/app/views/help.tpl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Tabs');?>
|
||||||
|
<?php $this->widget('Help');?>
|
||||||
|
<?php $this->widget('About');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
1
sources/app/views/infos.tpl
Normal file
1
sources/app/views/infos.tpl
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?php $this->widget('Infos');?>
|
9
sources/app/views/login.tpl
Normal file
9
sources/app/views/login.tpl
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php $this->widget('Presence'); ?>
|
||||||
|
<main>
|
||||||
|
<?php //$this->widget('Header');?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Login'); ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
12
sources/app/views/main.tpl
Normal file
12
sources/app/views/main.tpl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('Hello');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php $this->widget('Init');?>
|
24
sources/app/views/media.tpl
Normal file
24
sources/app/views/media.tpl
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php /* -*- mode: html -*- */
|
||||||
|
?>
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Chat');?>
|
||||||
|
<?php $this->widget('VisioExt');?>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
<div id="left">
|
||||||
|
<?php $this->widget('Profile');?>
|
||||||
|
<?php $this->widget('Notifs');?>
|
||||||
|
<?php $this->widget('Bookmark');?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="center">
|
||||||
|
<div title="<?php echo getFlagTitle("white"); ?>" class="protect white"></div>
|
||||||
|
<?php $this->widget('Tabs');?>
|
||||||
|
<?php $this->widget('Media');?>
|
||||||
|
<?php $this->widget('MediaUpload');?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="right">
|
||||||
|
<?php $this->widget('Roster');?>
|
||||||
|
</div>
|
15
sources/app/views/news.tpl
Normal file
15
sources/app/views/news.tpl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php $this->widget('Init');?>
|
||||||
|
<?php $this->widget('Upload');?>
|
||||||
|
|
||||||
|
<nav class="color dark">
|
||||||
|
<?php $this->widget('Presence');?>
|
||||||
|
<?php $this->widget('Navigation');?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<?php $this->widget('Menu');?>
|
||||||
|
<?php $this->widget('Post');?>
|
||||||
|
<?php $this->widget('Publish');?>
|
||||||
|
</section>
|
||||||
|
</main>
|
7
sources/app/views/node.tpl
Normal file
7
sources/app/views/node.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div style="background-color: #EEE;">
|
||||||
|
<?php $this->widget('Blog');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
7
sources/app/views/notfound.tpl
Normal file
7
sources/app/views/notfound.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('NotFound');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
54
sources/app/views/page.tpl
Normal file
54
sources/app/views/page.tpl
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html ng-app="roster">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title><?php $this->title();?></title>
|
||||||
|
|
||||||
|
<meta name="theme-color" content="#1C1D5B" />
|
||||||
|
|
||||||
|
<?php $this->meta();?>
|
||||||
|
|
||||||
|
<meta name="application-name" content="Movim">
|
||||||
|
<link rel="shortcut icon" href="<?php $this->linkFile('img/favicon.ico');?>" />
|
||||||
|
<link rel="icon" type="image/png" href="<?php $this->linkFile('img/app/48.png');?>" sizes="48x48">
|
||||||
|
<link rel="icon" type="image/png" href="<?php $this->linkFile('img/app/96.png');?>" sizes="96x96">
|
||||||
|
<link rel="icon" type="image/png" href="<?php $this->linkFile('img/app/128.png');?>" sizes="128x128">
|
||||||
|
<script src="<?php echo BASE_URI; ?>app/assets/js/favico.js"></script>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$this->addCss('style.css');
|
||||||
|
$this->addCss('header.css');
|
||||||
|
$this->addCss('listn.css');
|
||||||
|
$this->addCss('grid.css');
|
||||||
|
$this->addCss('article.css');
|
||||||
|
$this->addCss('form.css');
|
||||||
|
$this->addCss('color.css');
|
||||||
|
$this->addCss('block.css');
|
||||||
|
$this->addCss('menu.css');
|
||||||
|
$this->addCss('fonts.css');
|
||||||
|
$this->addCss('material-design-iconic-font.min.css');
|
||||||
|
|
||||||
|
$this->widget('System');
|
||||||
|
|
||||||
|
$this->scripts();
|
||||||
|
?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<style type="text/css">
|
||||||
|
nav {display:none;} #content {display: none;}
|
||||||
|
</style>
|
||||||
|
<div class="warning" style="width: 500px; margin: 0 auto;">
|
||||||
|
<?php echo __('global.no_js'); ?>
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
<div id="hiddendiv"></div>
|
||||||
|
<div id="snackbar" class="snackbar"></div>
|
||||||
|
<?php $this->widget('Dialog');?>
|
||||||
|
<?php $this->widget('Notification');?>
|
||||||
|
<?php $this->content();?>
|
||||||
|
<script type="text/javascript">if(typeof movim_onload == 'function') { movim_onload(); }</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
8
sources/app/views/pods.tpl
Normal file
8
sources/app/views/pods.tpl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header'); ?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Pods');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
11
sources/app/views/room.tpl
Normal file
11
sources/app/views/room.tpl
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php $this->widget('Presence'); ?>
|
||||||
|
<?php $this->widget('LoginAnonymous'); ?>
|
||||||
|
<main>
|
||||||
|
<?php $this->widget('Header');?>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Rooms'); ?>
|
||||||
|
</div>
|
||||||
|
<?php $this->widget('Chat'); ?>
|
||||||
|
</section>
|
||||||
|
</main>
|
7
sources/app/views/share.tpl
Normal file
7
sources/app/views/share.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('Share');?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue