From fd934aeab49b72ec3f13f1dbff156ce624a3dfce Mon Sep 17 00:00:00 2001 From: Fabiano Franz Date: Fri, 5 Apr 2013 18:30:45 -0300 Subject: [PATCH 01/32] Using getenv instead of ENV --- php/config.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/config.php b/php/config.php index d3645d6..4a203d2 100644 --- a/php/config.php +++ b/php/config.php @@ -4,11 +4,11 @@ // ******************************************* define('DB_TYPE', "pgsql"); // or mysql - define('DB_HOST', $_ENV['OPENSHIFT_POSTGRESQL_DB_HOST'] ); - define('DB_USER', $_ENV['OPENSHIFT_POSTGRESQL_DB_USERNAME'] ); - define('DB_NAME', $_ENV['OPENSHIFT_APP_NAME'] ); - define('DB_PASS', $_ENV['OPENSHIFT_POSTGRESQL_DB_PASSWORD'] ); - define('DB_PORT', $_ENV['OPENSHIFT_POSTGRESQL_DB_PORT'] ); // when neeeded, PG-only + define('DB_HOST', getenv('OPENSHIFT_POSTGRESQL_DB_HOST')); + define('DB_USER', getenv('OPENSHIFT_POSTGRESQL_DB_USERNAME')); + define('DB_NAME', getenv('OPENSHIFT_APP_NAME')); + define('DB_PASS', getenv('OPENSHIFT_POSTGRESQL_DB_PASSWORD')); + define('DB_PORT', getenv('OPENSHIFT_POSTGRESQL_DB_PORT')); // when neeeded, PG-only define('MYSQL_CHARSET', 'UTF8'); // Connection charset for MySQL. If you have a legacy database and/or experience @@ -18,7 +18,7 @@ // *** Basic settings (important!) *** // *********************************** - define('SELF_URL_PATH', 'http://'.$_ENV['OPENSHIFT_APP_DNS'] ); + define('SELF_URL_PATH', 'http://'.getenv('OPENSHIFT_APP_DNS')); // Full URL of your tt-rss installation. This should be set to the // location of tt-rss directory, e.g. http://yourserver/tt-rss/ // You need to set this option correctly otherwise several features From 9275037004bf0c6827d2223bf79ac2fafd4feb17 Mon Sep 17 00:00:00 2001 From: Fabiano Franz Date: Fri, 5 Apr 2013 19:24:51 -0300 Subject: [PATCH 02/32] Fixed the deploy script to wait for database availability --- .openshift/action_hooks/deploy | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/.openshift/action_hooks/deploy b/.openshift/action_hooks/deploy index ed5eb99..1f90235 100755 --- a/.openshift/action_hooks/deploy +++ b/.openshift/action_hooks/deploy @@ -2,4 +2,41 @@ # This deploy hook gets executed after dependencies are resolved and the # build hook has been run but before the application has been started back # up again. This script gets executed directly, so it could be python, php, -# ruby, etc. \ No newline at end of file +# ruby, etc. + +set -e + +if [ -z "$OPENSHIFT_POSTGRESQL_DB_HOST" ] +then + echo 1>&2 + echo "Could not find postgresql database. Please run:" 1>&2 + echo "rhc cartridge add -a $OPENSHIFT_APP_NAME -c postgresql-8" 1>&2 + echo "then make a sample commit (add whitespace somewhere) and re-push" 1>&2 + echo 1>&2 +fi + +RETRY=60 +while [ $RETRY -gt 0 ] ; do + #reload env variables + for env_var in $OPENSHIFT_HOMEDIR/.env/* + do + . $env_var + done + + #check for db + if [ -n "$OPENSHIFT_POSTGRESQL_DB_HOST" ] + then + echo "Database server found at $OPENSHIFT_POSTGRESQL_DB_HOST. initializing..." + sleep 5 + break + fi + + sleep 1 + RETRY=$(( $RETRY - 1 )) +done + +if [ -z "$OPENSHIFT_POSTGRESQL_DB_HOST" ] +then + exit 5 +fi + From 347cf630a6bf72c70c9cc975226cb6c669fda9ae Mon Sep 17 00:00:00 2001 From: Fabiano Franz Date: Fri, 5 Apr 2013 19:35:09 -0300 Subject: [PATCH 03/32] Updated the git url in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d484c19..545e52e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Create an account at http://openshift.redhat.com/ Create a PHP 5 application + a PostgreSQL 8 cartridge to the app, and import all the quickstart codes: - rhc app create php-5 postgresql-8 --from-code=git://github.com/lulinqing/tiny_tiny_rss-openshift-quickstart.git + rhc app create php-5 postgresql-8 --from-code=https://github.com/openshift-quickstart/tiny_tiny_rss-openshift-quickstart.git You can now checkout your RSS application at: From 25272723337ec39e726e893c8a92191dbc03e601 Mon Sep 17 00:00:00 2001 From: Fotios Lindiakos Date: Thu, 6 Jun 2013 11:47:48 -0400 Subject: [PATCH 04/32] Rename action_hooks --- .openshift/action_hooks/{post_start_php-5.3 => post_start_php} | 0 .openshift/action_hooks/{post_stop_php-5.3 => post_stop_php} | 0 .openshift/action_hooks/{pre_start_php-5.3 => pre_start_php} | 0 .openshift/action_hooks/{pre_stop_php-5.3 => pre_stop_php} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename .openshift/action_hooks/{post_start_php-5.3 => post_start_php} (100%) rename .openshift/action_hooks/{post_stop_php-5.3 => post_stop_php} (100%) rename .openshift/action_hooks/{pre_start_php-5.3 => pre_start_php} (100%) rename .openshift/action_hooks/{pre_stop_php-5.3 => pre_stop_php} (100%) diff --git a/.openshift/action_hooks/post_start_php-5.3 b/.openshift/action_hooks/post_start_php similarity index 100% rename from .openshift/action_hooks/post_start_php-5.3 rename to .openshift/action_hooks/post_start_php diff --git a/.openshift/action_hooks/post_stop_php-5.3 b/.openshift/action_hooks/post_stop_php similarity index 100% rename from .openshift/action_hooks/post_stop_php-5.3 rename to .openshift/action_hooks/post_stop_php diff --git a/.openshift/action_hooks/pre_start_php-5.3 b/.openshift/action_hooks/pre_start_php similarity index 100% rename from .openshift/action_hooks/pre_start_php-5.3 rename to .openshift/action_hooks/pre_start_php diff --git a/.openshift/action_hooks/pre_stop_php-5.3 b/.openshift/action_hooks/pre_stop_php similarity index 100% rename from .openshift/action_hooks/pre_stop_php-5.3 rename to .openshift/action_hooks/pre_stop_php From e1f46dbefbd44e0e649e124af9f99d1d90d36f62 Mon Sep 17 00:00:00 2001 From: Fotios Lindiakos Date: Thu, 6 Jun 2013 13:34:08 -0400 Subject: [PATCH 05/32] Remove waiting for database logic and sourcing environment variables --- .openshift/action_hooks/deploy | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/.openshift/action_hooks/deploy b/.openshift/action_hooks/deploy index 1f90235..0213601 100755 --- a/.openshift/action_hooks/deploy +++ b/.openshift/action_hooks/deploy @@ -13,30 +13,5 @@ then echo "rhc cartridge add -a $OPENSHIFT_APP_NAME -c postgresql-8" 1>&2 echo "then make a sample commit (add whitespace somewhere) and re-push" 1>&2 echo 1>&2 -fi - -RETRY=60 -while [ $RETRY -gt 0 ] ; do - #reload env variables - for env_var in $OPENSHIFT_HOMEDIR/.env/* - do - . $env_var - done - - #check for db - if [ -n "$OPENSHIFT_POSTGRESQL_DB_HOST" ] - then - echo "Database server found at $OPENSHIFT_POSTGRESQL_DB_HOST. initializing..." - sleep 5 - break - fi - - sleep 1 - RETRY=$(( $RETRY - 1 )) -done - -if [ -z "$OPENSHIFT_POSTGRESQL_DB_HOST" ] -then exit 5 fi - From 95d662d22121c96bc45997b249ee6fe901e20986 Mon Sep 17 00:00:00 2001 From: Thanos Lefteris Date: Tue, 11 Jun 2013 14:06:12 +0300 Subject: [PATCH 06/32] Update Tiny Tiny RSS to version 1.7.9 --- php/.htaccess | 3 + php/.settings/.jsdtscope | 16 - php/.settings/org.eclipse.php.core.prefs | 3 - ...rg.eclipse.wst.jsdt.ui.superType.container | 1 - .../org.eclipse.wst.jsdt.ui.superType.name | 1 - php/api/index.php | 17 +- php/atom-to-html.xsl | 1 - php/backend.php | 25 +- php/cache/.htaccess | 0 php/cache/images/.empty | 0 php/cache/{magpie => js}/.empty | 0 php/cache/simplepie/.empty | 0 .../init.js => cache/upload/.empty} | 0 php/cdm.css | 131 +- php/classes/.htaccess | 2 + php/classes/api.php | 419 +- php/classes/article.php | 246 +- php/classes/auth/base.php | 22 +- php/classes/backend.php | 59 +- php/classes/db.php | 98 + php/classes/db/mysql.php | 73 + php/classes/db/mysqli.php | 77 + php/classes/db/pdo.php | 100 + php/classes/db/pgsql.php | 82 + php/classes/db/prefs.php | 190 + php/classes/db/stmt.php | 32 + php/classes/dbupdater.php | 65 + php/classes/dlg.php | 518 +- php/classes/feedenclosure.php | 7 + php/classes/feeditem.php | 15 + php/classes/feeditem/atom.php | 109 + php/classes/feeditem/common.php | 51 + php/classes/feeditem/rss.php | 107 + php/classes/feedparser.php | 180 + php/classes/feeds.php | 686 +- php/classes/handler.php | 6 +- php/classes/handler/public.php | 455 +- php/classes/idb.php | 13 + php/classes/logger.php | 65 + php/classes/logger/sql.php | 28 + php/classes/logger/syslog.php | 31 + php/classes/opml.php | 167 +- php/classes/plugin.php | 10 +- php/classes/pluginhandler.php | 14 +- php/classes/pluginhost.php | 142 +- php/classes/pref/feeds.php | 670 +- php/classes/pref/filters.php | 330 +- php/classes/pref/labels.php | 79 +- php/classes/pref/prefs.php | 519 +- php/classes/pref/system.php | 90 + php/classes/pref/users.php | 173 +- php/classes/rpc.php | 603 +- php/classes/sanitizedummy.php | 7 - php/classes/ttrssmailer.php | 62 + php/config.php | 42 +- php/config.php-dist | 42 +- php/db-updater.php | 186 - php/errors.php | 5 +- php/feed-icons/.empty | 0 php/feed-icons/index.html | 0 php/image.php | 49 +- php/images/close_notify.svg | 76 + php/images/collapse.png | Bin 0 -> 186 bytes php/images/favicon-72px.png | Bin 0 -> 5474 bytes php/images/favicon.png | Bin 386 -> 772 bytes php/images/logo_small.png | Bin 0 -> 4134 bytes php/images/overlay.png | Bin 111 -> 0 bytes php/images/piggie.png | Bin 14123 -> 0 bytes php/images/piggie_icon.png | Bin 540 -> 0 bytes php/include/autoload.php | 14 + php/include/ccache.php | 78 +- php/include/colors.php | 82 +- php/include/crypt.php | 36 + php/include/db-prefs.php | 187 +- php/include/db.php | 124 +- php/include/digest.php | 64 +- php/include/errorhandler.php | 39 + php/include/feedbrowser.php | 10 +- php/include/functions.php | 1756 +- php/include/labels.php | 89 +- php/include/localized_schema.php | 65 - php/include/login_form.php | 44 +- php/include/rssfuncs.php | 744 +- php/include/sanity_check.php | 96 +- php/include/sanity_config.php | 4 +- php/include/sessions.php | 149 +- php/include/version.php | 18 +- php/index.php | 175 +- php/install/index.php | 498 + php/js/FeedTree.js | 130 +- php/js/PluginHost.js | 34 + php/js/PrefFilterTree.js | 28 + php/js/feedlist.js | 89 +- php/js/functions.js | 338 +- php/js/index.html | 0 php/js/prefs.js | 122 +- php/js/tt-rss.js | 580 +- php/js/viewfeed.js | 595 +- php/lib/MiniTemplator.class.php | 4 +- php/lib/dijit/BackgroundIframe.js | 2 +- php/lib/dijit/Calendar.js | 2 +- php/lib/dijit/CalendarLite.js | 2 +- php/lib/dijit/CheckedMenuItem.js | 2 +- php/lib/dijit/ColorPalette.js | 2 +- php/lib/dijit/Declaration.js | 2 +- php/lib/dijit/Destroyable.js | 2 + php/lib/dijit/Dialog.js | 2 +- php/lib/dijit/DialogUnderlay.js | 2 +- php/lib/dijit/DropDownMenu.js | 2 +- php/lib/dijit/Editor.js | 2 +- php/lib/dijit/InlineEditBox.js | 2 +- php/lib/dijit/LICENSE | 2 +- php/lib/dijit/Menu.js | 2 +- php/lib/dijit/MenuBar.js | 2 +- php/lib/dijit/MenuBarItem.js | 2 +- php/lib/dijit/MenuItem.js | 2 +- php/lib/dijit/PopupMenuItem.js | 2 +- php/lib/dijit/ProgressBar.js | 2 +- php/lib/dijit/TitlePane.js | 2 +- php/lib/dijit/Toolbar.js | 2 +- php/lib/dijit/Tooltip.js | 2 +- php/lib/dijit/TooltipDialog.js | 2 +- php/lib/dijit/Tree.js | 2 +- php/lib/dijit/Viewport.js | 2 + php/lib/dijit/WidgetSet.js | 2 +- php/lib/dijit/_BidiSupport.js | 2 +- php/lib/dijit/_Calendar.js | 2 +- php/lib/dijit/_Container.js | 2 +- php/lib/dijit/_CssStateMixin.js | 2 +- php/lib/dijit/_HasDropDown.js | 2 +- php/lib/dijit/_MenuBase.js | 2 +- php/lib/dijit/_OnDijitClickMixin.js | 2 +- php/lib/dijit/_PaletteMixin.js | 2 +- php/lib/dijit/_TemplatedMixin.js | 2 +- php/lib/dijit/_TimePicker.js | 2 +- php/lib/dijit/_Widget.js | 2 +- php/lib/dijit/_WidgetBase.js | 2 +- php/lib/dijit/_WidgetsInTemplateMixin.js | 2 +- php/lib/dijit/_base.js | 2 +- php/lib/dijit/_base/focus.js | 2 +- php/lib/dijit/_base/manager.js | 2 +- php/lib/dijit/_base/place.js | 2 +- php/lib/dijit/_base/popup.js | 2 +- php/lib/dijit/_base/scroll.js | 2 +- php/lib/dijit/_base/wai.js | 2 +- php/lib/dijit/_base/window.js | 2 +- php/lib/dijit/_editor/RichText.js | 2 +- php/lib/dijit/_editor/_Plugin.js | 2 +- php/lib/dijit/_editor/html.js | 2 +- php/lib/dijit/_editor/nls/ca/commands.js | 2 +- php/lib/dijit/_editor/nls/cs/commands.js | 2 +- php/lib/dijit/_editor/nls/da/commands.js | 2 +- php/lib/dijit/_editor/nls/de/commands.js | 2 +- php/lib/dijit/_editor/nls/el/commands.js | 2 +- php/lib/dijit/_editor/nls/es/commands.js | 2 +- php/lib/dijit/_editor/nls/fi/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/fi/commands.js | 2 +- php/lib/dijit/_editor/nls/fr/commands.js | 2 +- php/lib/dijit/_editor/nls/hu/commands.js | 2 +- php/lib/dijit/_editor/nls/it/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/it/commands.js | 2 +- php/lib/dijit/_editor/nls/ja/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/ja/commands.js | 2 +- php/lib/dijit/_editor/nls/kk/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/kk/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/kk/commands.js | 2 +- php/lib/dijit/_editor/nls/ko/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/ko/commands.js | 2 +- php/lib/dijit/_editor/nls/nl/commands.js | 2 +- php/lib/dijit/_editor/nls/pl/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/pl/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/pl/commands.js | 2 +- php/lib/dijit/_editor/nls/pt/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/pt/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/pt/commands.js | 2 +- php/lib/dijit/_editor/nls/ro/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/ro/commands.js | 2 +- php/lib/dijit/_editor/nls/ru/commands.js | 2 +- php/lib/dijit/_editor/nls/sk/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/sk/commands.js | 2 +- php/lib/dijit/_editor/nls/sl/commands.js | 2 +- php/lib/dijit/_editor/nls/sv/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/sv/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/sv/commands.js | 2 +- php/lib/dijit/_editor/nls/th/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/th/commands.js | 2 +- php/lib/dijit/_editor/nls/tr/commands.js | 2 +- php/lib/dijit/_editor/nls/zh-tw/commands.js | 2 +- php/lib/dijit/_editor/nls/zh/FontChoice.js | 2 +- php/lib/dijit/_editor/nls/zh/LinkDialog.js | 2 +- php/lib/dijit/_editor/nls/zh/commands.js | 2 +- .../_editor/plugins/AlwaysShowToolbar.js | 2 +- .../dijit/_editor/plugins/EnterKeyHandling.js | 2 +- php/lib/dijit/_editor/plugins/FontChoice.js | 2 +- php/lib/dijit/_editor/plugins/FullScreen.js | 2 +- php/lib/dijit/_editor/plugins/LinkDialog.js | 2 +- php/lib/dijit/_editor/plugins/NewPage.js | 2 +- php/lib/dijit/_editor/plugins/Print.js | 2 +- php/lib/dijit/_editor/plugins/TextColor.js | 2 +- php/lib/dijit/_editor/plugins/ToggleDir.js | 2 +- php/lib/dijit/_editor/plugins/ViewSource.js | 2 +- php/lib/dijit/_editor/range.js | 2 +- php/lib/dijit/_editor/selection.js | 2 +- php/lib/dijit/a11y.js | 2 +- php/lib/dijit/a11yclick.js | 2 + php/lib/dijit/dijit-all.js | 2 +- php/lib/dijit/dijit.js | 2 +- php/lib/dijit/dijit.profile.js | 6 +- php/lib/dijit/focus.js | 2 +- php/lib/dijit/form/Button.js | 2 +- php/lib/dijit/form/CheckBox.js | 2 +- php/lib/dijit/form/ComboBoxMixin.js | 2 +- php/lib/dijit/form/ComboButton.js | 2 +- php/lib/dijit/form/CurrencyTextBox.js | 2 +- php/lib/dijit/form/DropDownButton.js | 2 +- php/lib/dijit/form/FilteringSelect.js | 2 +- php/lib/dijit/form/Form.js | 2 +- php/lib/dijit/form/HorizontalRuleLabels.js | 2 +- php/lib/dijit/form/HorizontalSlider.js | 2 +- php/lib/dijit/form/MappedTextBox.js | 2 +- php/lib/dijit/form/MultiSelect.js | 2 +- php/lib/dijit/form/NumberSpinner.js | 2 +- php/lib/dijit/form/NumberTextBox.js | 2 +- php/lib/dijit/form/RangeBoundTextBox.js | 2 +- php/lib/dijit/form/Select.js | 2 +- php/lib/dijit/form/SimpleTextarea.js | 2 +- php/lib/dijit/form/TextBox.js | 2 +- php/lib/dijit/form/TimeTextBox.js | 2 +- php/lib/dijit/form/ValidationTextBox.js | 2 +- php/lib/dijit/form/VerticalSlider.js | 2 +- php/lib/dijit/form/_AutoCompleterMixin.js | 2 +- php/lib/dijit/form/_CheckBoxMixin.js | 2 +- php/lib/dijit/form/_ComboBoxMenu.js | 2 +- php/lib/dijit/form/_ComboBoxMenuMixin.js | 2 +- php/lib/dijit/form/_DateTimeTextBox.js | 2 +- php/lib/dijit/form/_ExpandingTextAreaMixin.js | 2 +- php/lib/dijit/form/_FormMixin.js | 2 +- php/lib/dijit/form/_FormSelectWidget.js | 2 +- php/lib/dijit/form/_FormValueMixin.js | 2 +- php/lib/dijit/form/_FormValueWidget.js | 2 +- php/lib/dijit/form/_FormWidget.js | 2 +- php/lib/dijit/form/_FormWidgetMixin.js | 2 +- php/lib/dijit/form/_ListBase.js | 2 +- php/lib/dijit/form/_ListMouseMixin.js | 2 +- php/lib/dijit/form/_RadioButtonMixin.js | 2 +- php/lib/dijit/form/_SearchMixin.js | 2 + php/lib/dijit/form/_Spinner.js | 2 +- php/lib/dijit/form/_TextBoxMixin.js | 2 +- php/lib/dijit/form/_ToggleButtonMixin.js | 2 +- php/lib/dijit/form/nls/da/validate.js | 2 +- php/lib/dijit/form/nls/it/ComboBox.js | 2 +- php/lib/dijit/form/nls/it/validate.js | 2 +- php/lib/dijit/form/nls/pl/validate.js | 2 +- php/lib/dijit/form/nls/sk/ComboBox.js | 2 +- php/lib/dijit/form/nls/sk/Textarea.js | 2 +- php/lib/dijit/form/nls/sk/validate.js | 2 +- php/lib/dijit/form/nls/sv/ComboBox.js | 2 +- php/lib/dijit/form/nls/sv/validate.js | 2 +- php/lib/dijit/form/nls/th/Textarea.js | 2 +- php/lib/dijit/form/nls/zh/Textarea.js | 2 +- php/lib/dijit/form/nls/zh/validate.js | 2 +- php/lib/dijit/form/templates/CheckBox.html | 2 +- php/lib/dijit/form/templates/ComboButton.html | 2 +- php/lib/dijit/form/templates/DropDownBox.html | 2 +- .../dijit/form/templates/DropDownButton.html | 2 +- .../form/templates/HorizontalSlider.html | 3 +- php/lib/dijit/form/templates/Select.html | 20 +- php/lib/dijit/form/templates/Spinner.html | 6 +- .../dijit/form/templates/VerticalSlider.html | 7 +- php/lib/dijit/hccss.js | 2 +- php/lib/dijit/icons/commonIcons.css | 172 +- php/lib/dijit/icons/commonIcons_rtl.css | 122 +- php/lib/dijit/icons/editorIcons.css | 79 +- php/lib/dijit/icons/editorIcons_rtl.css | 24 +- php/lib/dijit/layout/AccordionContainer.js | 2 +- php/lib/dijit/layout/BorderContainer.js | 2 +- php/lib/dijit/layout/ContentPane.js | 2 +- php/lib/dijit/layout/LayoutContainer.js | 2 +- .../dijit/layout/ScrollingTabController.js | 2 +- php/lib/dijit/layout/SplitContainer.js | 2 +- php/lib/dijit/layout/StackContainer.js | 2 +- php/lib/dijit/layout/StackController.js | 2 +- php/lib/dijit/layout/TabContainer.js | 2 +- php/lib/dijit/layout/TabController.js | 2 +- .../dijit/layout/_ContentPaneResizeMixin.js | 2 +- php/lib/dijit/layout/_LayoutWidget.js | 2 +- .../_ScrollingTabControllerButton.html | 10 +- .../dijit/layout/templates/_TabButton.html | 20 +- php/lib/dijit/layout/utils.js | 2 +- php/lib/dijit/nls/fr/common.js | 2 +- php/lib/dijit/nls/hr/loading.js | 2 +- php/lib/dijit/nls/it/common.js | 2 +- php/lib/dijit/nls/kk/loading.js | 2 +- php/lib/dijit/nls/ru/common.js | 2 +- php/lib/dijit/nls/sk/loading.js | 2 +- php/lib/dijit/nls/sv/loading.js | 2 +- php/lib/dijit/package.json | 7 +- php/lib/dijit/place.js | 2 +- php/lib/dijit/popup.js | 2 +- php/lib/dijit/registry.js | 2 +- php/lib/dijit/resources/_modules.js | 18 - php/lib/dijit/templates/Calendar.html | 2 +- php/lib/dijit/templates/CheckedMenuItem.html | 3 +- php/lib/dijit/templates/Dialog.html | 11 +- php/lib/dijit/templates/InlineEditBox.html | 6 +- php/lib/dijit/templates/Menu.html | 3 +- php/lib/dijit/templates/MenuBarItem.html | 4 +- php/lib/dijit/templates/MenuItem.html | 3 +- php/lib/dijit/templates/TitlePane.html | 6 +- php/lib/dijit/templates/TooltipDialog.html | 2 +- php/lib/dijit/templates/Tree.html | 3 +- php/lib/dijit/templates/TreeNode.html | 5 +- php/lib/dijit/themes/claro/Calendar.css | 285 +- php/lib/dijit/themes/claro/Calendar.less | 34 +- php/lib/dijit/themes/claro/Calendar_rtl.css | 19 +- php/lib/dijit/themes/claro/ColorPalette.css | 42 +- php/lib/dijit/themes/claro/Common.css | 66 +- php/lib/dijit/themes/claro/Common.less | 34 +- php/lib/dijit/themes/claro/Dialog.css | 206 +- php/lib/dijit/themes/claro/Dialog.less | 18 +- php/lib/dijit/themes/claro/Dialog_rtl.css | 10 +- php/lib/dijit/themes/claro/Editor.css | 51 +- php/lib/dijit/themes/claro/Editor.less | 10 +- php/lib/dijit/themes/claro/Editor_rtl.css | 5 +- php/lib/dijit/themes/claro/InlineEditBox.css | 21 +- php/lib/dijit/themes/claro/Menu.css | 191 +- php/lib/dijit/themes/claro/Menu.less | 87 +- php/lib/dijit/themes/claro/Menu_rtl.css | 9 +- php/lib/dijit/themes/claro/ProgressBar.css | 64 +- php/lib/dijit/themes/claro/ProgressBar.less | 10 +- php/lib/dijit/themes/claro/README | 34 +- php/lib/dijit/themes/claro/TimePicker.css | 131 +- php/lib/dijit/themes/claro/TimePicker.less | 17 +- php/lib/dijit/themes/claro/TimePicker_rtl.css | 10 +- php/lib/dijit/themes/claro/TitlePane.css | 72 +- php/lib/dijit/themes/claro/TitlePane.less | 8 +- php/lib/dijit/themes/claro/TitlePane_rtl.css | 5 +- php/lib/dijit/themes/claro/Toolbar.css | 190 +- php/lib/dijit/themes/claro/Toolbar.less | 30 +- php/lib/dijit/themes/claro/Toolbar_rtl.css | 31 +- php/lib/dijit/themes/claro/Tree.css | 135 +- php/lib/dijit/themes/claro/Tree.less | 39 +- php/lib/dijit/themes/claro/claro.css | 29 +- php/lib/dijit/themes/claro/claro_rtl.css | 17 +- php/lib/dijit/themes/claro/document.css | 42 +- php/lib/dijit/themes/claro/form/Button.css | 163 +- php/lib/dijit/themes/claro/form/Button.less | 38 +- .../dijit/themes/claro/form/Button_rtl.css | 14 +- php/lib/dijit/themes/claro/form/Checkbox.css | 72 +- php/lib/dijit/themes/claro/form/Common.css | 179 +- php/lib/dijit/themes/claro/form/Common.less | 71 +- .../dijit/themes/claro/form/Common_rtl.css | 11 +- .../dijit/themes/claro/form/Common_rtl.less | 9 +- .../dijit/themes/claro/form/NumberSpinner.css | 139 +- .../themes/claro/form/NumberSpinner.less | 10 +- .../dijit/themes/claro/form/RadioButton.css | 80 +- php/lib/dijit/themes/claro/form/Select.css | 110 +- php/lib/dijit/themes/claro/form/Select.less | 64 +- .../dijit/themes/claro/form/Select_rtl.css | 4 - .../dijit/themes/claro/form/Select_rtl.less | 6 - php/lib/dijit/themes/claro/form/Slider.css | 330 +- php/lib/dijit/themes/claro/form/Slider.less | 43 +- .../dijit/themes/claro/form/Slider_rtl.css | 25 +- .../dijit/themes/claro/form/images/button.png | Bin 680 -> 0 bytes .../claro/form/images/buttonDisabled.png | Bin 0 -> 105 bytes .../claro/form/images/buttonDisabled.svg | 23 + .../claro/form/images/buttonEnabled.png | Bin 0 -> 122 bytes .../claro/form/images/buttonEnabled.svg | 24 + .../claro/form/images/button_grad_d.png | Bin 3897 -> 0 bytes .../claro/form/images/formHighlight.png | Bin 339 -> 0 bytes .../dijit/themes/claro/form/images/shadow.png | Bin 4624 -> 0 bytes .../claro/form/images/sliderHorizontal.png | Bin 180 -> 0 bytes .../claro/form/images/sliderVertical.png | Bin 177 -> 0 bytes .../themes/claro/form/images/textBox_back.png | Bin 2837 -> 0 bytes .../themes/claro/images/activeGradient.png | Bin 0 -> 146 bytes .../themes/claro/images/activeGradient.svg | 19 + .../dijit/themes/claro/images/calendar.png | Bin 0 -> 194 bytes .../claro/images/calendarContainerImages.png | Bin 3347 -> 0 bytes .../themes/claro/images/commonHighlight.png | Bin 339 -> 0 bytes php/lib/dijit/themes/claro/images/dnd.png | Bin 2996 -> 2127 bytes .../themes/claro/images/menuHighlight.png | Bin 339 -> 0 bytes .../themes/claro/images/progressBarEmpty.png | Bin 2849 -> 0 bytes .../themes/claro/images/standardGradient.png | Bin 0 -> 153 bytes .../themes/claro/images/standardGradient.svg | 18 + .../dijit/themes/claro/images/titlebar.png | Bin 640 -> 0 bytes .../themes/claro/images/tooltipGradient.png | Bin 1030 -> 0 bytes .../claro/images/treeExpand_loading.gif | Bin 1944 -> 0 bytes .../claro/layout/AccordionContainer.css | 122 +- .../claro/layout/AccordionContainer.less | 16 +- .../themes/claro/layout/BorderContainer.css | 110 +- .../themes/claro/layout/BorderContainer.less | 20 +- .../dijit/themes/claro/layout/ContentPane.css | 39 +- .../themes/claro/layout/TabContainer.css | 435 +- .../themes/claro/layout/TabContainer.less | 268 +- .../themes/claro/layout/TabContainer_rtl.css | 68 +- .../themes/claro/layout/TabContainer_rtl.less | 74 - .../themes/claro/layout/images/accordion.png | Bin 640 -> 0 bytes .../layout/images/splitterHorizontalHover.png | Bin 3711 -> 0 bytes .../layout/images/splitterVerticalHover.png | Bin 3869 -> 0 bytes .../themes/claro/layout/images/tabBottom.png | Bin 718 -> 0 bytes .../claro/layout/images/tabBottomSelected.png | Bin 0 -> 118 bytes .../claro/layout/images/tabBottomSelected.svg | 18 + .../layout/images/tabBottomUnselected.png | Bin 0 -> 110 bytes .../layout/images/tabBottomUnselected.svg | 19 + .../themes/claro/layout/images/tabLeft.png | Bin 1692 -> 0 bytes .../claro/layout/images/tabLeftSelected.png | Bin 0 -> 213 bytes .../claro/layout/images/tabLeftSelected.svg | 17 + .../claro/layout/images/tabLeftUnselected.png | Bin 0 -> 106 bytes .../claro/layout/images/tabLeftUnselected.svg | 16 + .../themes/claro/layout/images/tabRight.png | Bin 1759 -> 0 bytes .../claro/layout/images/tabRightSelected.png | Bin 0 -> 210 bytes .../claro/layout/images/tabRightSelected.svg | 17 + .../layout/images/tabRightUnselected.png | Bin 0 -> 105 bytes .../layout/images/tabRightUnselected.svg | 16 + .../themes/claro/layout/images/tabTop.png | Bin 721 -> 0 bytes .../claro/layout/images/tabTopSelected.png | Bin 0 -> 120 bytes .../claro/layout/images/tabTopSelected.svg | 18 + .../claro/layout/images/tabTopUnselected.png | Bin 0 -> 121 bytes .../claro/layout/images/tabTopUnselected.svg | 19 + php/lib/dijit/themes/claro/variables.less | 186 +- php/lib/dijit/themes/dijit.css | 2052 +- php/lib/dijit/themes/dijit_rtl.css | 129 +- php/lib/dijit/themes/nihilo/Calendar.css | 162 +- php/lib/dijit/themes/nihilo/Calendar_rtl.css | 10 +- php/lib/dijit/themes/nihilo/ColorPalette.css | 6 +- php/lib/dijit/themes/nihilo/Common.css | 24 +- php/lib/dijit/themes/nihilo/Dialog.css | 153 +- php/lib/dijit/themes/nihilo/Dialog_rtl.css | 7 +- php/lib/dijit/themes/nihilo/Editor.css | 17 +- php/lib/dijit/themes/nihilo/Editor_rtl.css | 10 +- php/lib/dijit/themes/nihilo/Menu.css | 79 +- php/lib/dijit/themes/nihilo/Menu_rtl.css | 11 +- php/lib/dijit/themes/nihilo/ProgressBar.css | 34 +- php/lib/dijit/themes/nihilo/TimePicker.css | 52 +- .../dijit/themes/nihilo/TimePicker_rtl.css | 5 +- php/lib/dijit/themes/nihilo/TitlePane.css | 55 +- php/lib/dijit/themes/nihilo/TitlePane_rtl.css | 7 +- php/lib/dijit/themes/nihilo/Toolbar.css | 66 +- php/lib/dijit/themes/nihilo/Tree.css | 101 +- php/lib/dijit/themes/nihilo/Tree_rtl.css | 23 +- php/lib/dijit/themes/nihilo/form/Button.css | 130 +- .../dijit/themes/nihilo/form/Button_rtl.css | 9 +- php/lib/dijit/themes/nihilo/form/Checkbox.css | 68 +- php/lib/dijit/themes/nihilo/form/Common.css | 75 +- .../dijit/themes/nihilo/form/RadioButton.css | 67 +- php/lib/dijit/themes/nihilo/form/Select.css | 55 +- php/lib/dijit/themes/nihilo/form/Slider.css | 142 +- .../dijit/themes/nihilo/form/Slider_rtl.css | 37 +- .../dijit/themes/nihilo/images/dndNoCopy.png | Bin 699 -> 1332 bytes .../dijit/themes/nihilo/images/dndNoMove.png | Bin 677 -> 991 bytes .../nihilo/images/tabBottomActiveSpriteLR.gif | Bin 291 -> 0 bytes .../images/tabBottomEnabledSpriteLR.gif | Bin 266 -> 0 bytes .../nihilo/images/tabBottomHoverSpriteLR.gif | Bin 388 -> 0 bytes .../themes/nihilo/images/tabLeftChecked.gif | Bin 303 -> 0 bytes .../themes/nihilo/images/tabRightChecked.gif | Bin 300 -> 0 bytes .../dijit/themes/nihilo/images/tabStripe.gif | Bin 54 -> 0 bytes .../themes/nihilo/images/tabStripeBottom.gif | Bin 432 -> 0 bytes .../themes/nihilo/images/tabStripeLeft.gif | Bin 432 -> 0 bytes .../themes/nihilo/images/tabStripeRight.gif | Bin 432 -> 0 bytes .../nihilo/layout/AccordionContainer.css | 47 +- .../nihilo/layout/AccordionContainer_rtl.css | 9 +- .../themes/nihilo/layout/BorderContainer.css | 77 +- .../themes/nihilo/layout/ContentPane.css | 22 +- .../themes/nihilo/layout/SplitContainer.css | 35 +- .../themes/nihilo/layout/TabContainer.css | 497 +- .../themes/nihilo/layout/TabContainer_rtl.css | 44 +- php/lib/dijit/themes/nihilo/nihilo.css | 43 +- php/lib/dijit/themes/nihilo/nihilo_rtl.css | 30 +- php/lib/dijit/themes/soria/Calendar.css | 162 +- php/lib/dijit/themes/soria/Calendar_rtl.css | 10 +- php/lib/dijit/themes/soria/ColorPalette.css | 6 +- php/lib/dijit/themes/soria/Common.css | 24 +- php/lib/dijit/themes/soria/Dialog.css | 156 +- php/lib/dijit/themes/soria/Dialog_rtl.css | 6 +- php/lib/dijit/themes/soria/Editor.css | 18 +- php/lib/dijit/themes/soria/Editor_rtl.css | 8 +- php/lib/dijit/themes/soria/Menu.css | 79 +- php/lib/dijit/themes/soria/Menu_rtl.css | 11 +- php/lib/dijit/themes/soria/ProgressBar.css | 34 +- php/lib/dijit/themes/soria/TimePicker.css | 52 +- php/lib/dijit/themes/soria/TimePicker_rtl.css | 5 +- php/lib/dijit/themes/soria/TitlePane.css | 59 +- php/lib/dijit/themes/soria/TitlePane_rtl.css | 7 +- php/lib/dijit/themes/soria/Toolbar.css | 66 +- php/lib/dijit/themes/soria/Tree.css | 106 +- php/lib/dijit/themes/soria/Tree_rtl.css | 23 +- php/lib/dijit/themes/soria/form/Button.css | 123 +- .../dijit/themes/soria/form/Button_rtl.css | 8 +- php/lib/dijit/themes/soria/form/Checkbox.css | 68 +- php/lib/dijit/themes/soria/form/Common.css | 75 +- .../dijit/themes/soria/form/RadioButton.css | 67 +- php/lib/dijit/themes/soria/form/Select.css | 55 +- php/lib/dijit/themes/soria/form/Slider.css | 145 +- .../dijit/themes/soria/form/Slider_rtl.css | 37 +- .../dijit/themes/soria/images/dndNoCopy.png | Bin 699 -> 1332 bytes .../dijit/themes/soria/images/dndNoMove.png | Bin 677 -> 991 bytes .../soria/images/tabBottomActiveSpriteLR.gif | Bin 741 -> 0 bytes .../soria/images/tabBottomHoverSpriteLR.gif | Bin 569 -> 0 bytes .../themes/soria/images/tabLeftChecked.gif | Bin 795 -> 2005 bytes .../themes/soria/images/tabRightChecked.gif | Bin 793 -> 2003 bytes .../dijit/themes/soria/images/tabStripe.gif | Bin 54 -> 0 bytes .../themes/soria/images/tabStripeBottom.gif | Bin 54 -> 0 bytes .../themes/soria/images/tabStripeLeft.gif | Bin 54 -> 0 bytes .../themes/soria/images/tabStripeRight.gif | Bin 54 -> 0 bytes .../soria/layout/AccordionContainer.css | 47 +- .../soria/layout/AccordionContainer_rtl.css | 9 +- .../themes/soria/layout/BorderContainer.css | 78 +- .../dijit/themes/soria/layout/ContentPane.css | 22 +- .../themes/soria/layout/SplitContainer.css | 35 +- .../themes/soria/layout/TabContainer.css | 493 +- .../themes/soria/layout/TabContainer_rtl.css | 44 +- php/lib/dijit/themes/soria/soria.css | 42 +- php/lib/dijit/themes/soria/soria_rtl.css | 30 +- php/lib/dijit/themes/tundra/Calendar.css | 162 +- php/lib/dijit/themes/tundra/Calendar_rtl.css | 10 +- php/lib/dijit/themes/tundra/ColorPalette.css | 6 +- php/lib/dijit/themes/tundra/Common.css | 35 +- php/lib/dijit/themes/tundra/Dialog.css | 153 +- php/lib/dijit/themes/tundra/Dialog_rtl.css | 6 +- php/lib/dijit/themes/tundra/Editor.css | 17 +- php/lib/dijit/themes/tundra/Editor_rtl.css | 8 +- php/lib/dijit/themes/tundra/Menu.css | 78 +- php/lib/dijit/themes/tundra/Menu_rtl.css | 4 +- php/lib/dijit/themes/tundra/ProgressBar.css | 29 +- php/lib/dijit/themes/tundra/TimePicker.css | 53 +- .../dijit/themes/tundra/TimePicker_rtl.css | 5 +- php/lib/dijit/themes/tundra/TitlePane.css | 39 +- php/lib/dijit/themes/tundra/TitlePane_rtl.css | 4 +- php/lib/dijit/themes/tundra/Toolbar.css | 76 +- php/lib/dijit/themes/tundra/Tree.css | 97 +- php/lib/dijit/themes/tundra/Tree_rtl.css | 18 +- php/lib/dijit/themes/tundra/form/Button.css | 137 +- php/lib/dijit/themes/tundra/form/Checkbox.css | 55 +- php/lib/dijit/themes/tundra/form/Common.css | 77 +- .../dijit/themes/tundra/form/RadioButton.css | 53 +- php/lib/dijit/themes/tundra/form/Select.css | 58 +- php/lib/dijit/themes/tundra/form/Slider.css | 148 +- .../dijit/themes/tundra/form/Slider_rtl.css | 32 +- .../dijit/themes/tundra/images/dndNoCopy.png | Bin 699 -> 1332 bytes .../dijit/themes/tundra/images/dndNoMove.png | Bin 677 -> 991 bytes .../tundra/layout/AccordionContainer.css | 27 +- .../themes/tundra/layout/BorderContainer.css | 70 +- .../themes/tundra/layout/ContentPane.css | 22 +- .../themes/tundra/layout/SplitContainer.css | 32 +- .../themes/tundra/layout/TabContainer.css | 336 +- .../themes/tundra/layout/TabContainer_rtl.css | 52 +- php/lib/dijit/themes/tundra/tundra.css | 42 +- php/lib/dijit/themes/tundra/tundra_rtl.css | 28 +- php/lib/dijit/tree/ForestStoreModel.js | 2 +- php/lib/dijit/tree/ObjectStoreModel.js | 2 + php/lib/dijit/tree/TreeStoreModel.js | 2 +- php/lib/dijit/tree/_dndContainer.js | 2 +- php/lib/dijit/tree/_dndSelector.js | 2 +- php/lib/dijit/tree/dndSource.js | 2 +- php/lib/dijit/tree/model.js | 1 + php/lib/dijit/typematic.js | 2 +- php/lib/dojo-src/.gitignore | 2 + php/lib/dojo-src/rebuild-dojo.sh | 22 +- php/lib/dojo-src/tt-rss.profile.js | 7 + php/lib/dojo/AdapterRegistry.js | 2 +- php/lib/dojo/Deferred.js | 8 + php/lib/dojo/DeferredList.js | 2 +- php/lib/dojo/Evented.js | 2 +- php/lib/dojo/LICENSE | 2 +- php/lib/dojo/NodeList-data.js | 2 +- php/lib/dojo/NodeList-dom.js | 4 +- php/lib/dojo/NodeList-fx.js | 4 +- php/lib/dojo/NodeList-html.js | 2 +- php/lib/dojo/NodeList-manipulate.js | 2 +- php/lib/dojo/NodeList-traverse.js | 2 +- php/lib/dojo/NodeList.js | 8 + php/lib/dojo/OpenAjax.js | 28 +- php/lib/dojo/Stateful.js | 4 +- php/lib/dojo/_base/Color.js | 2 +- php/lib/dojo/_base/Deferred.js | 4 +- php/lib/dojo/_base/NodeList.js | 4 +- php/lib/dojo/_base/array.js | 4 +- php/lib/dojo/_base/browser.js | 2 +- php/lib/dojo/_base/config.js | 2 +- php/lib/dojo/_base/configFirefoxExtension.js | 28 +- php/lib/dojo/_base/configNode.js | 10 +- php/lib/dojo/_base/configRhino.js | 2 +- php/lib/dojo/_base/configSpidermonkey.js | 14 +- php/lib/dojo/_base/connect.js | 4 +- php/lib/dojo/_base/declare.js | 4 +- php/lib/dojo/_base/event.js | 4 +- php/lib/dojo/_base/fx.js | 4 +- php/lib/dojo/_base/html.js | 2 +- php/lib/dojo/_base/json.js | 2 +- php/lib/dojo/_base/kernel.js | 4 +- php/lib/dojo/_base/lang.js | 4 +- php/lib/dojo/_base/loader.js | 4 +- php/lib/dojo/_base/query.js | 4 +- php/lib/dojo/_base/sniff.js | 4 +- php/lib/dojo/_base/unload.js | 4 +- php/lib/dojo/_base/url.js | 2 +- php/lib/dojo/_base/window.js | 4 +- php/lib/dojo/_base/xhr.js | 4 +- php/lib/dojo/_firebug/firebug.css | 212 +- php/lib/dojo/_firebug/firebug.js | 4 +- php/lib/dojo/aspect.js | 4 +- php/lib/dojo/back.js | 4 +- php/lib/dojo/behavior.js | 4 +- php/lib/dojo/cache.js | 4 +- php/lib/dojo/cldr/monetary.js | 4 +- php/lib/dojo/cldr/nls/ar/buddhist.js | 4 +- php/lib/dojo/cldr/nls/ar/currency.js | 4 +- php/lib/dojo/cldr/nls/ar/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ar/hebrew.js | 4 +- php/lib/dojo/cldr/nls/ar/islamic.js | 4 +- php/lib/dojo/cldr/nls/ar/number.js | 4 +- php/lib/dojo/cldr/nls/buddhist.js | 4 +- php/lib/dojo/cldr/nls/ca/buddhist.js | 8 + php/lib/dojo/cldr/nls/ca/currency.js | 4 +- php/lib/dojo/cldr/nls/ca/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ca/number.js | 4 +- php/lib/dojo/cldr/nls/cs/buddhist.js | 8 + php/lib/dojo/cldr/nls/cs/currency.js | 4 +- php/lib/dojo/cldr/nls/cs/gregorian.js | 4 +- php/lib/dojo/cldr/nls/cs/islamic.js | 8 + php/lib/dojo/cldr/nls/cs/number.js | 4 +- php/lib/dojo/cldr/nls/currency.js | 4 +- php/lib/dojo/cldr/nls/da/buddhist.js | 4 +- php/lib/dojo/cldr/nls/da/currency.js | 4 +- php/lib/dojo/cldr/nls/da/gregorian.js | 4 +- php/lib/dojo/cldr/nls/da/islamic.js | 4 +- php/lib/dojo/cldr/nls/da/number.js | 4 +- php/lib/dojo/cldr/nls/de/buddhist.js | 4 +- php/lib/dojo/cldr/nls/de/currency.js | 4 +- php/lib/dojo/cldr/nls/de/gregorian.js | 4 +- php/lib/dojo/cldr/nls/de/islamic.js | 4 +- php/lib/dojo/cldr/nls/de/number.js | 4 +- php/lib/dojo/cldr/nls/el/buddhist.js | 4 +- php/lib/dojo/cldr/nls/el/currency.js | 4 +- php/lib/dojo/cldr/nls/el/gregorian.js | 4 +- php/lib/dojo/cldr/nls/el/hebrew.js | 4 +- php/lib/dojo/cldr/nls/el/number.js | 4 +- php/lib/dojo/cldr/nls/en-au/currency.js | 2 +- php/lib/dojo/cldr/nls/en-au/gregorian.js | 4 +- php/lib/dojo/cldr/nls/en-au/number.js | 2 +- php/lib/dojo/cldr/nls/en-ca/currency.js | 2 +- php/lib/dojo/cldr/nls/en-ca/gregorian.js | 4 +- php/lib/dojo/cldr/nls/en-gb/buddhist.js | 4 +- php/lib/dojo/cldr/nls/en-gb/currency.js | 8 + php/lib/dojo/cldr/nls/en-gb/gregorian.js | 4 +- php/lib/dojo/cldr/nls/en-gb/islamic.js | 4 +- php/lib/dojo/cldr/nls/en-gb/number.js | 4 +- php/lib/dojo/cldr/nls/en/buddhist.js | 4 +- php/lib/dojo/cldr/nls/en/currency.js | 2 +- php/lib/dojo/cldr/nls/en/gregorian.js | 4 +- php/lib/dojo/cldr/nls/en/islamic.js | 4 +- php/lib/dojo/cldr/nls/en/number.js | 4 +- php/lib/dojo/cldr/nls/es/buddhist.js | 4 +- php/lib/dojo/cldr/nls/es/currency.js | 4 +- php/lib/dojo/cldr/nls/es/gregorian.js | 4 +- php/lib/dojo/cldr/nls/es/islamic.js | 4 +- php/lib/dojo/cldr/nls/es/number.js | 4 +- php/lib/dojo/cldr/nls/fi/buddhist.js | 4 +- php/lib/dojo/cldr/nls/fi/currency.js | 4 +- php/lib/dojo/cldr/nls/fi/gregorian.js | 4 +- php/lib/dojo/cldr/nls/fi/hebrew.js | 4 +- php/lib/dojo/cldr/nls/fi/islamic.js | 4 +- php/lib/dojo/cldr/nls/fi/number.js | 4 +- php/lib/dojo/cldr/nls/fr-ch/gregorian.js | 2 +- php/lib/dojo/cldr/nls/fr-ch/number.js | 2 +- php/lib/dojo/cldr/nls/fr/buddhist.js | 8 + php/lib/dojo/cldr/nls/fr/currency.js | 4 +- php/lib/dojo/cldr/nls/fr/gregorian.js | 4 +- php/lib/dojo/cldr/nls/fr/hebrew.js | 8 + php/lib/dojo/cldr/nls/fr/islamic.js | 8 + php/lib/dojo/cldr/nls/fr/number.js | 4 +- php/lib/dojo/cldr/nls/gregorian.js | 4 +- php/lib/dojo/cldr/nls/he/currency.js | 2 +- php/lib/dojo/cldr/nls/he/gregorian.js | 4 +- php/lib/dojo/cldr/nls/he/hebrew.js | 4 +- php/lib/dojo/cldr/nls/he/islamic.js | 4 +- php/lib/dojo/cldr/nls/he/number.js | 4 +- php/lib/dojo/cldr/nls/hebrew.js | 4 +- php/lib/dojo/cldr/nls/hu/buddhist.js | 8 + php/lib/dojo/cldr/nls/hu/currency.js | 4 +- php/lib/dojo/cldr/nls/hu/gregorian.js | 4 +- php/lib/dojo/cldr/nls/hu/hebrew.js | 8 + php/lib/dojo/cldr/nls/hu/islamic.js | 8 + php/lib/dojo/cldr/nls/hu/number.js | 4 +- php/lib/dojo/cldr/nls/islamic.js | 4 +- php/lib/dojo/cldr/nls/it/buddhist.js | 8 + php/lib/dojo/cldr/nls/it/currency.js | 4 +- php/lib/dojo/cldr/nls/it/gregorian.js | 4 +- php/lib/dojo/cldr/nls/it/islamic.js | 8 + php/lib/dojo/cldr/nls/it/number.js | 4 +- php/lib/dojo/cldr/nls/ja/buddhist.js | 8 + php/lib/dojo/cldr/nls/ja/currency.js | 4 +- php/lib/dojo/cldr/nls/ja/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ja/hebrew.js | 8 + php/lib/dojo/cldr/nls/ja/islamic.js | 8 + php/lib/dojo/cldr/nls/ja/number.js | 4 +- php/lib/dojo/cldr/nls/ko/buddhist.js | 8 + php/lib/dojo/cldr/nls/ko/currency.js | 4 +- php/lib/dojo/cldr/nls/ko/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ko/number.js | 4 +- php/lib/dojo/cldr/nls/nb/buddhist.js | 8 + php/lib/dojo/cldr/nls/nb/currency.js | 4 +- php/lib/dojo/cldr/nls/nb/gregorian.js | 4 +- php/lib/dojo/cldr/nls/nb/islamic.js | 8 + php/lib/dojo/cldr/nls/nb/number.js | 4 +- php/lib/dojo/cldr/nls/nl/buddhist.js | 8 + php/lib/dojo/cldr/nls/nl/currency.js | 4 +- php/lib/dojo/cldr/nls/nl/gregorian.js | 4 +- php/lib/dojo/cldr/nls/nl/hebrew.js | 8 + php/lib/dojo/cldr/nls/nl/islamic.js | 8 + php/lib/dojo/cldr/nls/nl/number.js | 4 +- php/lib/dojo/cldr/nls/number.js | 4 +- php/lib/dojo/cldr/nls/pl/buddhist.js | 8 + php/lib/dojo/cldr/nls/pl/currency.js | 4 +- php/lib/dojo/cldr/nls/pl/gregorian.js | 4 +- php/lib/dojo/cldr/nls/pl/hebrew.js | 8 + php/lib/dojo/cldr/nls/pl/islamic.js | 8 + php/lib/dojo/cldr/nls/pl/number.js | 4 +- php/lib/dojo/cldr/nls/pt-pt/buddhist.js | 8 + php/lib/dojo/cldr/nls/pt-pt/currency.js | 8 + php/lib/dojo/cldr/nls/pt-pt/gregorian.js | 4 +- php/lib/dojo/cldr/nls/pt-pt/islamic.js | 8 + php/lib/dojo/cldr/nls/pt-pt/number.js | 4 +- php/lib/dojo/cldr/nls/pt/buddhist.js | 8 + php/lib/dojo/cldr/nls/pt/currency.js | 4 +- php/lib/dojo/cldr/nls/pt/gregorian.js | 4 +- php/lib/dojo/cldr/nls/pt/hebrew.js | 8 + php/lib/dojo/cldr/nls/pt/islamic.js | 8 + php/lib/dojo/cldr/nls/pt/number.js | 4 +- php/lib/dojo/cldr/nls/ro/buddhist.js | 4 +- php/lib/dojo/cldr/nls/ro/currency.js | 4 +- php/lib/dojo/cldr/nls/ro/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ro/hebrew.js | 8 + php/lib/dojo/cldr/nls/ro/islamic.js | 8 + php/lib/dojo/cldr/nls/ro/number.js | 4 +- php/lib/dojo/cldr/nls/ru/buddhist.js | 8 + php/lib/dojo/cldr/nls/ru/currency.js | 4 +- php/lib/dojo/cldr/nls/ru/gregorian.js | 4 +- php/lib/dojo/cldr/nls/ru/hebrew.js | 8 + php/lib/dojo/cldr/nls/ru/islamic.js | 8 + php/lib/dojo/cldr/nls/ru/number.js | 4 +- php/lib/dojo/cldr/nls/sk/currency.js | 4 +- php/lib/dojo/cldr/nls/sk/gregorian.js | 4 +- php/lib/dojo/cldr/nls/sk/number.js | 4 +- php/lib/dojo/cldr/nls/sl/currency.js | 2 +- php/lib/dojo/cldr/nls/sl/gregorian.js | 4 +- php/lib/dojo/cldr/nls/sl/number.js | 4 +- php/lib/dojo/cldr/nls/sv/buddhist.js | 8 + php/lib/dojo/cldr/nls/sv/currency.js | 4 +- php/lib/dojo/cldr/nls/sv/gregorian.js | 4 +- php/lib/dojo/cldr/nls/sv/hebrew.js | 8 + php/lib/dojo/cldr/nls/sv/islamic.js | 8 + php/lib/dojo/cldr/nls/sv/number.js | 4 +- php/lib/dojo/cldr/nls/th/buddhist.js | 4 +- php/lib/dojo/cldr/nls/th/currency.js | 4 +- php/lib/dojo/cldr/nls/th/gregorian.js | 4 +- php/lib/dojo/cldr/nls/th/hebrew.js | 8 + php/lib/dojo/cldr/nls/th/islamic.js | 8 + php/lib/dojo/cldr/nls/th/number.js | 4 +- php/lib/dojo/cldr/nls/tr/buddhist.js | 8 + php/lib/dojo/cldr/nls/tr/currency.js | 4 +- php/lib/dojo/cldr/nls/tr/gregorian.js | 4 +- php/lib/dojo/cldr/nls/tr/hebrew.js | 8 + php/lib/dojo/cldr/nls/tr/islamic.js | 8 + php/lib/dojo/cldr/nls/tr/number.js | 4 +- php/lib/dojo/cldr/nls/zh-hant/buddhist.js | 4 +- php/lib/dojo/cldr/nls/zh-hant/currency.js | 4 +- php/lib/dojo/cldr/nls/zh-hant/gregorian.js | 4 +- php/lib/dojo/cldr/nls/zh-hant/hebrew.js | 8 + php/lib/dojo/cldr/nls/zh-hant/islamic.js | 4 +- php/lib/dojo/cldr/nls/zh-hant/number.js | 4 +- php/lib/dojo/cldr/nls/zh-hk/currency.js | 4 +- php/lib/dojo/cldr/nls/zh-hk/gregorian.js | 4 +- php/lib/dojo/cldr/nls/zh-hk/number.js | 4 +- php/lib/dojo/cldr/nls/zh-tw/currency.js | 4 +- php/lib/dojo/cldr/nls/zh-tw/gregorian.js | 4 +- php/lib/dojo/cldr/nls/zh-tw/number.js | 8 + php/lib/dojo/cldr/nls/zh/buddhist.js | 8 + php/lib/dojo/cldr/nls/zh/currency.js | 4 +- php/lib/dojo/cldr/nls/zh/gregorian.js | 4 +- php/lib/dojo/cldr/nls/zh/hebrew.js | 8 + php/lib/dojo/cldr/nls/zh/islamic.js | 8 + php/lib/dojo/cldr/nls/zh/number.js | 4 +- php/lib/dojo/cldr/supplemental.js | 4 +- php/lib/dojo/colors.js | 4 +- php/lib/dojo/cookie.js | 2 +- php/lib/dojo/currency.js | 4 +- php/lib/dojo/data/ItemFileReadStore.js | 4 +- php/lib/dojo/data/ItemFileWriteStore.js | 4 +- php/lib/dojo/data/ObjectStore.js | 4 +- php/lib/dojo/data/api/Identity.js | 4 +- php/lib/dojo/data/api/Item.js | 8 + php/lib/dojo/data/api/Notification.js | 4 +- php/lib/dojo/data/api/Read.js | 4 +- php/lib/dojo/data/api/Request.js | 4 +- php/lib/dojo/data/api/Write.js | 4 +- php/lib/dojo/data/util/filter.js | 4 +- php/lib/dojo/data/util/simpleFetch.js | 4 +- php/lib/dojo/data/util/sorter.js | 4 +- php/lib/dojo/date.js | 4 +- php/lib/dojo/date/locale.js | 4 +- php/lib/dojo/date/stamp.js | 4 +- php/lib/dojo/dnd/AutoSource.js | 4 +- php/lib/dojo/dnd/Avatar.js | 4 +- php/lib/dojo/dnd/Container.js | 4 +- php/lib/dojo/dnd/Manager.js | 4 +- php/lib/dojo/dnd/Moveable.js | 4 +- php/lib/dojo/dnd/Mover.js | 4 +- php/lib/dojo/dnd/Selector.js | 4 +- php/lib/dojo/dnd/Source.js | 4 +- php/lib/dojo/dnd/Target.js | 4 +- php/lib/dojo/dnd/TimedMoveable.js | 4 +- php/lib/dojo/dnd/autoscroll.js | 4 +- php/lib/dojo/dnd/common.js | 4 +- php/lib/dojo/dnd/move.js | 4 +- php/lib/dojo/dojo.js | 4 +- php/lib/dojo/dojo.profile.js | 12 +- php/lib/dojo/dom-attr.js | 4 +- php/lib/dojo/dom-class.js | 2 +- php/lib/dojo/dom-construct.js | 4 +- php/lib/dojo/dom-form.js | 2 +- php/lib/dojo/dom-geometry.js | 4 +- php/lib/dojo/dom-prop.js | 4 +- php/lib/dojo/dom-style.js | 4 +- php/lib/dojo/dom.js | 4 +- php/lib/dojo/domReady.js | 4 +- php/lib/dojo/errors/CancelError.js | 8 + php/lib/dojo/errors/RequestError.js | 8 + php/lib/dojo/errors/RequestTimeoutError.js | 8 + php/lib/dojo/errors/create.js | 8 + php/lib/dojo/fx.js | 2 +- php/lib/dojo/fx/Toggler.js | 2 +- php/lib/dojo/fx/easing.js | 2 +- php/lib/dojo/gears.js | 4 +- php/lib/dojo/has.js | 4 +- php/lib/dojo/hash.js | 4 +- php/lib/dojo/hccss.js | 8 + php/lib/dojo/html.js | 4 +- php/lib/dojo/i18n.js | 4 +- php/lib/dojo/io-query.js | 4 +- php/lib/dojo/io/iframe.js | 4 +- php/lib/dojo/io/script.js | 4 +- php/lib/dojo/jaxer.js | 4 +- php/lib/dojo/json.js | 4 +- php/lib/dojo/keys.js | 4 +- php/lib/dojo/loadInit.js | 2 +- php/lib/dojo/main.js | 4 +- php/lib/dojo/mouse.js | 4 +- php/lib/dojo/nls/ar/colors.js | 2 +- php/lib/dojo/nls/az/colors.js | 2 +- php/lib/dojo/nls/ca/colors.js | 2 +- php/lib/dojo/nls/colors.js | 2 +- php/lib/dojo/nls/cs/colors.js | 2 +- php/lib/dojo/nls/da/colors.js | 2 +- php/lib/dojo/nls/de/colors.js | 2 +- php/lib/dojo/nls/el/colors.js | 2 +- php/lib/dojo/nls/es/colors.js | 2 +- php/lib/dojo/nls/fi/colors.js | 2 +- php/lib/dojo/nls/fr/colors.js | 2 +- php/lib/dojo/nls/he/colors.js | 4 +- php/lib/dojo/nls/hr/colors.js | 4 +- php/lib/dojo/nls/hu/colors.js | 2 +- php/lib/dojo/nls/it/colors.js | 2 +- php/lib/dojo/nls/ja/colors.js | 2 +- php/lib/dojo/nls/kk/colors.js | 2 +- php/lib/dojo/nls/ko/colors.js | 2 +- php/lib/dojo/nls/nb/colors.js | 2 +- php/lib/dojo/nls/nl/colors.js | 2 +- php/lib/dojo/nls/pl/colors.js | 2 +- php/lib/dojo/nls/pt-pt/colors.js | 2 +- php/lib/dojo/nls/pt/colors.js | 2 +- php/lib/dojo/nls/ro/colors.js | 2 +- php/lib/dojo/nls/ru/colors.js | 2 +- php/lib/dojo/nls/sk/colors.js | 2 +- php/lib/dojo/nls/sl/colors.js | 4 +- php/lib/dojo/nls/sv/colors.js | 2 +- php/lib/dojo/nls/th/colors.js | 4 +- php/lib/dojo/nls/tr/colors.js | 2 +- php/lib/dojo/nls/tt-rss-layer_ROOT.js | 4 +- php/lib/dojo/nls/tt-rss-layer_ar.js | 4 +- php/lib/dojo/nls/tt-rss-layer_ca.js | 4 +- php/lib/dojo/nls/tt-rss-layer_cs.js | 4 +- php/lib/dojo/nls/tt-rss-layer_da.js | 4 +- php/lib/dojo/nls/tt-rss-layer_de-de.js | 8 - php/lib/dojo/nls/tt-rss-layer_de.js | 8 + php/lib/dojo/nls/tt-rss-layer_el.js | 4 +- php/lib/dojo/nls/tt-rss-layer_en-gb.js | 4 +- php/lib/dojo/nls/tt-rss-layer_en-us.js | 4 +- php/lib/dojo/nls/tt-rss-layer_es-es.js | 4 +- php/lib/dojo/nls/tt-rss-layer_fi-fi.js | 4 +- php/lib/dojo/nls/tt-rss-layer_fr-fr.js | 4 +- php/lib/dojo/nls/tt-rss-layer_he-il.js | 4 +- php/lib/dojo/nls/tt-rss-layer_hu.js | 4 +- php/lib/dojo/nls/tt-rss-layer_it-it.js | 4 +- php/lib/dojo/nls/tt-rss-layer_ja-jp.js | 4 +- php/lib/dojo/nls/tt-rss-layer_ko-kr.js | 4 +- php/lib/dojo/nls/tt-rss-layer_nb.js | 4 +- php/lib/dojo/nls/tt-rss-layer_nl-nl.js | 4 +- php/lib/dojo/nls/tt-rss-layer_pl.js | 4 +- php/lib/dojo/nls/tt-rss-layer_pt-br.js | 4 +- php/lib/dojo/nls/tt-rss-layer_pt-pt.js | 4 +- php/lib/dojo/nls/tt-rss-layer_ru.js | 4 +- php/lib/dojo/nls/tt-rss-layer_sk.js | 4 +- php/lib/dojo/nls/tt-rss-layer_sl.js | 4 +- php/lib/dojo/nls/tt-rss-layer_sv.js | 4 +- php/lib/dojo/nls/tt-rss-layer_th.js | 4 +- php/lib/dojo/nls/tt-rss-layer_tr.js | 4 +- php/lib/dojo/nls/tt-rss-layer_zh-cn.js | 4 +- php/lib/dojo/nls/tt-rss-layer_zh-tw.js | 4 +- php/lib/dojo/nls/zh-tw/colors.js | 2 +- php/lib/dojo/nls/zh/colors.js | 2 +- php/lib/dojo/node.js | 8 + php/lib/dojo/number.js | 4 +- php/lib/dojo/on.js | 4 +- php/lib/dojo/package.json | 2 +- php/lib/dojo/parser.js | 4 +- php/lib/dojo/promise/Promise.js | 8 + php/lib/dojo/promise/all.js | 8 + php/lib/dojo/promise/first.js | 8 + php/lib/dojo/promise/instrumentation.js | 8 + php/lib/dojo/promise/tracer.js | 8 + php/lib/dojo/query.js | 4 +- php/lib/dojo/ready.js | 4 +- php/lib/dojo/regexp.js | 4 +- php/lib/dojo/request.js | 8 + php/lib/dojo/request/default.js | 8 + php/lib/dojo/request/handlers.js | 8 + php/lib/dojo/request/iframe.js | 8 + php/lib/dojo/request/node.js | 8 + php/lib/dojo/request/notify.js | 8 + php/lib/dojo/request/registry.js | 8 + php/lib/dojo/request/script.js | 8 + php/lib/dojo/request/util.js | 8 + php/lib/dojo/request/watch.js | 8 + php/lib/dojo/request/xhr.js | 8 + php/lib/dojo/require.js | 2 +- php/lib/dojo/resources/_modules.js | 36 - php/lib/dojo/resources/dnd.css | 17 +- php/lib/dojo/resources/dojo.css | 197 +- php/lib/dojo/router.js | 8 + php/lib/dojo/router/RouterBase.js | 8 + php/lib/dojo/rpc/JsonService.js | 4 +- php/lib/dojo/rpc/JsonpService.js | 4 +- php/lib/dojo/rpc/RpcService.js | 4 +- php/lib/dojo/selector/_loader.js | 2 +- php/lib/dojo/selector/acme.js | 4 +- php/lib/dojo/selector/lite.js | 4 +- php/lib/dojo/sniff.js | 8 + php/lib/dojo/store/Cache.js | 4 +- php/lib/dojo/store/DataStore.js | 4 +- php/lib/dojo/store/JsonRest.js | 4 +- php/lib/dojo/store/Memory.js | 4 +- php/lib/dojo/store/Observable.js | 4 +- php/lib/dojo/store/README | 14 +- php/lib/dojo/store/api/Store.js | 4 +- php/lib/dojo/store/util/QueryResults.js | 4 +- php/lib/dojo/store/util/SimpleQueryEngine.js | 4 +- php/lib/dojo/string.js | 4 +- php/lib/dojo/text.js | 4 +- php/lib/dojo/topic.js | 2 +- php/lib/dojo/touch.js | 4 +- php/lib/dojo/tt-rss-layer.js | 4 +- php/lib/dojo/uacss.js | 4 +- php/lib/dojo/when.js | 8 + php/lib/dojo/window.js | 4 +- php/lib/floIcon.php | 849 + php/lib/gettext/gettext.inc | 78 +- php/lib/gettext/gettext.php | 17 +- php/lib/htmLawed.php | 723 - php/lib/index.html | 0 php/lib/iui/LICENSE.txt | 21 - php/lib/iui/NOTICE.txt | 33 - php/lib/iui/backButton.png | Bin 816 -> 0 bytes php/lib/iui/blueButton.png | Bin 517 -> 0 bytes php/lib/iui/cancel.png | Bin 362 -> 0 bytes php/lib/iui/grayButton.png | Bin 943 -> 0 bytes php/lib/iui/iui-logo-touch-icon.png | Bin 2887 -> 0 bytes php/lib/iui/iui.css | 398 - php/lib/iui/iui.js | 542 - php/lib/iui/iuix.css | 1 - php/lib/iui/iuix.js | 1 - php/lib/iui/listArrow.png | Bin 259 -> 0 bytes php/lib/iui/listArrowSel.png | Bin 308 -> 0 bytes php/lib/iui/listGroup.png | Bin 2867 -> 0 bytes php/lib/iui/loading.gif | Bin 1435 -> 0 bytes php/lib/iui/pinstripes.png | Bin 117 -> 0 bytes php/lib/iui/redButton.png | Bin 947 -> 0 bytes php/lib/iui/selection.png | Bin 159 -> 0 bytes php/lib/iui/thumb.png | Bin 2835 -> 0 bytes php/lib/iui/toggle.png | Bin 2815 -> 0 bytes php/lib/iui/toggleOn.png | Bin 163 -> 0 bytes php/lib/iui/toolButton.png | Bin 531 -> 0 bytes php/lib/iui/toolbar.png | Bin 171 -> 0 bytes php/lib/iui/whiteButton.png | Bin 978 -> 0 bytes php/lib/jshrink/LICENSE | 24 + php/lib/jshrink/Minifier.php | 470 + php/lib/jshrink/README.md | 21 + php/lib/jsmin.php | 375 - php/lib/phpqrcode/bindings/tcpdf/qrcode.php | 8 +- php/lib/phpqrcode/phpqrcode.php | 12 +- php/lib/phpqrcode/qrencode.php | 2 +- php/lib/phpqrcode/qrmask.php | 4 +- php/lib/phpqrcode/qrsplit.php | 8 +- php/lib/position.js | 31 - php/lib/simplepie/simplepie.inc | 17772 ---------------- php/lib/timezones.txt | 1 + php/locale/.htaccess | 2 + php/locale/ca_CA/LC_MESSAGES/messages.mo | Bin 28356 -> 23924 bytes php/locale/ca_CA/LC_MESSAGES/messages.po | 5143 +++-- php/locale/cs_CZ/LC_MESSAGES/messages.mo | Bin 0 -> 62404 bytes php/locale/cs_CZ/LC_MESSAGES/messages.po | 3758 ++++ php/locale/de_DE/LC_MESSAGES/messages.mo | Bin 49701 -> 66102 bytes php/locale/de_DE/LC_MESSAGES/messages.po | 4364 ++-- php/locale/es_ES/LC_MESSAGES/messages.mo | Bin 46681 -> 68105 bytes php/locale/es_ES/LC_MESSAGES/messages.po | 5109 +++-- php/locale/fi_FI/LC_MESSAGES/messages.mo | Bin 0 -> 42356 bytes php/locale/fi_FI/LC_MESSAGES/messages.po | 3697 ++++ php/locale/fr_FR/LC_MESSAGES/messages.mo | Bin 50526 -> 68002 bytes php/locale/fr_FR/LC_MESSAGES/messages.po | 4292 ++-- php/locale/hu_HU/LC_MESSAGES/messages.mo | Bin 25696 -> 51926 bytes php/locale/hu_HU/LC_MESSAGES/messages.po | 5777 +++-- php/locale/it_IT/LC_MESSAGES/messages.mo | Bin 44627 -> 35860 bytes php/locale/it_IT/LC_MESSAGES/messages.po | 4580 ++-- php/locale/ja_JP/LC_MESSAGES/messages.mo | Bin 25811 -> 24564 bytes php/locale/ja_JP/LC_MESSAGES/messages.po | 5539 ++--- php/locale/lv_LV/LC_MESSAGES/messages.mo | Bin 0 -> 44585 bytes php/locale/lv_LV/LC_MESSAGES/messages.po | 4026 ++++ php/locale/nb_NO/LC_MESSAGES/messages.mo | Bin 26920 -> 22671 bytes php/locale/nb_NO/LC_MESSAGES/messages.po | 5137 +++-- php/locale/nl_NL/LC_MESSAGES/messages.mo | Bin 0 -> 65016 bytes php/locale/nl_NL/LC_MESSAGES/messages.po | 3755 ++++ php/locale/pl_PL/LC_MESSAGES/messages.mo | Bin 51968 -> 66402 bytes php/locale/pl_PL/LC_MESSAGES/messages.po | 4689 ++-- php/locale/pt_BR/LC_MESSAGES/messages.mo | Bin 6986 -> 6580 bytes php/locale/pt_BR/LC_MESSAGES/messages.po | 4650 ++-- php/locale/ru_RU/LC_MESSAGES/messages.mo | Bin 46189 -> 37584 bytes php/locale/ru_RU/LC_MESSAGES/messages.po | 5328 +++-- php/locale/sv_SE/LC_MESSAGES/messages.mo | Bin 0 -> 62802 bytes php/locale/sv_SE/LC_MESSAGES/messages.po | 3943 ++++ php/locale/zh_CN/LC_MESSAGES/messages.mo | Bin 42009 -> 33808 bytes php/locale/zh_CN/LC_MESSAGES/messages.po | 4461 ++-- php/localized_js.php | 42 - php/lock/.empty | 0 php/lock/.htaccess | 0 php/messages.pot | 3207 +-- php/mobile/article.php | 24 - php/mobile/backend.php | 55 - php/mobile/cat.php | 21 - php/mobile/feed.php | 25 - php/mobile/home.php | 25 - php/mobile/image.php | 19 - php/mobile/index.php | 82 - php/mobile/login_form.php | 58 - php/mobile/logout.php | 7 - php/mobile/mobile-functions.php | 548 - php/mobile/mobile.css | 38 - php/mobile/mobile.js | 163 - php/mobile/prefs.php | 54 - php/opml.php | 13 +- php/plugins/af_buttersafe/init.php | 9 +- php/plugins/af_explosm/init.php | 8 +- php/plugins/af_gocomics/init.php | 10 +- php/plugins/af_pennyarcade/init.php | 59 +- php/plugins/af_redditimgur/init.php | 24 +- php/plugins/af_unburn/init.php | 66 +- php/plugins/auth_imap/init.php | 51 - php/plugins/auth_internal/init.php | 39 +- php/plugins/auth_remote/init.php | 20 +- php/plugins/bookmarklets/init.php | 17 +- php/plugins/close_button/init.php | 11 +- php/plugins/digest/digest.css | 337 - php/plugins/digest/digest.js | 906 - php/plugins/digest/digest_body.php | 81 - php/plugins/digest/images/tile.png | Bin 958 -> 0 bytes php/plugins/digest/init.php | 110 - php/plugins/embed_original/button.png | Bin 0 -> 1298 bytes php/plugins/embed_original/init.css | 13 + php/plugins/embed_original/init.js | 68 + php/plugins/embed_original/init.php | 58 + php/plugins/example/example.js | 3 - php/plugins/example/init.php | 82 - php/plugins/example_article/init.php | 31 - php/plugins/example_feed/init.php | 29 - php/plugins/example_routing/init.php | 54 - php/plugins/flattr/flattr.png | Bin 693 -> 0 bytes php/plugins/flattr/init.php | 46 - php/plugins/googleplus/googleplus.js | 29 - php/plugins/googleplus/googleplus.png | Bin 3295 -> 0 bytes php/plugins/googleplus/init.php | 53 - php/plugins/googlereaderimport/init.js | 53 + php/plugins/googlereaderimport/init.php | 383 + php/plugins/googlereaderkeys/init.php | 26 +- php/plugins/identica/identica.js | 31 - php/plugins/identica/identica.png | Bin 121 -> 0 bytes php/plugins/identica/init.php | 53 - php/plugins/import_export/import_export.js | 4 +- php/plugins/import_export/init.php | 96 +- php/plugins/index.html | 0 php/plugins/instances/init.php | 106 +- php/plugins/instances/instances.js | 12 +- php/plugins/mail/init.php | 84 +- php/plugins/mail/mail.js | 1 + php/plugins/mailto/init.js | 32 + php/plugins/mailto/init.php | 94 + php/plugins/mailto/mail.png | Bin 0 -> 254 bytes php/plugins/mark_button/init.php | 43 + php/plugins/note/init.php | 12 +- php/plugins/nsfw/init.php | 7 +- php/plugins/owncloud/init.php | 96 - php/plugins/owncloud/owncloud.js | 26 - php/plugins/owncloud/owncloud.png | Bin 625 -> 0 bytes php/plugins/pinterest/init.php | 53 - php/plugins/pinterest/pinterest.js | 31 - php/plugins/pinterest/pinterest.png | Bin 3829 -> 0 bytes php/plugins/pocket/init.php | 54 - php/plugins/pocket/pocket.js | 31 - php/plugins/pocket/pocket.png | Bin 471 -> 0 bytes php/plugins/share/init.php | 19 +- php/plugins/swap_jk/init.php | 6 +- php/plugins/updater/init.php | 391 +- php/plugins/updater/updater.js | 4 +- php/prefs.css | 141 + php/prefs.php | 91 +- php/public.php | 14 +- php/register.php | 103 +- php/schema/.htaccess | 2 + php/schema/ttrss_schema_mysql.sql | 211 +- php/schema/ttrss_schema_pgsql.sql | 190 +- php/schema/versions/mysql/104.sql | 7 + php/schema/versions/mysql/105.sql | 11 + php/schema/versions/mysql/106.sql | 12 + php/schema/versions/mysql/107.sql | 15 + php/schema/versions/mysql/108.sql | 7 + php/schema/versions/mysql/109.sql | 7 + php/schema/versions/mysql/110.sql | 7 + php/schema/versions/mysql/111.sql | 7 + php/schema/versions/mysql/112.sql | 15 + php/schema/versions/mysql/113.sql | 8 + php/schema/versions/mysql/114.sql | 15 + php/schema/versions/mysql/115.sql | 9 + php/schema/versions/mysql/116.sql | 7 + php/schema/versions/mysql/117.sql | 8 + php/schema/versions/mysql/118.sql | 16 + php/schema/versions/mysql/119.sql | 7 + php/schema/versions/mysql/120.sql | 7 + php/schema/versions/pgsql/104.sql | 7 + php/schema/versions/pgsql/105.sql | 11 + php/schema/versions/pgsql/106.sql | 12 + php/schema/versions/pgsql/107.sql | 15 + php/schema/versions/pgsql/108.sql | 7 + php/schema/versions/pgsql/109.sql | 7 + php/schema/versions/pgsql/110.sql | 7 + php/schema/versions/pgsql/111.sql | 7 + php/schema/versions/pgsql/112.sql | 15 + php/schema/versions/pgsql/113.sql | 8 + php/schema/versions/pgsql/114.sql | 15 + php/schema/versions/pgsql/115.sql | 9 + php/schema/versions/pgsql/116.sql | 7 + php/schema/versions/pgsql/117.sql | 8 + php/schema/versions/pgsql/118.sql | 15 + php/schema/versions/pgsql/119.sql | 7 + php/schema/versions/pgsql/120.sql | 7 + php/templates/.htaccess | 2 + php/templates/email_article_template.txt | 2 - php/templates/resetpass_template.txt | 2 +- php/themes/.empty | 0 php/themes/default.css | 0 php/tt-rss.css | 698 +- php/update.php | 222 +- php/update_daemon2.php | 139 +- php/utility.css | 135 +- php/utils/.htaccess | 2 + php/utils/create-release-deb.sh | 23 - php/utils/create-release-tarball.sh | 6 - php/utils/update-schema-translations.sh | 19 - php/utils/update-translations.sh | 14 +- 1176 files changed, 69270 insertions(+), 71212 deletions(-) create mode 100644 php/.htaccess delete mode 100644 php/.settings/.jsdtscope delete mode 100644 php/.settings/org.eclipse.php.core.prefs delete mode 100644 php/.settings/org.eclipse.wst.jsdt.ui.superType.container delete mode 100644 php/.settings/org.eclipse.wst.jsdt.ui.superType.name mode change 100644 => 100755 php/cache/.htaccess mode change 100644 => 100755 php/cache/images/.empty rename php/cache/{magpie => js}/.empty (100%) mode change 100644 => 100755 mode change 100644 => 100755 php/cache/simplepie/.empty rename php/{plugins/example_article/init.js => cache/upload/.empty} (100%) create mode 100644 php/classes/.htaccess create mode 100644 php/classes/db.php create mode 100644 php/classes/db/mysql.php create mode 100644 php/classes/db/mysqli.php create mode 100644 php/classes/db/pdo.php create mode 100644 php/classes/db/pgsql.php create mode 100644 php/classes/db/prefs.php create mode 100644 php/classes/db/stmt.php create mode 100644 php/classes/dbupdater.php create mode 100644 php/classes/feedenclosure.php create mode 100644 php/classes/feeditem.php create mode 100644 php/classes/feeditem/atom.php create mode 100644 php/classes/feeditem/common.php create mode 100644 php/classes/feeditem/rss.php create mode 100644 php/classes/feedparser.php create mode 100644 php/classes/idb.php create mode 100644 php/classes/logger.php create mode 100644 php/classes/logger/sql.php create mode 100644 php/classes/logger/syslog.php create mode 100644 php/classes/pref/system.php delete mode 100644 php/classes/sanitizedummy.php create mode 100644 php/classes/ttrssmailer.php delete mode 100644 php/db-updater.php mode change 100644 => 100755 php/feed-icons/.empty create mode 100644 php/feed-icons/index.html create mode 100644 php/images/close_notify.svg create mode 100644 php/images/collapse.png create mode 100644 php/images/favicon-72px.png create mode 100644 php/images/logo_small.png delete mode 100644 php/images/overlay.png delete mode 100644 php/images/piggie.png delete mode 100644 php/images/piggie_icon.png create mode 100644 php/include/autoload.php create mode 100644 php/include/crypt.php create mode 100644 php/include/errorhandler.php delete mode 100644 php/include/localized_schema.php create mode 100644 php/install/index.php create mode 100644 php/js/PluginHost.js create mode 100644 php/js/index.html create mode 100644 php/lib/dijit/Destroyable.js create mode 100644 php/lib/dijit/Viewport.js create mode 100644 php/lib/dijit/a11yclick.js create mode 100644 php/lib/dijit/form/_SearchMixin.js delete mode 100644 php/lib/dijit/resources/_modules.js delete mode 100644 php/lib/dijit/themes/claro/form/Select_rtl.css delete mode 100644 php/lib/dijit/themes/claro/form/Select_rtl.less delete mode 100644 php/lib/dijit/themes/claro/form/images/button.png create mode 100644 php/lib/dijit/themes/claro/form/images/buttonDisabled.png create mode 100644 php/lib/dijit/themes/claro/form/images/buttonDisabled.svg create mode 100644 php/lib/dijit/themes/claro/form/images/buttonEnabled.png create mode 100644 php/lib/dijit/themes/claro/form/images/buttonEnabled.svg delete mode 100644 php/lib/dijit/themes/claro/form/images/button_grad_d.png delete mode 100644 php/lib/dijit/themes/claro/form/images/formHighlight.png delete mode 100644 php/lib/dijit/themes/claro/form/images/shadow.png delete mode 100644 php/lib/dijit/themes/claro/form/images/sliderHorizontal.png delete mode 100644 php/lib/dijit/themes/claro/form/images/sliderVertical.png delete mode 100644 php/lib/dijit/themes/claro/form/images/textBox_back.png create mode 100644 php/lib/dijit/themes/claro/images/activeGradient.png create mode 100644 php/lib/dijit/themes/claro/images/activeGradient.svg create mode 100644 php/lib/dijit/themes/claro/images/calendar.png delete mode 100644 php/lib/dijit/themes/claro/images/calendarContainerImages.png delete mode 100644 php/lib/dijit/themes/claro/images/commonHighlight.png delete mode 100644 php/lib/dijit/themes/claro/images/menuHighlight.png delete mode 100644 php/lib/dijit/themes/claro/images/progressBarEmpty.png create mode 100644 php/lib/dijit/themes/claro/images/standardGradient.png create mode 100644 php/lib/dijit/themes/claro/images/standardGradient.svg delete mode 100644 php/lib/dijit/themes/claro/images/titlebar.png delete mode 100644 php/lib/dijit/themes/claro/images/tooltipGradient.png delete mode 100644 php/lib/dijit/themes/claro/images/treeExpand_loading.gif delete mode 100644 php/lib/dijit/themes/claro/layout/images/accordion.png delete mode 100644 php/lib/dijit/themes/claro/layout/images/splitterHorizontalHover.png delete mode 100644 php/lib/dijit/themes/claro/layout/images/splitterVerticalHover.png delete mode 100644 php/lib/dijit/themes/claro/layout/images/tabBottom.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabBottomSelected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabBottomSelected.svg create mode 100644 php/lib/dijit/themes/claro/layout/images/tabBottomUnselected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabBottomUnselected.svg delete mode 100644 php/lib/dijit/themes/claro/layout/images/tabLeft.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabLeftSelected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabLeftSelected.svg create mode 100644 php/lib/dijit/themes/claro/layout/images/tabLeftUnselected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabLeftUnselected.svg delete mode 100644 php/lib/dijit/themes/claro/layout/images/tabRight.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabRightSelected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabRightSelected.svg create mode 100644 php/lib/dijit/themes/claro/layout/images/tabRightUnselected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabRightUnselected.svg delete mode 100644 php/lib/dijit/themes/claro/layout/images/tabTop.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabTopSelected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabTopSelected.svg create mode 100644 php/lib/dijit/themes/claro/layout/images/tabTopUnselected.png create mode 100644 php/lib/dijit/themes/claro/layout/images/tabTopUnselected.svg delete mode 100644 php/lib/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabLeftChecked.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabRightChecked.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabStripe.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabStripeBottom.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabStripeLeft.gif delete mode 100644 php/lib/dijit/themes/nihilo/images/tabStripeRight.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabStripe.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabStripeBottom.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabStripeLeft.gif delete mode 100644 php/lib/dijit/themes/soria/images/tabStripeRight.gif create mode 100644 php/lib/dijit/tree/ObjectStoreModel.js create mode 100644 php/lib/dojo/Deferred.js create mode 100644 php/lib/dojo/NodeList.js create mode 100644 php/lib/dojo/cldr/nls/ca/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/cs/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/cs/islamic.js create mode 100644 php/lib/dojo/cldr/nls/en-gb/currency.js create mode 100644 php/lib/dojo/cldr/nls/fr/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/fr/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/fr/islamic.js create mode 100644 php/lib/dojo/cldr/nls/hu/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/hu/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/hu/islamic.js create mode 100644 php/lib/dojo/cldr/nls/it/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/it/islamic.js create mode 100644 php/lib/dojo/cldr/nls/ja/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/ja/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/ja/islamic.js create mode 100644 php/lib/dojo/cldr/nls/ko/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/nb/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/nb/islamic.js create mode 100644 php/lib/dojo/cldr/nls/nl/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/nl/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/nl/islamic.js create mode 100644 php/lib/dojo/cldr/nls/pl/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/pl/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/pl/islamic.js create mode 100644 php/lib/dojo/cldr/nls/pt-pt/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/pt-pt/currency.js create mode 100644 php/lib/dojo/cldr/nls/pt-pt/islamic.js create mode 100644 php/lib/dojo/cldr/nls/pt/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/pt/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/pt/islamic.js create mode 100644 php/lib/dojo/cldr/nls/ro/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/ro/islamic.js create mode 100644 php/lib/dojo/cldr/nls/ru/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/ru/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/ru/islamic.js create mode 100644 php/lib/dojo/cldr/nls/sv/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/sv/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/sv/islamic.js create mode 100644 php/lib/dojo/cldr/nls/th/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/th/islamic.js create mode 100644 php/lib/dojo/cldr/nls/tr/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/tr/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/tr/islamic.js create mode 100644 php/lib/dojo/cldr/nls/zh-hant/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/zh-tw/number.js create mode 100644 php/lib/dojo/cldr/nls/zh/buddhist.js create mode 100644 php/lib/dojo/cldr/nls/zh/hebrew.js create mode 100644 php/lib/dojo/cldr/nls/zh/islamic.js create mode 100644 php/lib/dojo/data/api/Item.js create mode 100644 php/lib/dojo/errors/CancelError.js create mode 100644 php/lib/dojo/errors/RequestError.js create mode 100644 php/lib/dojo/errors/RequestTimeoutError.js create mode 100644 php/lib/dojo/errors/create.js create mode 100644 php/lib/dojo/hccss.js delete mode 100644 php/lib/dojo/nls/tt-rss-layer_de-de.js create mode 100644 php/lib/dojo/nls/tt-rss-layer_de.js create mode 100644 php/lib/dojo/node.js create mode 100644 php/lib/dojo/promise/Promise.js create mode 100644 php/lib/dojo/promise/all.js create mode 100644 php/lib/dojo/promise/first.js create mode 100644 php/lib/dojo/promise/instrumentation.js create mode 100644 php/lib/dojo/promise/tracer.js create mode 100644 php/lib/dojo/request.js create mode 100644 php/lib/dojo/request/default.js create mode 100644 php/lib/dojo/request/handlers.js create mode 100644 php/lib/dojo/request/iframe.js create mode 100644 php/lib/dojo/request/node.js create mode 100644 php/lib/dojo/request/notify.js create mode 100644 php/lib/dojo/request/registry.js create mode 100644 php/lib/dojo/request/script.js create mode 100644 php/lib/dojo/request/util.js create mode 100644 php/lib/dojo/request/watch.js create mode 100644 php/lib/dojo/request/xhr.js delete mode 100644 php/lib/dojo/resources/_modules.js create mode 100644 php/lib/dojo/router.js create mode 100644 php/lib/dojo/router/RouterBase.js create mode 100644 php/lib/dojo/sniff.js create mode 100644 php/lib/dojo/when.js create mode 100644 php/lib/floIcon.php delete mode 100644 php/lib/htmLawed.php create mode 100644 php/lib/index.html delete mode 100644 php/lib/iui/LICENSE.txt delete mode 100644 php/lib/iui/NOTICE.txt delete mode 100644 php/lib/iui/backButton.png delete mode 100644 php/lib/iui/blueButton.png delete mode 100644 php/lib/iui/cancel.png delete mode 100644 php/lib/iui/grayButton.png delete mode 100644 php/lib/iui/iui-logo-touch-icon.png delete mode 100644 php/lib/iui/iui.css delete mode 100644 php/lib/iui/iui.js delete mode 100644 php/lib/iui/iuix.css delete mode 100644 php/lib/iui/iuix.js delete mode 100644 php/lib/iui/listArrow.png delete mode 100644 php/lib/iui/listArrowSel.png delete mode 100644 php/lib/iui/listGroup.png delete mode 100644 php/lib/iui/loading.gif delete mode 100644 php/lib/iui/pinstripes.png delete mode 100644 php/lib/iui/redButton.png delete mode 100644 php/lib/iui/selection.png delete mode 100644 php/lib/iui/thumb.png delete mode 100644 php/lib/iui/toggle.png delete mode 100644 php/lib/iui/toggleOn.png delete mode 100644 php/lib/iui/toolButton.png delete mode 100644 php/lib/iui/toolbar.png delete mode 100644 php/lib/iui/whiteButton.png create mode 100644 php/lib/jshrink/LICENSE create mode 100644 php/lib/jshrink/Minifier.php create mode 100644 php/lib/jshrink/README.md delete mode 100644 php/lib/jsmin.php delete mode 100644 php/lib/position.js delete mode 100644 php/lib/simplepie/simplepie.inc create mode 100644 php/locale/.htaccess create mode 100644 php/locale/cs_CZ/LC_MESSAGES/messages.mo create mode 100644 php/locale/cs_CZ/LC_MESSAGES/messages.po mode change 100644 => 100755 php/locale/de_DE/LC_MESSAGES/messages.mo mode change 100644 => 100755 php/locale/de_DE/LC_MESSAGES/messages.po create mode 100644 php/locale/fi_FI/LC_MESSAGES/messages.mo create mode 100644 php/locale/fi_FI/LC_MESSAGES/messages.po create mode 100644 php/locale/lv_LV/LC_MESSAGES/messages.mo create mode 100644 php/locale/lv_LV/LC_MESSAGES/messages.po create mode 100644 php/locale/nl_NL/LC_MESSAGES/messages.mo create mode 100644 php/locale/nl_NL/LC_MESSAGES/messages.po create mode 100644 php/locale/sv_SE/LC_MESSAGES/messages.mo create mode 100644 php/locale/sv_SE/LC_MESSAGES/messages.po delete mode 100644 php/localized_js.php mode change 100644 => 100755 php/lock/.empty mode change 100644 => 100755 php/lock/.htaccess delete mode 100644 php/mobile/article.php delete mode 100644 php/mobile/backend.php delete mode 100644 php/mobile/cat.php delete mode 100644 php/mobile/feed.php delete mode 100644 php/mobile/home.php delete mode 100644 php/mobile/image.php delete mode 100644 php/mobile/index.php delete mode 100644 php/mobile/login_form.php delete mode 100644 php/mobile/logout.php delete mode 100644 php/mobile/mobile-functions.php delete mode 100644 php/mobile/mobile.css delete mode 100644 php/mobile/mobile.js delete mode 100644 php/mobile/prefs.php delete mode 100644 php/plugins/auth_imap/init.php delete mode 100644 php/plugins/digest/digest.css delete mode 100644 php/plugins/digest/digest.js delete mode 100644 php/plugins/digest/digest_body.php delete mode 100644 php/plugins/digest/images/tile.png delete mode 100644 php/plugins/digest/init.php create mode 100644 php/plugins/embed_original/button.png create mode 100644 php/plugins/embed_original/init.css create mode 100644 php/plugins/embed_original/init.js create mode 100644 php/plugins/embed_original/init.php delete mode 100644 php/plugins/example/example.js delete mode 100644 php/plugins/example/init.php delete mode 100644 php/plugins/example_article/init.php delete mode 100644 php/plugins/example_feed/init.php delete mode 100644 php/plugins/example_routing/init.php delete mode 100644 php/plugins/flattr/flattr.png delete mode 100644 php/plugins/flattr/init.php delete mode 100644 php/plugins/googleplus/googleplus.js delete mode 100644 php/plugins/googleplus/googleplus.png delete mode 100644 php/plugins/googleplus/init.php create mode 100644 php/plugins/googlereaderimport/init.js create mode 100644 php/plugins/googlereaderimport/init.php delete mode 100644 php/plugins/identica/identica.js delete mode 100644 php/plugins/identica/identica.png delete mode 100644 php/plugins/identica/init.php create mode 100644 php/plugins/index.html create mode 100644 php/plugins/mailto/init.js create mode 100644 php/plugins/mailto/init.php create mode 100644 php/plugins/mailto/mail.png create mode 100644 php/plugins/mark_button/init.php delete mode 100644 php/plugins/owncloud/init.php delete mode 100644 php/plugins/owncloud/owncloud.js delete mode 100644 php/plugins/owncloud/owncloud.png delete mode 100644 php/plugins/pinterest/init.php delete mode 100644 php/plugins/pinterest/pinterest.js delete mode 100644 php/plugins/pinterest/pinterest.png delete mode 100644 php/plugins/pocket/init.php delete mode 100644 php/plugins/pocket/pocket.js delete mode 100644 php/plugins/pocket/pocket.png create mode 100644 php/prefs.css create mode 100644 php/schema/.htaccess create mode 100644 php/schema/versions/mysql/104.sql create mode 100644 php/schema/versions/mysql/105.sql create mode 100644 php/schema/versions/mysql/106.sql create mode 100644 php/schema/versions/mysql/107.sql create mode 100644 php/schema/versions/mysql/108.sql create mode 100644 php/schema/versions/mysql/109.sql create mode 100644 php/schema/versions/mysql/110.sql create mode 100644 php/schema/versions/mysql/111.sql create mode 100644 php/schema/versions/mysql/112.sql create mode 100644 php/schema/versions/mysql/113.sql create mode 100644 php/schema/versions/mysql/114.sql create mode 100644 php/schema/versions/mysql/115.sql create mode 100644 php/schema/versions/mysql/116.sql create mode 100644 php/schema/versions/mysql/117.sql create mode 100644 php/schema/versions/mysql/118.sql create mode 100644 php/schema/versions/mysql/119.sql create mode 100644 php/schema/versions/mysql/120.sql create mode 100644 php/schema/versions/pgsql/104.sql create mode 100644 php/schema/versions/pgsql/105.sql create mode 100644 php/schema/versions/pgsql/106.sql create mode 100644 php/schema/versions/pgsql/107.sql create mode 100644 php/schema/versions/pgsql/108.sql create mode 100644 php/schema/versions/pgsql/109.sql create mode 100644 php/schema/versions/pgsql/110.sql create mode 100644 php/schema/versions/pgsql/111.sql create mode 100644 php/schema/versions/pgsql/112.sql create mode 100644 php/schema/versions/pgsql/113.sql create mode 100644 php/schema/versions/pgsql/114.sql create mode 100644 php/schema/versions/pgsql/115.sql create mode 100644 php/schema/versions/pgsql/116.sql create mode 100644 php/schema/versions/pgsql/117.sql create mode 100644 php/schema/versions/pgsql/118.sql create mode 100644 php/schema/versions/pgsql/119.sql create mode 100644 php/schema/versions/pgsql/120.sql create mode 100644 php/templates/.htaccess create mode 100644 php/themes/.empty create mode 100644 php/themes/default.css create mode 100644 php/utils/.htaccess delete mode 100755 php/utils/create-release-deb.sh delete mode 100755 php/utils/create-release-tarball.sh delete mode 100755 php/utils/update-schema-translations.sh diff --git a/php/.htaccess b/php/.htaccess new file mode 100644 index 0000000..22b33f0 --- /dev/null +++ b/php/.htaccess @@ -0,0 +1,3 @@ +AddType image/svg+xml svg +AddType image/svg+xml svgz + diff --git a/php/.settings/.jsdtscope b/php/.settings/.jsdtscope deleted file mode 100644 index f5d6a6f..0000000 --- a/php/.settings/.jsdtscope +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/php/.settings/org.eclipse.php.core.prefs b/php/.settings/org.eclipse.php.core.prefs deleted file mode 100644 index ffae6c3..0000000 --- a/php/.settings/org.eclipse.php.core.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Sat Dec 10 20:07:32 MSK 2011 -eclipse.preferences.version=1 -include_path=0;/tt-rss diff --git a/php/.settings/org.eclipse.wst.jsdt.ui.superType.container b/php/.settings/org.eclipse.wst.jsdt.ui.superType.container deleted file mode 100644 index 3bd5d0a..0000000 --- a/php/.settings/org.eclipse.wst.jsdt.ui.superType.container +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/php/.settings/org.eclipse.wst.jsdt.ui.superType.name b/php/.settings/org.eclipse.wst.jsdt.ui.superType.name deleted file mode 100644 index 05bd71b..0000000 --- a/php/.settings/org.eclipse.wst.jsdt.ui.superType.name +++ /dev/null @@ -1 +0,0 @@ -Window \ No newline at end of file diff --git a/php/api/index.php b/php/api/index.php index 1471579..facdf82 100644 --- a/php/api/index.php +++ b/php/api/index.php @@ -11,12 +11,16 @@ chdir(".."); define('TTRSS_SESSION_NAME', 'ttrss_api_sid'); + define('NO_SESSION_AUTOSTART', true); + require_once "autoload.php"; require_once "db.php"; require_once "db-prefs.php"; require_once "functions.php"; require_once "sessions.php"; + ini_set("session.gc_maxlifetime", 86400); + define('AUTH_DISABLE_OTP', true); if (defined('ENABLE_GZIP_OUTPUT') && ENABLE_GZIP_OUTPUT && @@ -27,8 +31,6 @@ function_exists("ob_gzhandler")) { ob_start(); } - $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); - $input = file_get_contents("php://input"); if (defined('_API_DEBUG_HTTP_ENABLED') && _API_DEBUG_HTTP_ENABLED) { @@ -46,15 +48,16 @@ function_exists("ob_gzhandler")) { if ($_REQUEST["sid"]) { session_id($_REQUEST["sid"]); + @session_start(); + } else if (defined('_API_DEBUG_HTTP_ENABLED')) { + @session_start(); } - @session_start(); - - if (!init_connection($link)) return; + if (!init_plugins()) return; $method = strtolower($_REQUEST["op"]); - $handler = new API($link, $_REQUEST); + $handler = new API($_REQUEST); if ($handler->before($method)) { if ($method && method_exists($handler, $method)) { @@ -65,8 +68,6 @@ function_exists("ob_gzhandler")) { $handler->after(); } - db_close($link); - header("Api-Content-Length: " . ob_get_length()); ob_end_flush(); diff --git a/php/atom-to-html.xsl b/php/atom-to-html.xsl index 2cc4665..097b07f 100644 --- a/php/atom-to-html.xsl +++ b/php/atom-to-html.xsl @@ -41,7 +41,6 @@

