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-?
|
||||
- Update to movim 0.9 git2016-03-14
|
||||
- Php composer stuff is now shipped in the package
|
||||
- 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
|
||||
- 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
|
||||
|
||||
# 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 "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 "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 install -n" movim # install + quiet mode
|
||||
|
||||
# Movim configuration
|
||||
sudo sed -i "s@'username' => 'username'@'username' => '$db_user'@g" $final_path/config/db.inc.php
|
||||
|
|
|
@ -32,10 +32,9 @@ else
|
|||
fi
|
||||
|
||||
# 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 && 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 && 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 install -n" movim
|
||||
|
||||
# Movim configuration
|
||||
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.
|
||||
|
||||
![movim logo](https://movim.eu/img/main_top.png)
|
||||
|
||||
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…
Reference in a new issue