Extra...

-
diff --git a/php/backend.php b/php/backend.php index 41481a9..84abc97 100644 --- a/php/backend.php +++ b/php/backend.php @@ -37,21 +37,18 @@ function stripslashes_deep($value) { @$csrf_token = $_REQUEST['csrf_token']; + require_once "autoload.php"; require_once "sessions.php"; require_once "functions.php"; require_once "config.php"; require_once "db.php"; require_once "db-prefs.php"; - no_cache_incantation(); - startup_gettext(); $script_started = microtime(true); - $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); - - if (!init_connection($link)) return; + if (!init_plugins()) return; header("Content-Type: text/json; charset=utf-8"); @@ -60,11 +57,16 @@ function stripslashes_deep($value) { } if (SINGLE_USER_MODE) { - authenticate_user($link, "admin", null); + authenticate_user( "admin", null); } if ($_SESSION["uid"]) { - load_user_plugins($link, $_SESSION["uid"]); + if (!validate_session()) { + header("Content-Type: text/json"); + print json_encode(array("error" => array("code" => 6))); + return; + } + load_user_plugins( $_SESSION["uid"]); } $purge_intervals = array( @@ -102,7 +104,7 @@ function stripslashes_deep($value) { 5 => __("Power User"), 10 => __("Administrator")); - #$error = sanity_check($link); + #$error = sanity_check(); #if ($error['code'] != 0 && $op != "logout") { # print json_encode(array("error" => $error)); @@ -111,15 +113,14 @@ function stripslashes_deep($value) { $op = str_replace("-", "_", $op); - global $pluginhost; - $override = $pluginhost->lookup_handler($op, $method); + $override = PluginHost::getInstance()->lookup_handler($op, $method); if (class_exists($op) || $override) { if ($override) { $handler = $override; } else { - $handler = new $op($link, $_REQUEST); + $handler = new $op($_REQUEST); } if ($handler && implements_interface($handler, 'IHandler')) { @@ -150,6 +151,4 @@ function stripslashes_deep($value) { header("Content-Type: text/json"); print json_encode(array("error" => array("code" => 7))); - // We close the connection to database. - db_close($link); ?> diff --git a/php/cache/.htaccess b/php/cache/.htaccess old mode 100644 new mode 100755 diff --git a/php/cache/images/.empty b/php/cache/images/.empty old mode 100644 new mode 100755 diff --git a/php/cache/magpie/.empty b/php/cache/js/.empty old mode 100644 new mode 100755 similarity index 100% rename from php/cache/magpie/.empty rename to php/cache/js/.empty diff --git a/php/cache/simplepie/.empty b/php/cache/simplepie/.empty old mode 100644 new mode 100755 diff --git a/php/plugins/example_article/init.js b/php/cache/upload/.empty similarity index 100% rename from php/plugins/example_article/init.js rename to php/cache/upload/.empty diff --git a/php/cdm.css b/php/cdm.css index 83de011..6028c6e 100644 --- a/php/cdm.css +++ b/php/cdm.css @@ -22,6 +22,9 @@ div.cdmHeader > span { div.cdmHeader span.updated { color : gray; font-weight : normal; + font-size : 11px; + white-space : nowrap; + vertical-align : middle; } div.cdmHeader input { @@ -42,10 +45,6 @@ div.cdmHeader img, div.cdmFooter img { margin : 0px 2px 0px 2px; } -div.cdmContent, div.cdmContentInner * { - font-weight : normal; -} - div.cdmContent a { color : #4684ff; } @@ -55,24 +54,95 @@ div.cdmContent a:hover { } div.cdmContentInner { - margin : 0px 10px 10px 10px; + margin : 10px; + line-height : 20px; } div.cdmContentInner img { border-width : 0px; max-width : 98%; + height : auto; } div.cdmFooter { - background : #f9f9f9; padding : 5px; font-weight : normal; color : gray; clear : both; } -.Selected div.cdmFooter { - background-color : #FFF2BF; +div.cdm.expanded { + margin-top : 4px; + margin-bottom : 4px; +} + +div.cdm.expandable { + background-color : #f0f0f0; + border-width : 0px 0px 1px 0px; + border-color : #c0c0c0; + border-style : solid; +} + +div.cdm.expandable > hr { + display : none; +} + +div.cdm.expanded > hr { + margin-top : 0px; + margin-bottom : 0px; +} + +div.cdm.Unread { + background : white; +} + +div.cdm.active { + border-color : #88b0f0; + background : white ! important; +} + +div.cdm.expandable div.cdmHeader a.title { + font-weight : bold; + color : gray; +} + +div.cdm.expandable.Unread div.cdmHeader a.title { + color : black; +} + +div.cdm.expandable.active div.cdmHeader a.title { + color : #4684ff; +} + +div.cdm.expanded div.cdmHeader { + background : transparent ! important; +} + +div.cdm.expanded div.cdmHeader a.title { + font-size : 14px; + color : gray; + font-weight : bold; +} + + +div.cdm.expanded.active div.cdmHeader a.title { + color : #4684ff; +} + +div.cdm.expanded.Unread div.cdmHeader a.title { + color : black; +} + +div.cdm.expanded div.cdmContent { + color : gray; +} + +div.cdm.expanded.Unread div.cdmContent { + color : black; +} + +div.cdm.active div.cdmContent { + color : black; } span.cdmExcerpt { @@ -96,11 +166,52 @@ div.cdmFeedTitle { background-repeat : repeat-x; } -div.articleNote { - border-style : dashed none dashed none; +div.cdmFeedTitle a.title { + color : gray; + font-style : italic; + font-weight : bold; +} + +div.cdmFeedTitle a { + color : gray; +} + +div.cdmFeedTitle a:hover { + color : #4684ff; } div.cdmHeader span.hlFeed { float : right; font-weight : normal; + font-style : italic; } + +div.cdmHeader div.hlFeed, div.cdmHeader div.hlFeed a { + vertical-align : middle; + color : gray; + font-weight : normal; + font-style : italic; + font-size : 11px; +} + +div.cdm .hlFeed a { + border-radius : 4px; + display : inline-block; + padding : 1px 4px 1px 4px; +} + +div.cdmContentInner p { + max-width : 650px; +} + +div.cdmContentInner iframe { + min-width : 50%; +} + +div.cdmHeader span.author { + color : gray; + font-size : 11px; + font-weight : normal; +} + + diff --git a/php/classes/.htaccess b/php/classes/.htaccess new file mode 100644 index 0000000..93169e4 --- /dev/null +++ b/php/classes/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/php/classes/api.php b/php/classes/api.php index 4b24b01..f5e4a0c 100644 --- a/php/classes/api.php +++ b/php/classes/api.php @@ -2,7 +2,7 @@ class API extends Handler { - const API_LEVEL = 4; + const API_LEVEL = 6; const STATUS_OK = 0; const STATUS_ERR = 1; @@ -14,12 +14,12 @@ function before($method) { header("Content-Type: text/json"); if (!$_SESSION["uid"] && $method != "login" && $method != "isloggedin") { - print $this->wrap(self::STATUS_ERR, array("error" => 'NOT_LOGGED_IN')); + $this->wrap(self::STATUS_ERR, array("error" => 'NOT_LOGGED_IN')); return false; } - if ($_SESSION["uid"] && $method != "logout" && !get_pref($this->link, 'ENABLE_API_ACCESS')) { - print $this->wrap(self::STATUS_ERR, array("error" => 'API_DISABLED')); + if ($_SESSION["uid"] && $method != "logout" && !get_pref('ENABLE_API_ACCESS')) { + $this->wrap(self::STATUS_ERR, array("error" => 'API_DISABLED')); return false; } @@ -38,90 +38,94 @@ function wrap($status, $reply) { function getVersion() { $rv = array("version" => VERSION); - print $this->wrap(self::STATUS_OK, $rv); + $this->wrap(self::STATUS_OK, $rv); } function getApiLevel() { $rv = array("level" => self::API_LEVEL); - print $this->wrap(self::STATUS_OK, $rv); + $this->wrap(self::STATUS_OK, $rv); } function login() { - $login = db_escape_string($_REQUEST["user"]); + @session_destroy(); + @session_start(); + + $login = $this->dbh->escape_string($_REQUEST["user"]); $password = $_REQUEST["password"]; $password_base64 = base64_decode($_REQUEST["password"]); if (SINGLE_USER_MODE) $login = "admin"; - $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE login = '$login'"); + $result = $this->dbh->query("SELECT id FROM ttrss_users WHERE login = '$login'"); - if (db_num_rows($result) != 0) { - $uid = db_fetch_result($result, 0, "id"); + if ($this->dbh->num_rows($result) != 0) { + $uid = $this->dbh->fetch_result($result, 0, "id"); } else { $uid = 0; } if (!$uid) { - print $this->wrap(self::STATUS_ERR, array("error" => "LOGIN_ERROR")); + $this->wrap(self::STATUS_ERR, array("error" => "LOGIN_ERROR")); return; } - if (get_pref($this->link, "ENABLE_API_ACCESS", $uid)) { - if (authenticate_user($this->link, $login, $password)) { // try login with normal password - print $this->wrap(self::STATUS_OK, array("session_id" => session_id(), + if (get_pref("ENABLE_API_ACCESS", $uid)) { + if (authenticate_user($login, $password)) { // try login with normal password + $this->wrap(self::STATUS_OK, array("session_id" => session_id(), "api_level" => self::API_LEVEL)); - } else if (authenticate_user($this->link, $login, $password_base64)) { // else try with base64_decoded password - print $this->wrap(self::STATUS_OK, array("session_id" => session_id(), + } else if (authenticate_user($login, $password_base64)) { // else try with base64_decoded password + $this->wrap(self::STATUS_OK, array("session_id" => session_id(), "api_level" => self::API_LEVEL)); } else { // else we are not logged in - print $this->wrap(self::STATUS_ERR, array("error" => "LOGIN_ERROR")); + $this->wrap(self::STATUS_ERR, array("error" => "LOGIN_ERROR")); } } else { - print $this->wrap(self::STATUS_ERR, array("error" => "API_DISABLED")); + $this->wrap(self::STATUS_ERR, array("error" => "API_DISABLED")); } } function logout() { logout_user(); - print $this->wrap(self::STATUS_OK, array("status" => "OK")); + $this->wrap(self::STATUS_OK, array("status" => "OK")); } function isLoggedIn() { - print $this->wrap(self::STATUS_OK, array("status" => $_SESSION["uid"] != '')); + $this->wrap(self::STATUS_OK, array("status" => $_SESSION["uid"] != '')); } function getUnread() { - $feed_id = db_escape_string($_REQUEST["feed_id"]); - $is_cat = db_escape_string($_REQUEST["is_cat"]); + $feed_id = $this->dbh->escape_string($_REQUEST["feed_id"]); + $is_cat = $this->dbh->escape_string($_REQUEST["is_cat"]); if ($feed_id) { - print $this->wrap(self::STATUS_OK, array("unread" => getFeedUnread($this->link, $feed_id, $is_cat))); + $this->wrap(self::STATUS_OK, array("unread" => getFeedUnread($feed_id, $is_cat))); } else { - print $this->wrap(self::STATUS_OK, array("unread" => getGlobalUnread($this->link))); + $this->wrap(self::STATUS_OK, array("unread" => getGlobalUnread())); } } /* Method added for ttrss-reader for Android */ function getCounters() { - print $this->wrap(self::STATUS_OK, getAllCounters($this->link)); + $this->wrap(self::STATUS_OK, getAllCounters()); } function getFeeds() { - $cat_id = db_escape_string($_REQUEST["cat_id"]); - $unread_only = (bool)db_escape_string($_REQUEST["unread_only"]); - $limit = (int) db_escape_string($_REQUEST["limit"]); - $offset = (int) db_escape_string($_REQUEST["offset"]); - $include_nested = (bool)db_escape_string($_REQUEST["include_nested"]); + $cat_id = $this->dbh->escape_string($_REQUEST["cat_id"]); + $unread_only = sql_bool_to_bool($_REQUEST["unread_only"]); + $limit = (int) $this->dbh->escape_string($_REQUEST["limit"]); + $offset = (int) $this->dbh->escape_string($_REQUEST["offset"]); + $include_nested = sql_bool_to_bool($_REQUEST["include_nested"]); - $feeds = $this->api_get_feeds($this->link, $cat_id, $unread_only, $limit, $offset, $include_nested); + $feeds = $this->api_get_feeds($cat_id, $unread_only, $limit, $offset, $include_nested); - print $this->wrap(self::STATUS_OK, $feeds); + $this->wrap(self::STATUS_OK, $feeds); } function getCategories() { - $unread_only = (bool)db_escape_string($_REQUEST["unread_only"]); - $enable_nested = (bool)db_escape_string($_REQUEST["enable_nested"]); + $unread_only = sql_bool_to_bool($_REQUEST["unread_only"]); + $enable_nested = sql_bool_to_bool($_REQUEST["enable_nested"]); + $include_empty = sql_bool_to_bool($_REQUEST['include_empty']); // TODO do not return empty categories, return Uncategorized and standard virtual cats @@ -130,22 +134,25 @@ function getCategories() { else $nested_qpart = "true"; - $result = db_query($this->link, "SELECT + $result = $this->dbh->query("SELECT id, title, order_id, (SELECT COUNT(id) FROM ttrss_feeds WHERE - ttrss_feed_categories.id IS NOT NULL AND cat_id = ttrss_feed_categories.id) AS num_feeds + ttrss_feed_categories.id IS NOT NULL AND cat_id = ttrss_feed_categories.id) AS num_feeds, + (SELECT COUNT(id) FROM + ttrss_feed_categories AS c2 WHERE + c2.parent_cat = ttrss_feed_categories.id) AS num_cats FROM ttrss_feed_categories WHERE $nested_qpart AND owner_uid = " . $_SESSION["uid"]); $cats = array(); - while ($line = db_fetch_assoc($result)) { - if ($line["num_feeds"] > 0) { - $unread = getFeedUnread($this->link, $line["id"], true); + while ($line = $this->dbh->fetch_assoc($result)) { + if ($include_empty || $line["num_feeds"] > 0 || $line["num_cats"] > 0) { + $unread = getFeedUnread($line["id"], true); if ($enable_nested) - $unread += getCategoryChildrenUnread($this->link, $line["id"]); + $unread += getCategoryChildrenUnread($line["id"]); if ($unread || !$unread_only) { array_push($cats, array("id" => $line["id"], @@ -158,60 +165,71 @@ function getCategories() { } foreach (array(-2,-1,0) as $cat_id) { - $unread = getFeedUnread($this->link, $cat_id, true); + if ($include_empty || !$this->isCategoryEmpty($cat_id)) { + $unread = getFeedUnread($cat_id, true); - if ($unread || !$unread_only) { - array_push($cats, array("id" => $cat_id, - "title" => getCategoryTitle($this->link, $cat_id), - "unread" => $unread)); + if ($unread || !$unread_only) { + array_push($cats, array("id" => $cat_id, + "title" => getCategoryTitle($cat_id), + "unread" => $unread)); + } } } - print $this->wrap(self::STATUS_OK, $cats); + $this->wrap(self::STATUS_OK, $cats); } function getHeadlines() { - $feed_id = db_escape_string($_REQUEST["feed_id"]); + $feed_id = $this->dbh->escape_string($_REQUEST["feed_id"]); if ($feed_id != "") { - $limit = (int)db_escape_string($_REQUEST["limit"]); + $limit = (int)$this->dbh->escape_string($_REQUEST["limit"]); - if (!$limit || $limit >= 60) $limit = 60; + if (!$limit || $limit >= 200) $limit = 200; - $offset = (int)db_escape_string($_REQUEST["skip"]); - $filter = db_escape_string($_REQUEST["filter"]); - $is_cat = (bool)db_escape_string($_REQUEST["is_cat"]); - $show_excerpt = (bool)db_escape_string($_REQUEST["show_excerpt"]); - $show_content = (bool)db_escape_string($_REQUEST["show_content"]); + $offset = (int)$this->dbh->escape_string($_REQUEST["skip"]); + $filter = $this->dbh->escape_string($_REQUEST["filter"]); + $is_cat = sql_bool_to_bool($_REQUEST["is_cat"]); + $show_excerpt = sql_bool_to_bool($_REQUEST["show_excerpt"]); + $show_content = sql_bool_to_bool($_REQUEST["show_content"]); /* all_articles, unread, adaptive, marked, updated */ - $view_mode = db_escape_string($_REQUEST["view_mode"]); - $include_attachments = (bool)db_escape_string($_REQUEST["include_attachments"]); - $since_id = (int)db_escape_string($_REQUEST["since_id"]); - $include_nested = (bool)db_escape_string($_REQUEST["include_nested"]); + $view_mode = $this->dbh->escape_string($_REQUEST["view_mode"]); + $include_attachments = sql_bool_to_bool($_REQUEST["include_attachments"]); + $since_id = (int)$this->dbh->escape_string($_REQUEST["since_id"]); + $include_nested = sql_bool_to_bool($_REQUEST["include_nested"]); $sanitize_content = true; + $override_order = false; + switch ($_REQUEST["order_by"]) { + case "date_reverse": + $override_order = "date_entered, updated"; + break; + case "feed_dates": + $override_order = "updated DESC"; + break; + } + /* do not rely on params below */ - $search = db_escape_string($_REQUEST["search"]); - $search_mode = db_escape_string($_REQUEST["search_mode"]); - $match_on = db_escape_string($_REQUEST["match_on"]); + $search = $this->dbh->escape_string($_REQUEST["search"]); + $search_mode = $this->dbh->escape_string($_REQUEST["search_mode"]); - $headlines = $this->api_get_headlines($this->link, $feed_id, $limit, $offset, - $filter, $is_cat, $show_excerpt, $show_content, $view_mode, false, - $include_attachments, $since_id, $search, $search_mode, $match_on, + $headlines = $this->api_get_headlines($feed_id, $limit, $offset, + $filter, $is_cat, $show_excerpt, $show_content, $view_mode, $override_order, + $include_attachments, $since_id, $search, $search_mode, $include_nested, $sanitize_content); - print $this->wrap(self::STATUS_OK, $headlines); + $this->wrap(self::STATUS_OK, $headlines); } else { - print $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); + $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); } } function updateArticle() { - $article_ids = array_filter(explode(",", db_escape_string($_REQUEST["article_ids"])), is_numeric); - $mode = (int) db_escape_string($_REQUEST["mode"]); - $data = db_escape_string($_REQUEST["data"]); - $field_raw = (int)db_escape_string($_REQUEST["field"]); + $article_ids = array_filter(explode(",", $this->dbh->escape_string($_REQUEST["article_ids"])), is_numeric); + $mode = (int) $this->dbh->escape_string($_REQUEST["mode"]); + $data = $this->dbh->escape_string($_REQUEST["data"]); + $field_raw = (int)$this->dbh->escape_string($_REQUEST["field"]); $field = ""; $set_to = ""; @@ -219,12 +237,15 @@ function updateArticle() { switch ($field_raw) { case 0: $field = "marked"; + $additional_fields = ",last_marked = NOW()"; break; case 1: $field = "published"; + $additional_fields = ",last_published = NOW()"; break; case 2: $field = "unread"; + $additional_fields = ",last_read = NOW()"; break; case 3: $field = "note"; @@ -248,79 +269,90 @@ function updateArticle() { $article_ids = join(", ", $article_ids); - if ($field == "unread") { - $result = db_query($this->link, "UPDATE ttrss_user_entries SET $field = $set_to, - last_read = NOW() - WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]); - } else { - $result = db_query($this->link, "UPDATE ttrss_user_entries SET $field = $set_to - WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]); - } + $result = $this->dbh->query("UPDATE ttrss_user_entries SET $field = $set_to $additional_fields WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]); - $num_updated = db_affected_rows($this->link, $result); + $num_updated = $this->dbh->affected_rows($result); if ($num_updated > 0 && $field == "unread") { - $result = db_query($this->link, "SELECT DISTINCT feed_id FROM ttrss_user_entries + $result = $this->dbh->query("SELECT DISTINCT feed_id FROM ttrss_user_entries WHERE ref_id IN ($article_ids)"); - while ($line = db_fetch_assoc($result)) { - ccache_update($this->link, $line["feed_id"], $_SESSION["uid"]); + while ($line = $this->dbh->fetch_assoc($result)) { + ccache_update($line["feed_id"], $_SESSION["uid"]); } } - print $this->wrap(self::STATUS_OK, array("status" => "OK", + if ($num_updated > 0 && $field == "published") { + if (PUBSUBHUBBUB_HUB) { + $rss_link = get_self_url_prefix() . + "/public.php?op=rss&id=-2&key=" . + get_feed_access_key(-2, false); + + $p = new Publisher(PUBSUBHUBBUB_HUB); + $pubsub_result = $p->publish_update($rss_link); + } + } + + $this->wrap(self::STATUS_OK, array("status" => "OK", "updated" => $num_updated)); } else { - print $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); + $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); } } function getArticle() { - $article_id = join(",", array_filter(explode(",", db_escape_string($_REQUEST["article_id"])), is_numeric)); + $article_id = join(",", array_filter(explode(",", $this->dbh->escape_string($_REQUEST["article_id"])), is_numeric)); $query = "SELECT id,title,link,content,cached_content,feed_id,comments,int_id, - marked,unread,published, + marked,unread,published,score, ".SUBSTRING_FOR_DATE."(updated,1,16) as updated, - author + author,(SELECT title FROM ttrss_feeds WHERE id = feed_id) AS feed_title FROM ttrss_entries,ttrss_user_entries WHERE id IN ($article_id) AND ref_id = id AND owner_uid = " . $_SESSION["uid"] ; - $result = db_query($this->link, $query); + $result = $this->dbh->query($query); $articles = array(); - if (db_num_rows($result) != 0) { + if ($this->dbh->num_rows($result) != 0) { - while ($line = db_fetch_assoc($result)) { + while ($line = $this->dbh->fetch_assoc($result)) { - $attachments = get_article_enclosures($this->link, $line['id']); + $attachments = get_article_enclosures($line['id']); $article = array( "id" => $line["id"], "title" => $line["title"], "link" => $line["link"], - "labels" => get_article_labels($this->link, $line['id']), + "labels" => get_article_labels($line['id']), "unread" => sql_bool_to_bool($line["unread"]), "marked" => sql_bool_to_bool($line["marked"]), "published" => sql_bool_to_bool($line["published"]), "comments" => $line["comments"], "author" => $line["author"], - "updated" => strtotime($line["updated"]), + "updated" => (int) strtotime($line["updated"]), "content" => $line["cached_content"] != "" ? $line["cached_content"] : $line["content"], "feed_id" => $line["feed_id"], - "attachments" => $attachments + "attachments" => $attachments, + "score" => (int)$line["score"], + "feed_title" => $line["feed_title"] ); + foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_API) as $p) { + $article = $p->hook_render_article_api(array("article" => $article)); + } + + array_push($articles, $article); } } - print $this->wrap(self::STATUS_OK, $articles); + $this->wrap(self::STATUS_OK, $articles); } @@ -331,56 +363,58 @@ function getConfig() { $config["daemon_is_running"] = file_is_locked("update_daemon.lock"); - $result = db_query($this->link, "SELECT COUNT(*) AS cf FROM + $result = $this->dbh->query("SELECT COUNT(*) AS cf FROM ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"]); - $num_feeds = db_fetch_result($result, 0, "cf"); + $num_feeds = $this->dbh->fetch_result($result, 0, "cf"); $config["num_feeds"] = (int)$num_feeds; - print $this->wrap(self::STATUS_OK, $config); + $this->wrap(self::STATUS_OK, $config); } function updateFeed() { - $feed_id = db_escape_string($_REQUEST["feed_id"]); + require_once "include/rssfuncs.php"; + + $feed_id = (int) $this->dbh->escape_string($_REQUEST["feed_id"]); - update_rss_feed($this->link, $feed_id, true); + update_rss_feed($feed_id, true); - print $this->wrap(self::STATUS_OK, array("status" => "OK")); + $this->wrap(self::STATUS_OK, array("status" => "OK")); } function catchupFeed() { - $feed_id = db_escape_string($_REQUEST["feed_id"]); - $is_cat = db_escape_string($_REQUEST["is_cat"]); + $feed_id = $this->dbh->escape_string($_REQUEST["feed_id"]); + $is_cat = $this->dbh->escape_string($_REQUEST["is_cat"]); - catchup_feed($this->link, $feed_id, $is_cat); + catchup_feed($feed_id, $is_cat); - print $this->wrap(self::STATUS_OK, array("status" => "OK")); + $this->wrap(self::STATUS_OK, array("status" => "OK")); } function getPref() { - $pref_name = db_escape_string($_REQUEST["pref_name"]); + $pref_name = $this->dbh->escape_string($_REQUEST["pref_name"]); - print $this->wrap(self::STATUS_OK, array("value" => get_pref($this->link, $pref_name))); + $this->wrap(self::STATUS_OK, array("value" => get_pref($pref_name))); } function getLabels() { - //$article_ids = array_filter(explode(",", db_escape_string($_REQUEST["article_ids"])), is_numeric); + //$article_ids = array_filter(explode(",", $this->dbh->escape_string($_REQUEST["article_ids"])), is_numeric); $article_id = (int)$_REQUEST['article_id']; $rv = array(); - $result = db_query($this->link, "SELECT id, caption, fg_color, bg_color + $result = $this->dbh->query("SELECT id, caption, fg_color, bg_color FROM ttrss_labels2 WHERE owner_uid = '".$_SESSION['uid']."' ORDER BY caption"); if ($article_id) - $article_labels = get_article_labels($this->link, $article_id); + $article_labels = get_article_labels($article_id); else $article_labels = array(); - while ($line = db_fetch_assoc($result)) { + while ($line = $this->dbh->fetch_assoc($result)) { $checked = false; foreach ($article_labels as $al) { @@ -398,16 +432,16 @@ function getLabels() { "checked" => $checked)); } - print $this->wrap(self::STATUS_OK, $rv); + $this->wrap(self::STATUS_OK, $rv); } function setArticleLabel() { - $article_ids = array_filter(explode(",", db_escape_string($_REQUEST["article_ids"])), is_numeric); - $label_id = (int) db_escape_string($_REQUEST['label_id']); - $assign = (bool) db_escape_string($_REQUEST['assign']) == "true"; + $article_ids = array_filter(explode(",", $this->dbh->escape_string($_REQUEST["article_ids"])), is_numeric); + $label_id = (int) $this->dbh->escape_string($_REQUEST['label_id']); + $assign = (bool) $this->dbh->escape_string($_REQUEST['assign']) == "true"; - $label = db_escape_string(label_find_caption($this->link, + $label = $this->dbh->escape_string(label_find_caption( $label_id, $_SESSION["uid"])); $num_updated = 0; @@ -417,44 +451,53 @@ function setArticleLabel() { foreach ($article_ids as $id) { if ($assign) - label_add_article($this->link, $id, $label, $_SESSION["uid"]); + label_add_article($id, $label, $_SESSION["uid"]); else - label_remove_article($this->link, $id, $label, $_SESSION["uid"]); + label_remove_article($id, $label, $_SESSION["uid"]); ++$num_updated; } } - print $this->wrap(self::STATUS_OK, array("status" => "OK", + $this->wrap(self::STATUS_OK, array("status" => "OK", "updated" => $num_updated)); } - function index() { - print $this->wrap(self::STATUS_ERR, array("error" => 'UNKNOWN_METHOD')); + function index($method) { + $plugin = PluginHost::getInstance()->get_api_method(strtolower($method)); + + if ($plugin && method_exists($plugin, $method)) { + $reply = $plugin->$method(); + + $this->wrap($reply[0], $reply[1]); + + } else { + $this->wrap(self::STATUS_ERR, array("error" => 'UNKNOWN_METHOD', "method" => $method)); + } } function shareToPublished() { - $title = db_escape_string(strip_tags($_REQUEST["title"])); - $url = db_escape_string(strip_tags($_REQUEST["url"])); - $content = db_escape_string(strip_tags($_REQUEST["content"])); + $title = $this->dbh->escape_string(strip_tags($_REQUEST["title"])); + $url = $this->dbh->escape_string(strip_tags($_REQUEST["url"])); + $content = $this->dbh->escape_string(strip_tags($_REQUEST["content"])); - if (Article::create_published_article($this->link, $title, $url, $content, "", $_SESSION["uid"])) { - print $this->wrap(self::STATUS_OK, array("status" => 'OK')); + if (Article::create_published_article($title, $url, $content, "", $_SESSION["uid"])) { + $this->wrap(self::STATUS_OK, array("status" => 'OK')); } else { - print $this->wrap(self::STATUS_ERR, array("error" => 'Publishing failed')); + $this->wrap(self::STATUS_ERR, array("error" => 'Publishing failed')); } } - static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $include_nested = false) { + static function api_get_feeds($cat_id, $unread_only, $limit, $offset, $include_nested = false) { $feeds = array(); /* Labels */ if ($cat_id == -4 || $cat_id == -2) { - $counters = getLabelCounters($link, true); + $counters = getLabelCounters(true); foreach (array_values($counters) as $cv) { @@ -478,10 +521,10 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in if ($cat_id == -4 || $cat_id == -1) { foreach (array(-1, -2, -3, -4, -6, 0) as $i) { - $unread = getFeedUnread($link, $i); + $unread = getFeedUnread($i); if ($unread || !$unread_only) { - $title = getFeedTitle($link, $i); + $title = getFeedTitle($i); $row = array( "id" => $i, @@ -498,14 +541,14 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in /* Child cats */ if ($include_nested && $cat_id) { - $result = db_query($link, "SELECT + $result = db_query("SELECT id, title FROM ttrss_feed_categories WHERE parent_cat = '$cat_id' AND owner_uid = " . $_SESSION["uid"] . " ORDER BY id, title"); while ($line = db_fetch_assoc($result)) { - $unread = getFeedUnread($link, $line["id"], true) + - getCategoryChildrenUnread($link, $line["id"]); + $unread = getFeedUnread($line["id"], true) + + getCategoryChildrenUnread($line["id"]); if ($unread || !$unread_only) { $row = array( @@ -528,7 +571,7 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in } if ($cat_id == -4 || $cat_id == -3) { - $result = db_query($link, "SELECT + $result = db_query("SELECT id, feed_url, cat_id, title, order_id, ". SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated FROM ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"] . @@ -540,7 +583,7 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in else $cat_qpart = "cat_id IS NULL"; - $result = db_query($link, "SELECT + $result = db_query("SELECT id, feed_url, cat_id, title, order_id, ". SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated FROM ttrss_feeds WHERE @@ -550,7 +593,7 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in while ($line = db_fetch_assoc($result)) { - $unread = getFeedUnread($link, $line["id"]); + $unread = getFeedUnread($line["id"]); $has_icon = feed_has_icon($line['id']); @@ -563,7 +606,7 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in "unread" => (int)$unread, "has_icon" => $has_icon, "cat_id" => (int)$line["cat_id"], - "last_updated" => strtotime($line["last_updated"]), + "last_updated" => (int) strtotime($line["last_updated"]), "order_id" => (int) $line["order_id"], ); @@ -574,14 +617,14 @@ static function api_get_feeds($link, $cat_id, $unread_only, $limit, $offset, $in return $feeds; } - static function api_get_headlines($link, $feed_id, $limit, $offset, + static function api_get_headlines($feed_id, $limit, $offset, $filter, $is_cat, $show_excerpt, $show_content, $view_mode, $order, $include_attachments, $since_id, - $search = "", $search_mode = "", $match_on = "", + $search = "", $search_mode = "", $include_nested = false, $sanitize_content = true) { - $qfh_ret = queryFeedHeadlines($link, $feed_id, $limit, - $view_mode, $is_cat, $search, $search_mode, $match_on, + $qfh_ret = queryFeedHeadlines($feed_id, $limit, + $view_mode, $is_cat, $search, $search_mode, $order, $offset, 0, false, $since_id, $include_nested); $result = $qfh_ret[0]; @@ -596,15 +639,15 @@ static function api_get_headlines($link, $feed_id, $limit, $offset, $tags = explode(",", $line["tag_cache"]); $labels = json_decode($line["label_cache"], true); - //if (!$tags) $tags = get_article_tags($link, $line["id"]); - //if (!$labels) $labels = get_article_labels($link, $line["id"]); + //if (!$tags) $tags = get_article_tags($line["id"]); + //if (!$labels) $labels = get_article_labels($line["id"]); $headline_row = array( "id" => (int)$line["id"], "unread" => sql_bool_to_bool($line["unread"]), "marked" => sql_bool_to_bool($line["marked"]), "published" => sql_bool_to_bool($line["published"]), - "updated" => strtotime($line["updated"]), + "updated" => (int) strtotime($line["updated"]), "is_updated" => $is_updated, "title" => $line["title"], "link" => $line["link"], @@ -613,7 +656,7 @@ static function api_get_headlines($link, $feed_id, $limit, $offset, ); if ($include_attachments) - $headline_row['attachments'] = get_article_enclosures($link, + $headline_row['attachments'] = get_article_enclosures( $line['id']); if ($show_excerpt) { @@ -628,8 +671,10 @@ static function api_get_headlines($link, $feed_id, $limit, $offset, } if ($sanitize_content) { - $headline_row["content"] = sanitize($link, - $line["content_preview"], false, false, $line["site_url"]); + $headline_row["content"] = sanitize( + $line["content_preview"], + sql_bool_to_bool($line['hide_images']), + false, $line["site_url"]); } else { $headline_row["content"] = $line["content_preview"]; } @@ -640,19 +685,95 @@ static function api_get_headlines($link, $feed_id, $limit, $offset, $headline_row["labels"] = $labels; - $headline_row["feed_title"] = $line["feed_title"]; + $headline_row["feed_title"] = $line["feed_title"] ? $line["feed_title"] : + $feed_title; $headline_row["comments_count"] = (int)$line["num_comments"]; $headline_row["comments_link"] = $line["comments"]; $headline_row["always_display_attachments"] = sql_bool_to_bool($line["always_display_enclosures"]); + $headline_row["author"] = $line["author"]; + $headline_row["score"] = (int)$line["score"]; + + foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_API) as $p) { + $headline_row = $p->hook_render_article_api(array("headline" => $headline_row)); + } + array_push($headlines, $headline_row); } return $headlines; } + function unsubscribeFeed() { + $feed_id = (int) $this->dbh->escape_string($_REQUEST["feed_id"]); + + $result = $this->dbh->query("SELECT id FROM ttrss_feeds WHERE + id = '$feed_id' AND owner_uid = ".$_SESSION["uid"]); + + if ($this->dbh->num_rows($result) != 0) { + Pref_Feeds::remove_feed($feed_id, $_SESSION["uid"]); + $this->wrap(self::STATUS_OK, array("status" => "OK")); + } else { + $this->wrap(self::STATUS_ERR, array("error" => "FEED_NOT_FOUND")); + } + } + + function subscribeToFeed() { + $feed_url = $this->dbh->escape_string($_REQUEST["feed_url"]); + $category_id = (int) $this->dbh->escape_string($_REQUEST["category_id"]); + $login = $this->dbh->escape_string($_REQUEST["login"]); + $password = $this->dbh->escape_string($_REQUEST["password"]); + + if ($feed_url) { + $rc = subscribe_to_feed($feed_url, $category_id, $login, $password); + + $this->wrap(self::STATUS_OK, array("status" => $rc)); + } else { + $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); + } + } + + function getFeedTree() { + $include_empty = sql_bool_to_bool($_REQUEST['include_empty']); + + $pf = new Pref_Feeds($_REQUEST); + + $_REQUEST['mode'] = 2; + $_REQUEST['force_show_empty'] = $include_empty; + + if ($pf){ + $data = $pf->makefeedtree(); + $this->wrap(self::STATUS_OK, array("categories" => $data)); + } else { + $this->wrap(self::STATUS_ERR, array("error" => + 'UNABLE_TO_INSTANTIATE_OBJECT')); + } + + } + + // only works for labels or uncategorized for the time being + private function isCategoryEmpty($id) { + + if ($id == -2) { + $result = $this->dbh->query("SELECT COUNT(*) AS count FROM ttrss_labels2 + WHERE owner_uid = " . $_SESSION["uid"]); + + return $this->dbh->fetch_result($result, 0, "count") == 0; + + } else if ($id == 0) { + $result = $this->dbh->query("SELECT COUNT(*) AS count FROM ttrss_feeds + WHERE cat_id IS NULL AND owner_uid = " . $_SESSION["uid"]); + + return $this->dbh->fetch_result($result, 0, "count") == 0; + + } + + return false; + } + + } ?> diff --git a/php/classes/article.php b/php/classes/article.php index 2f49b18..e9f86f2 100644 --- a/php/classes/article.php +++ b/php/classes/article.php @@ -2,20 +2,20 @@ class Article extends Handler_Protected { function csrf_ignore($method) { - $csrf_ignored = array("redirect"); + $csrf_ignored = array("redirect", "editarticletags"); return array_search($method, $csrf_ignored) !== false; } function redirect() { - $id = db_escape_string($_REQUEST['id']); + $id = $this->dbh->escape_string($_REQUEST['id']); - $result = db_query($this->link, "SELECT link FROM ttrss_entries, ttrss_user_entries + $result = $this->dbh->query("SELECT link FROM ttrss_entries, ttrss_user_entries WHERE id = '$id' AND id = ref_id AND owner_uid = '".$_SESSION['uid']."' LIMIT 1"); - if (db_num_rows($result) == 1) { - $article_url = db_fetch_result($result, 0, 'link'); + if ($this->dbh->num_rows($result) == 1) { + $article_url = $this->dbh->fetch_result($result, 0, 'link'); $article_url = str_replace("\n", "", $article_url); header("Location: $article_url"); @@ -27,10 +27,10 @@ function redirect() { } function view() { - $id = db_escape_string($_REQUEST["id"]); - $cids = explode(",", db_escape_string($_REQUEST["cids"])); - $mode = db_escape_string($_REQUEST["mode"]); - $omode = db_escape_string($_REQUEST["omode"]); + $id = $this->dbh->escape_string($_REQUEST["id"]); + $cids = explode(",", $this->dbh->escape_string($_REQUEST["cids"])); + $mode = $this->dbh->escape_string($_REQUEST["mode"]); + $omode = $this->dbh->escape_string($_REQUEST["omode"]); // in prefetch mode we only output requested cids, main article // just gets marked as read (it already exists in client cache) @@ -38,26 +38,26 @@ function view() { $articles = array(); if ($mode == "") { - array_push($articles, format_article($this->link, $id, false)); + array_push($articles, format_article($id, false)); } else if ($mode == "zoom") { - array_push($articles, format_article($this->link, $id, true, true)); + array_push($articles, format_article($id, true, true)); } else if ($mode == "raw") { if ($_REQUEST['html']) { header("Content-Type: text/html"); print ''; } - $article = format_article($this->link, $id, false); + $article = format_article($id, false); print $article['content']; return; } - $this->catchupArticleById($this->link, $id, 0); + $this->catchupArticleById($id, 0); if (!$_SESSION["bw_limit"]) { foreach ($cids as $cid) { if ($cid) { - array_push($articles, format_article($this->link, $cid, false, false)); + array_push($articles, format_article($cid, false, false)); } } } @@ -65,30 +65,30 @@ function view() { print json_encode($articles); } - private function catchupArticleById($link, $id, $cmode) { + private function catchupArticleById($id, $cmode) { if ($cmode == 0) { - db_query($link, "UPDATE ttrss_user_entries SET + $this->dbh->query("UPDATE ttrss_user_entries SET unread = false,last_read = NOW() WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); } else if ($cmode == 1) { - db_query($link, "UPDATE ttrss_user_entries SET + $this->dbh->query("UPDATE ttrss_user_entries SET unread = true WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); } else { - db_query($link, "UPDATE ttrss_user_entries SET + $this->dbh->query("UPDATE ttrss_user_entries SET unread = NOT unread,last_read = NOW() WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); } - $feed_id = getArticleFeed($link, $id); - ccache_update($link, $feed_id, $_SESSION["uid"]); + $feed_id = getArticleFeed($id); + ccache_update($feed_id, $_SESSION["uid"]); } - static function create_published_article($link, $title, $url, $content, $labels_str, + static function create_published_article($title, $url, $content, $labels_str, $owner_uid) { - $guid = sha1($url . $owner_uid); // include owner_uid to prevent global GUID clash + $guid = 'SHA1:' . sha1("ttshared:" . $url . $owner_uid); // include owner_uid to prevent global GUID clash $content_hash = sha1($content); if ($labels_str != "") { @@ -104,61 +104,64 @@ static function create_published_article($link, $title, $url, $content, $labels_ if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) return false; - db_query($link, "BEGIN"); + db_query("BEGIN"); // only check for our user data here, others might have shared this with different content etc - $result = db_query($link, "SELECT id FROM ttrss_entries, ttrss_user_entries WHERE + $result = db_query("SELECT id FROM ttrss_entries, ttrss_user_entries WHERE link = '$url' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1"); if (db_num_rows($result) != 0) { $ref_id = db_fetch_result($result, 0, "id"); - $result = db_query($link, "SELECT int_id FROM ttrss_user_entries WHERE + $result = db_query("SELECT int_id FROM ttrss_user_entries WHERE ref_id = '$ref_id' AND owner_uid = '$owner_uid' LIMIT 1"); if (db_num_rows($result) != 0) { $int_id = db_fetch_result($result, 0, "int_id"); - db_query($link, "UPDATE ttrss_entries SET + db_query("UPDATE ttrss_entries SET content = '$content', content_hash = '$content_hash' WHERE id = '$ref_id'"); - db_query($link, "UPDATE ttrss_user_entries SET published = true WHERE + db_query("UPDATE ttrss_user_entries SET published = true, + last_published = NOW() WHERE int_id = '$int_id' AND owner_uid = '$owner_uid'"); } else { - db_query($link, "INSERT INTO ttrss_user_entries - (ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache, last_read, note, unread) + db_query("INSERT INTO ttrss_user_entries + (ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache, + last_read, note, unread, last_published) VALUES - ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false)"); + ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false, NOW())"); } if (count($labels) != 0) { foreach ($labels as $label) { - label_add_article($link, $ref_id, trim($label), $owner_uid); + label_add_article($ref_id, trim($label), $owner_uid); } } $rc = true; } else { - $result = db_query($link, "INSERT INTO ttrss_entries + $result = db_query("INSERT INTO ttrss_entries (title, guid, link, updated, content, content_hash, date_entered, date_updated) VALUES ('$title', '$guid', '$url', NOW(), '$content', '$content_hash', NOW(), NOW())"); - $result = db_query($link, "SELECT id FROM ttrss_entries WHERE guid = '$guid'"); + $result = db_query("SELECT id FROM ttrss_entries WHERE guid = '$guid'"); if (db_num_rows($result) != 0) { $ref_id = db_fetch_result($result, 0, "id"); - db_query($link, "INSERT INTO ttrss_user_entries - (ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache, last_read, note, unread) + db_query("INSERT INTO ttrss_user_entries + (ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache, + last_read, note, unread, last_published) VALUES - ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false)"); + ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false, NOW())"); if (count($labels) != 0) { foreach ($labels as $label) { - label_add_article($link, $ref_id, trim($label), $owner_uid); + label_add_article($ref_id, trim($label), $owner_uid); } } @@ -166,11 +169,178 @@ static function create_published_article($link, $title, $url, $content, $labels_ } } - db_query($link, "COMMIT"); + db_query("COMMIT"); return $rc; } + function editArticleTags() { + + print __("Tags for this article (separated by commas):")."
"; + + $param = $this->dbh->escape_string($_REQUEST['param']); + + $tags = get_article_tags($this->dbh->escape_string($param)); + + $tags_str = join(", ", $tags); + + print ""; + print ""; + print ""; + + print "
"; + + print " +
"; + + print "
"; + + print "
"; + + print " "; + print ""; + print "
"; + + } + + function setScore() { + $ids = $this->dbh->escape_string($_REQUEST['id']); + $score = (int)$this->dbh->escape_string($_REQUEST['score']); + + $this->dbh->query("UPDATE ttrss_user_entries SET + score = '$score' WHERE ref_id IN ($ids) AND owner_uid = " . $_SESSION["uid"]); + + print json_encode(array("id" => $ids, + "score_pic" => get_score_pic($score))); + } + + + function setArticleTags() { + + $id = $this->dbh->escape_string($_REQUEST["id"]); + + $tags_str = $this->dbh->escape_string($_REQUEST["tags_str"]); + $tags = array_unique(trim_array(explode(",", $tags_str))); + + $this->dbh->query("BEGIN"); + + $result = $this->dbh->query("SELECT int_id FROM ttrss_user_entries WHERE + ref_id = '$id' AND owner_uid = '".$_SESSION["uid"]."' LIMIT 1"); + + if ($this->dbh->num_rows($result) == 1) { + + $tags_to_cache = array(); + + $int_id = $this->dbh->fetch_result($result, 0, "int_id"); + + $this->dbh->query("DELETE FROM ttrss_tags WHERE + post_int_id = $int_id AND owner_uid = '".$_SESSION["uid"]."'"); + + foreach ($tags as $tag) { + $tag = sanitize_tag($tag); + + if (!tag_is_valid($tag)) { + continue; + } + + if (preg_match("/^[0-9]*$/", $tag)) { + continue; + } + + // print ""; + + if ($tag != '') { + $this->dbh->query("INSERT INTO ttrss_tags + (post_int_id, owner_uid, tag_name) VALUES ('$int_id', '".$_SESSION["uid"]."', '$tag')"); + } + + array_push($tags_to_cache, $tag); + } + + /* update tag cache */ + + sort($tags_to_cache); + $tags_str = join(",", $tags_to_cache); + + $this->dbh->query("UPDATE ttrss_user_entries + SET tag_cache = '$tags_str' WHERE ref_id = '$id' + AND owner_uid = " . $_SESSION["uid"]); + } + + $this->dbh->query("COMMIT"); + + $tags = get_article_tags($id); + $tags_str = format_tags_string($tags, $id); + $tags_str_full = join(", ", $tags); + + if (!$tags_str_full) $tags_str_full = __("no tags"); + + print json_encode(array("id" => (int)$id, + "content" => $tags_str, "content_full" => $tags_str_full)); + } + + + function completeTags() { + $search = $this->dbh->escape_string($_REQUEST["search"]); + + $result = $this->dbh->query("SELECT DISTINCT tag_name FROM ttrss_tags + WHERE owner_uid = '".$_SESSION["uid"]."' AND + tag_name LIKE '$search%' ORDER BY tag_name + LIMIT 10"); + + print "
    "; + while ($line = $this->dbh->fetch_assoc($result)) { + print "
  • " . $line["tag_name"] . "
  • "; + } + print "
"; + } + + function assigntolabel() { + return $this->labelops(true); + } + + function removefromlabel() { + return $this->labelops(false); + } + + private function labelops($assign) { + $reply = array(); + + $ids = explode(",", $this->dbh->escape_string($_REQUEST["ids"])); + $label_id = $this->dbh->escape_string($_REQUEST["lid"]); + + $label = $this->dbh->escape_string(label_find_caption($label_id, + $_SESSION["uid"])); + + $reply["info-for-headlines"] = array(); + + if ($label) { + + foreach ($ids as $id) { + + if ($assign) + label_add_article($id, $label, $_SESSION["uid"]); + else + label_remove_article($id, $label, $_SESSION["uid"]); + + $labels = get_article_labels($id, $_SESSION["uid"]); + + array_push($reply["info-for-headlines"], + array("id" => $id, "labels" => format_article_labels($labels, $id))); + + } + } + + $reply["message"] = "UPDATE_COUNTERS"; + + print json_encode($reply); + } + } diff --git a/php/classes/auth/base.php b/php/classes/auth/base.php index aa9d657..69acd09 100644 --- a/php/classes/auth/base.php +++ b/php/classes/auth/base.php @@ -1,9 +1,9 @@ link = $link; + function __construct() { + $this->dbh = Db::get(); } function check_password($owner_uid, $password) { @@ -16,12 +16,14 @@ function authenticate($login, $password) { // Auto-creates specified user if allowed by system configuration // Can be used instead of find_user_by_login() by external auth modules - function auto_create_user($login) { + function auto_create_user($login, $password = false) { if ($login && defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE) { $user_id = $this->find_user_by_login($login); + if (!$password) $password = make_password(); + if (!$user_id) { - $login = db_escape_string($login); + $login = $this->dbh->escape_string($login); $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); @@ -29,7 +31,7 @@ function auto_create_user($login) { (login,access_level,last_login,created,pwd_hash,salt) VALUES ('$login', 0, null, NOW(), '$pwd_hash','$salt')"; - db_query($this->link, $query); + $this->dbh->query($query); return $this->find_user_by_login($login); @@ -42,13 +44,13 @@ function auto_create_user($login) { } function find_user_by_login($login) { - $login = db_escape_string($login); + $login = $this->dbh->escape_string($login); - $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE + $result = $this->dbh->query("SELECT id FROM ttrss_users WHERE login = '$login'"); - if (db_num_rows($result) > 0) { - return db_fetch_result($result, 0, "id"); + if ($this->dbh->num_rows($result) > 0) { + return $this->dbh->fetch_result($result, 0, "id"); } else { return false; } diff --git a/php/classes/backend.php b/php/classes/backend.php index d9a7a9f..7737df0 100644 --- a/php/classes/backend.php +++ b/php/classes/backend.php @@ -11,7 +11,7 @@ function digestTest() { require_once "digest.php"; - $rv = prepare_headlines_digest($this->link, $_SESSION['uid'], 1, 1000); + $rv = prepare_headlines_digest($_SESSION['uid'], 1, 1000); $rv[3] = "
" . $rv[3] . "
"; @@ -19,8 +19,8 @@ function digestTest() { } private function display_main_help() { - $info = get_hotkeys_info($this->link); - $imap = get_hotkeys_map($this->link); + $info = get_hotkeys_info(); + $imap = get_hotkeys_map(); $omap = array(); foreach ($imap[1] as $sequence => $action) { @@ -29,6 +29,10 @@ private function display_main_help() { array_push($omap[$action], $sequence); } + print_notice("". + __("Other interface tips are available in the Tiny Tiny RSS wiki.") . + ""); + print "
    "; print "

    " . __("Keyboard Shortcuts") . "

    "; @@ -39,27 +43,46 @@ private function display_main_help() { foreach ($hotkeys as $action => $description) { - foreach ($omap[$action] as $sequence) { - if (strpos($sequence, "|") !== FALSE) { - $sequence = substr($sequence, - strpos($sequence, "|")+1, - strlen($sequence)); + if (is_array($omap[$action])) { + foreach ($omap[$action] as $sequence) { + if (strpos($sequence, "|") !== FALSE) { + $sequence = substr($sequence, + strpos($sequence, "|")+1, + strlen($sequence)); + } else { + $keys = explode(" ", $sequence); + + for ($i = 0; $i < count($keys); $i++) { + if (strlen($keys[$i]) > 1) { + $tmp = ''; + foreach (str_split($keys[$i]) as $c) { + switch ($c) { + case '*': + $tmp .= __('Shift') . '+'; + break; + case '^': + $tmp .= __('Ctrl') . '+'; + break; + default: + $tmp .= $c; + } + } + $keys[$i] = $tmp; + } + } + $sequence = join(" ", $keys); + } + + print "
  • "; + print "$sequence"; + print $description; + print "
  • "; } - - print "
  • "; - print "$sequence"; - print $description; - print "
  • "; - } } } print "
"; - - print "

". - __("Other interface tips are available in the Tiny Tiny RSS wiki.") . - "

"; } function help() { diff --git a/php/classes/db.php b/php/classes/db.php new file mode 100644 index 0000000..695ca6e --- /dev/null +++ b/php/classes/db.php @@ -0,0 +1,98 @@ +adapter = new Db_PDO(); + } else { + switch (DB_TYPE) { + case "mysql": + if (function_exists("mysqli_connect")) { + $this->adapter = new Db_Mysqli(); + } else { + $this->adapter = new Db_Mysql(); + } + break; + case "pgsql": + $this->adapter = new Db_Pgsql(); + break; + default: + die("Unknown DB_TYPE: " . DB_TYPE); + } + } + + if (!$this->adapter) die("Error initializing database adapter for " . DB_TYPE); + + $this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : ""); + + if (!$this->link) { + die("Error connecting through adapter: " . $this->adapter->last_error()); + } + + error_reporting($er); + } + + private function __clone() { + // + } + + public static function get() { + if (self::$instance == null) + self::$instance = new self(); + + return self::$instance; + } + + static function quote($str){ + return("'$str'"); + } + + function reconnect() { + $this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : ""); + } + + function connect($host, $user, $pass, $db, $port) { + //return $this->adapter->connect($host, $user, $pass, $db, $port); + return ; + } + + function escape_string($s, $strip_tags = true) { + return $this->adapter->escape_string($s, $strip_tags); + } + + function query($query, $die_on_error = true) { + return $this->adapter->query($query, $die_on_error); + } + + function fetch_assoc($result) { + return $this->adapter->fetch_assoc($result); + } + + function num_rows($result) { + return $this->adapter->num_rows($result); + } + + function fetch_result($result, $row, $param) { + return $this->adapter->fetch_result($result, $row, $param); + } + + function close() { + return $this->adapter->close(); + } + + function affected_rows($result) { + return $this->adapter->affected_rows($result); + } + + function last_error() { + return $this->adapter->last_error(); + } + +} +?> diff --git a/php/classes/db/mysql.php b/php/classes/db/mysql.php new file mode 100644 index 0000000..aab05ac --- /dev/null +++ b/php/classes/db/mysql.php @@ -0,0 +1,73 @@ +link = mysql_connect($host, $user, $pass); + + if ($this->link) { + $result = mysql_select_db($db, $this->link); + if (!$result) { + die("Can't select DB: " . mysql_error($this->link)); + } + + $this->init(); + + return $this->link; + } else { + die("Unable to connect to database (as $user to $host, database $db): " . mysql_error()); + } + } + + function escape_string($s, $strip_tags = true) { + if ($strip_tags) $s = strip_tags($s); + + return mysql_real_escape_string($s, $this->link); + } + + function query($query, $die_on_error = true) { + $result = mysql_query($query, $this->link); + if (!$result) { + user_error("Query $query failed: " . ($this->link ? mysql_error($this->link) : "No connection"), + $die_on_error ? E_USER_ERROR : E_USER_WARNING); + } + return $result; + } + + function fetch_assoc($result) { + return mysql_fetch_assoc($result); + } + + + function num_rows($result) { + return mysql_num_rows($result); + } + + function fetch_result($result, $row, $param) { + return mysql_result($result, $row, $param); + } + + function close() { + return mysql_close($this->link); + } + + function affected_rows($result) { + return mysql_affected_rows($this->link); + } + + function last_error() { + return mysql_error(); + } + + function init() { + $this->query("SET time_zone = '+0:0'"); + + if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) { + $this->query("SET NAMES " . MYSQL_CHARSET); + } + + return true; + } + +} +?> diff --git a/php/classes/db/mysqli.php b/php/classes/db/mysqli.php new file mode 100644 index 0000000..550df6f --- /dev/null +++ b/php/classes/db/mysqli.php @@ -0,0 +1,77 @@ +link = mysqli_connect($host, $user, $pass, $db, $port); + else + $this->link = mysqli_connect($host, $user, $pass, $db); + + if ($this->link) { + $this->init(); + + return $this->link; + } else { + die("Unable to connect to database (as $user to $host, database $db): " . mysqli_error()); + } + } + + function escape_string($s, $strip_tags = true) { + if ($strip_tags) $s = strip_tags($s); + + return mysqli_real_escape_string($this->link, $s); + } + + function query($query, $die_on_error = true) { + $result = mysqli_query($this->link, $query); + if (!$result) { + user_error("Query $query failed: " . ($this->link ? mysqli_error($this->link) : "No connection"), + $die_on_error ? E_USER_ERROR : E_USER_WARNING); + } + + return $result; + } + + function fetch_assoc($result) { + return mysqli_fetch_assoc($result); + } + + + function num_rows($result) { + return mysqli_num_rows($result); + } + + function fetch_result($result, $row, $param) { + if (mysqli_data_seek($result, $row)) { + $line = mysqli_fetch_assoc($result); + return $line[$param]; + } else { + return false; + } + } + + function close() { + return mysqli_close($this->link); + } + + function affected_rows($result) { + return mysqli_affected_rows($this->link); + } + + function last_error() { + return mysqli_error(); + } + + function init() { + $this->query("SET time_zone = '+0:0'"); + + if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) { + $this->query("SET NAMES " . MYSQL_CHARSET); + } + + return true; + } + +} +?> diff --git a/php/classes/db/pdo.php b/php/classes/db/pdo.php new file mode 100644 index 0000000..126f515 --- /dev/null +++ b/php/classes/db/pdo.php @@ -0,0 +1,100 @@ +pdo = new PDO($connstr, $user, $pass); + $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->init(); + } catch (PDOException $e) { + die($e->getMessage()); + } + + return $this->pdo; + } + + function escape_string($s, $strip_tags = true) { + if ($strip_tags) $s = strip_tags($s); + + $qs = $this->pdo->quote($s); + + return mb_substr($qs, 1, mb_strlen($qs)-2); + } + + function query($query, $die_on_error = true) { + try { + return new Db_Stmt($this->pdo->query($query)); + } catch (PDOException $e) { + user_error($e->getMessage(), $die_on_error ? E_USER_ERROR : E_USER_WARNING); + } + } + + function fetch_assoc($result) { + try { + if ($result) { + return $result->fetch(); + } else { + return null; + } + } catch (PDOException $e) { + user_error($e->getMessage(), E_USER_WARNING); + } + } + + function num_rows($result) { + try { + if ($result) { + return $result->rowCount(); + } else { + return false; + } + } catch (PDOException $e) { + user_error($e->getMessage(), E_USER_WARNING); + } + } + + function fetch_result($result, $row, $param) { + return $result->fetch_result($row, $param); + } + + function close() { + $this->pdo = null; + } + + function affected_rows($result) { + try { + if ($result) { + return $result->rowCount(); + } else { + return null; + } + } catch (PDOException $e) { + user_error($e->getMessage(), E_USER_WARNING); + } + } + + function last_error() { + return join(" ", $this->pdo->errorInfo()); + } + + function init() { + switch (DB_TYPE) { + case "pgsql": + $this->query("set client_encoding = 'UTF-8'"); + $this->query("set datestyle = 'ISO, european'"); + $this->query("set TIME ZONE 0"); + case "mysql": + $this->query("SET time_zone = '+0:0'"); + return; + } + + return true; + } + +} +?> diff --git a/php/classes/db/pgsql.php b/php/classes/db/pgsql.php new file mode 100644 index 0000000..4d86079 --- /dev/null +++ b/php/classes/db/pgsql.php @@ -0,0 +1,82 @@ + 0) { + $string = "$string port=" . $port; + } + + $this->link = pg_connect($string); + + if (!$this->link) { + die("Unable to connect to database (as $user to $host, database $db):" . pg_last_error()); + } + + $this->init(); + + return $this->link; + } + + function escape_string($s, $strip_tags = true) { + if ($strip_tags) $s = strip_tags($s); + + return pg_escape_string($s); + } + + function query($query, $die_on_error = true) { + $result = pg_query($query); + + if (!$result) { + $query = htmlspecialchars($query); // just in case + user_error("Query $query failed: " . ($this->link ? pg_last_error($this->link) : "No connection"), + $die_on_error ? E_USER_ERROR : E_USER_WARNING); + } + return $result; + } + + function fetch_assoc($result) { + return pg_fetch_assoc($result); + } + + + function num_rows($result) { + return pg_num_rows($result); + } + + function fetch_result($result, $row, $param) { + return pg_fetch_result($result, $row, $param); + } + + function close() { + return pg_close($this->link); + } + + function affected_rows($result) { + return pg_affected_rows($result); + } + + function last_error() { + return pg_last_error($this->link); + } + + function init() { + $this->query("set client_encoding = 'UTF-8'"); + pg_set_client_encoding("UNICODE"); + $this->query("set datestyle = 'ISO, european'"); + $this->query("set TIME ZONE 0"); + + return true; + } +} +?> diff --git a/php/classes/db/prefs.php b/php/classes/db/prefs.php new file mode 100644 index 0000000..26fb466 --- /dev/null +++ b/php/classes/db/prefs.php @@ -0,0 +1,190 @@ +dbh = Db::get(); + $this->cache = array(); + + if ($_SESSION["uid"]) $this->cache(); + } + + private function __clone() { + // + } + + public static function get() { + if (self::$instance == null) + self::$instance = new self(); + + return self::$instance; + } + + function cache() { + $profile = false; + + $user_id = $_SESSION["uid"]; + @$profile = $_SESSION["profile"]; + + if ($profile) { + $profile_qpart = "profile = '$profile' AND"; + } else { + $profile_qpart = "profile IS NULL AND"; + } + + if (get_schema_version() < 63) $profile_qpart = ""; + + $result = db_query("SELECT + value,ttrss_prefs_types.type_name as type_name,ttrss_prefs.pref_name AS pref_name + FROM + ttrss_user_prefs,ttrss_prefs,ttrss_prefs_types + WHERE + $profile_qpart + ttrss_prefs.pref_name NOT LIKE '_MOBILE%' AND + ttrss_prefs_types.id = type_id AND + owner_uid = '$user_id' AND + ttrss_user_prefs.pref_name = ttrss_prefs.pref_name"); + + while ($line = db_fetch_assoc($result)) { + if ($user_id == $_SESSION["uid"]) { + $pref_name = $line["pref_name"]; + + $this->cache[$pref_name]["type"] = $line["type_name"]; + $this->cache[$pref_name]["value"] = $line["value"]; + } + } + } + + function read($pref_name, $user_id = false, $die_on_error = false) { + + $pref_name = db_escape_string($pref_name); + $profile = false; + + if (!$user_id) { + $user_id = $_SESSION["uid"]; + @$profile = $_SESSION["profile"]; + } else { + $user_id = sprintf("%d", $user_id); + } + + if (isset($this->cache[$pref_name])) { + $tuple = $this->cache[$pref_name]; + return $this->convert($tuple["value"], $tuple["type"]); + } + + if ($profile) { + $profile_qpart = "profile = '$profile' AND"; + } else { + $profile_qpart = "profile IS NULL AND"; + } + + if (get_schema_version() < 63) $profile_qpart = ""; + + $result = db_query("SELECT + value,ttrss_prefs_types.type_name as type_name + FROM + ttrss_user_prefs,ttrss_prefs,ttrss_prefs_types + WHERE + $profile_qpart + ttrss_user_prefs.pref_name = '$pref_name' AND + ttrss_prefs_types.id = type_id AND + owner_uid = '$user_id' AND + ttrss_user_prefs.pref_name = ttrss_prefs.pref_name"); + + if (db_num_rows($result) > 0) { + $value = db_fetch_result($result, 0, "value"); + $type_name = db_fetch_result($result, 0, "type_name"); + + if ($user_id == $_SESSION["uid"]) { + $this->cache[$pref_name]["type"] = $type_name; + $this->cache[$pref_name]["value"] = $value; + } + + return $this->convert($value, $type_name); + + } else { + user_error("Fatal error, unknown preferences key: $pref_name", $die_on_error ? E_USER_ERROR : E_USER_WARNING); + return null; + } + } + + function convert($value, $type_name) { + if ($type_name == "bool") { + return $value == "true"; + } else if ($type_name == "integer") { + return (int)$value; + } else { + return $value; + } + } + + function write($pref_name, $value, $user_id = false, $strip_tags = true) { + $pref_name = db_escape_string($pref_name); + $value = db_escape_string($value, $strip_tags); + + if (!$user_id) { + $user_id = $_SESSION["uid"]; + @$profile = $_SESSION["profile"]; + } else { + $user_id = sprintf("%d", $user_id); + $prefs_cache = false; + } + + if ($profile) { + $profile_qpart = "AND profile = '$profile'"; + } else { + $profile_qpart = "AND profile IS NULL"; + } + + if (get_schema_version() < 63) $profile_qpart = ""; + + $type_name = ""; + $current_value = ""; + + if (isset($this->cache[$pref_name])) { + $type_name = $this->cache[$pref_name]["type"]; + $current_value = $this->cache[$pref_name]["value"]; + } + + if (!$type_name) { + $result = db_query("SELECT type_name + FROM ttrss_prefs,ttrss_prefs_types + WHERE pref_name = '$pref_name' AND type_id = ttrss_prefs_types.id"); + + if (db_num_rows($result) > 0) + $type_name = db_fetch_result($result, 0, "type_name"); + } else if ($current_value == $value) { + return; + } + + if ($type_name) { + if ($type_name == "bool") { + if ($value == "1" || $value == "true") { + $value = "true"; + } else { + $value = "false"; + } + } else if ($type_name == "integer") { + $value = sprintf("%d", $value); + } + + if ($pref_name == 'USER_TIMEZONE' && $value == '') { + $value = 'UTC'; + } + + db_query("UPDATE ttrss_user_prefs SET + value = '$value' WHERE pref_name = '$pref_name' + $profile_qpart + AND owner_uid = " . $_SESSION["uid"]); + + if ($user_id == $_SESSION["uid"]) { + $this->cache[$pref_name]["type"] = $type_name; + $this->cache[$pref_name]["value"] = $value; + } + } + } + +} +?> diff --git a/php/classes/db/stmt.php b/php/classes/db/stmt.php new file mode 100644 index 0000000..4d3596e --- /dev/null +++ b/php/classes/db/stmt.php @@ -0,0 +1,32 @@ +stmt = $stmt; + $this->cache = false; + } + + function fetch_result($row, $param) { + if (!$this->cache) { + $this->cache = $this->stmt->fetchAll(); + } + + if (isset($this->cache[$row])) { + return $this->cache[$row][$param]; + } else { + user_error("Unable to jump to row $row", E_USER_WARNING); + return false; + } + } + + function rowCount() { + return $this->stmt->rowCount(); + } + + function fetch() { + return $this->stmt->fetch(); + } +} +?> diff --git a/php/classes/dbupdater.php b/php/classes/dbupdater.php new file mode 100644 index 0000000..a319da0 --- /dev/null +++ b/php/classes/dbupdater.php @@ -0,0 +1,65 @@ +dbh = $dbh; + $this->db_type = $db_type; + $this->need_version = (int) $need_version; + } + + function getSchemaVersion() { + $result = db_query("SELECT schema_version FROM ttrss_version"); + return (int) db_fetch_result($result, 0, "schema_version"); + } + + function isUpdateRequired() { + return $this->getSchemaVersion() < $this->need_version; + } + + function getSchemaLines($version) { + $filename = "schema/versions/".$this->db_type."/$version.sql"; + + if (file_exists($filename)) { + return explode(";", preg_replace("/[\r\n]/", "", file_get_contents($filename))); + } else { + return false; + } + } + + function performUpdateTo($version) { + if ($this->getSchemaVersion() == $version - 1) { + + $lines = $this->getSchemaLines($version); + + if (is_array($lines)) { + + db_query("BEGIN"); + + foreach ($lines as $line) { + if (strpos($line, "--") !== 0 && $line) { + db_query($line); + } + } + + $db_version = $this->getSchemaVersion(); + + if ($db_version == $version) { + db_query("COMMIT"); + return true; + } else { + db_query("ROLLBACK"); + return false; + } + } else { + return true; + } + } else { + return false; + } + } + +} ?> diff --git a/php/classes/dlg.php b/php/classes/dlg.php index 74eb9f6..cfa960d 100644 --- a/php/classes/dlg.php +++ b/php/classes/dlg.php @@ -4,35 +4,29 @@ class Dlg extends Handler_Protected { function before($method) { if (parent::before($method)) { - header("Content-Type: text/xml; charset=utf-8"); - $this->param = db_escape_string($_REQUEST["param"]); - print ""; + header("Content-Type: text/html"); # required for iframe + + $this->param = $this->dbh->escape_string($_REQUEST["param"]); return true; } return false; } - function after() { - print ""; - } - function importOpml() { - header("Content-Type: text/html"); # required for iframe - print __("If you have imported labels and/or filters, you might need to reload preferences to see your new data.") . "

"; print "
"; $owner_uid = $_SESSION["uid"]; - db_query($this->link, "BEGIN"); + $this->dbh->query("BEGIN"); print "
    "; - $opml = new Opml($this->link, $_REQUEST); + $opml = new Opml($_REQUEST); $opml->opml_import($_SESSION["uid"]); - db_query($this->link, "COMMIT"); + $this->dbh->query("COMMIT"); print "
"; print "
"; @@ -48,127 +42,8 @@ function importOpml() { //return; } - function editPrefProfiles() { - print "
"; - - print "
". - "" . __('Select').""; - print "
"; - print "
".__('All')."
"; - print "
".__('None')."
"; - print "
"; - - print "
"; - - print " -
"; - - print "
"; - - $result = db_query($this->link, "SELECT title,id FROM ttrss_settings_profiles - WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY title"); - - print "
"; - - print "
"; - - print ""; - - print ""; #odd - - print ""; - - if (!$_SESSION["profile"]) { - $is_active = __("(active)"); - } else { - $is_active = ""; - } - - print ""; - - print ""; - - $lnum = 1; - - while ($line = db_fetch_assoc($result)) { - - $class = ($lnum % 2) ? "even" : "odd"; - - $profile_id = $line["id"]; - $this_row_id = "id=\"FCATR-$profile_id\""; - - print ""; - - $edit_title = htmlspecialchars($line["title"]); - - print ""; - - if ($_SESSION["profile"] == $line["id"]) { - $is_active = __("(active)"); - } else { - $is_active = ""; - } - - print ""; - - print ""; - - ++$lnum; - } - - print "
" . - __("Default profile") . " $is_active
" . $edit_title . - " - $is_active
"; - print "
"; - print "
"; - - print "
-
- - -
"; - - print ""; - print "
"; - - } - function pubOPMLUrl() { - print "".__('Public OPML URL').""; - print ""; print ""; - print "]]>"; //return; } function explainError() { - print "".__('Notice').""; - print ""; if ($this->param == 1) { @@ -222,231 +93,11 @@ function explainError() { __('Close this window').""; print ""; - print "]]>"; //return; } - function quickAddFeed() { - print ""; - print ""; - - print "
".__("Feed or site URL")."
"; - print "
"; - - print "
-
"; - - print ""; - - print "
"; - - if (get_pref($this->link, 'ENABLE_FEED_CATS')) { - print __('Place in category:') . " "; - print_feed_cat_select($this->link, "cat", false, 'dojoType="dijit.form.Select"'); - } - - print "
"; - - print ''; - - print ""; - - - print "
- -
"; - - print ""; - - print "
- "; - - if (!(defined('_DISABLE_FEED_BROWSER') && _DISABLE_FEED_BROWSER)) { - print ""; - } - - print " -
"; - - //return; - } - - function feedBrowser() { - if (defined('_DISABLE_FEED_BROWSER') && _DISABLE_FEED_BROWSER) return; - - $browser_search = db_escape_string($_REQUEST["search"]); - - print ""; - print ""; - - print "
-
- - - -
"; - - print " "; - - print __("limit:"); - - print " "; - - print "
"; - - $owner_uid = $_SESSION["uid"]; - - require_once "feedbrowser.php"; - - print "
    "; - print make_feed_browser($this->link, $search, 25); - print "
"; - - print "
- - -
"; - - } - - function search() { - $this->params = explode(":", db_escape_string($_REQUEST["param"]), 2); - - $active_feed_id = sprintf("%d", $this->params[0]); - $is_cat = $this->params[1] != "false"; - - print "
".__('Look for')."
"; - - print "
"; - - print ""; - - print "
".__('Limit search to:')." "; - - print ""; - - print "
"; - - print "
"; - - if (!SPHINX_ENABLED) { - print ""; - } - - print " - -
"; - } - - function editArticleTags() { - - print __("Tags for this article (separated by commas):")."
"; - - $tags = get_article_tags($this->link, $this->param); - - $tags_str = join(", ", $tags); - - print "param\">"; - print ""; - print ""; - - print "
"; - - print " -
"; - - print "
"; - - print "
"; - - print " "; - print ""; - print "
"; - - } - function printTagCloud() { - print "".__('Tag Cloud').""; - print ""; // from here: http://www.roscripts.com/Create_tag_cloud-71.html @@ -455,15 +106,15 @@ function printTagCloud() { FROM ttrss_tags WHERE owner_uid = ".$_SESSION["uid"]." GROUP BY tag_name ORDER BY count DESC LIMIT 50"; - $result = db_query($this->link, $query); + $result = $this->dbh->query($query); $tags = array(); - while ($line = db_fetch_assoc($result)) { + while ($line = $this->dbh->fetch_assoc($result)) { $tags[$line["tag_name"]] = $line["count"]; } - if( count($tags) == 0 ){ return; } + if(count($tags) == 0 ){ return; } ksort($tags); @@ -508,14 +159,10 @@ function printTagCloud() { __('Close this window').""; print ""; - print "]]>"; } function printTagSelect() { - print "" . __('Select item(s) by tags') . ""; - print ""; print ""; @@ -524,10 +171,10 @@ function printTagSelect() { print "