Merge branch 'master' into quickform
Conflicts: data/templates/bookmarks.tpl.php data/templates/sidebar.block.search.php data/templates/top.inc.php doc/developers/TODO src/SemanticScuttle/header.php
This commit is contained in:
commit
7379805565
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
dist/
|
||||
build.properties
|
||||
package.xml
|
||||
semanticscuttle-dump.sql
|
||||
|
@ -1 +1,2 @@
|
||||
sfuser=FIXME
|
||||
websitedir=FIXME
|
||||
|
239
build.xml
239
build.xml
@ -7,14 +7,30 @@
|
||||
tagging a release, running unit tests etc.
|
||||
-->
|
||||
<property file="build.properties" />
|
||||
<property file="html.properties" />
|
||||
|
||||
<property name="version-m" value="0.97" />
|
||||
<property name="version" value="0.97.0" />
|
||||
<property name="zipfile" value="${phing.project.name}-${version}.zip" />
|
||||
<property name="distfile" value="dist/${zipfile}" />
|
||||
<property name="sfproject" value="SemanticScuttle" />
|
||||
<property name="sffilepath" value="s/se/semanticscuttle/" />
|
||||
<property name="svnpath" value="https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/" />
|
||||
<property name="stability" value="beta" />
|
||||
<property name="releasenotes" value="- Many SQL optimizations
|
||||
- SemanticScuttle shows bookmarks 4 times faster now
|
||||
- New config option to skip 'SET NAMES UTF8' call: $dbneedssetnames
|
||||
- Do not highlight admin bookmarks when $enableAdminColors is disabled
|
||||
- Add russian translation
|
||||
- Make HTML export follow the specifications a bit better
|
||||
- Fix bug #2953732: faulty error message for duplicate bookmarks
|
||||
- Fix bug #2960663: do not send content-type headers twice for ajax/api scripts
|
||||
- Fix bug #2976593: fr_FR locale is vietnamese
|
||||
" />
|
||||
<property name="zipfile" value="${phing.project.name}-${version}.zip" />
|
||||
<property name="pkgfile" value="${phing.project.name}-${version}.tgz" />
|
||||
<property name="distfile" value="dist/${zipfile}" />
|
||||
<property name="distpkgfile" value="dist/pear/${pkgfile}" />
|
||||
<property name="sfproject" value="SemanticScuttle" />
|
||||
<property name="sffilepath" value="s/se/semanticscuttle/" />
|
||||
<property name="svnpath" value="https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/" />
|
||||
|
||||
<taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
|
||||
|
||||
<target name="zip" depends="check"
|
||||
description="Create zip file for release"
|
||||
@ -48,7 +64,151 @@
|
||||
|
||||
|
||||
|
||||
<target name="release" depends="check,zip,deploy-sf,svntag"
|
||||
<target name="package" depends="check"
|
||||
description="Creates the pear package"
|
||||
>
|
||||
<!-- fixme: create package.xml with d51pearpkg2 -->
|
||||
<d51pearpkg2 dir="." baseinstalldir="/">
|
||||
<name>SemanticScuttle</name>
|
||||
<summary>A social bookmarking tool</summary>
|
||||
<description>
|
||||
A social bookmarking tool experimenting with new features
|
||||
like structured tags or collaborative descriptions of tags.
|
||||
</description>
|
||||
<channel>semanticscuttle.sourceforge.net</channel>
|
||||
|
||||
<lead user="cweiske" name="Christian Weiske" email="cweiske@cweiske.de" />
|
||||
<license>GPL</license>
|
||||
|
||||
<version release="${version}" api="${version}" />
|
||||
<stability release="${stability}" api="${stability}" />
|
||||
|
||||
<notes>${releasenotes}</notes>
|
||||
|
||||
<dependencies>
|
||||
<php minimum_version="5.2.0" />
|
||||
<pear minimum_version="1.8.1" />
|
||||
|
||||
<package name="HTML_QuickForm2"
|
||||
channel="pear.php.net"
|
||||
minimum_version="0.4.0"
|
||||
/>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<!-- map directory (key) to role -->
|
||||
<dirroles key="www">www</dirroles>
|
||||
<dirroles key="data">data</dirroles>
|
||||
<dirroles key="doc">doc</dirroles>
|
||||
<dirroles key="src">php</dirroles>
|
||||
<dirroles key="tests">test</dirroles>
|
||||
|
||||
<!-- do not add the following files to the package.
|
||||
copied from excludes above -->
|
||||
<ignore>**/.gitignore</ignore>
|
||||
<ignore>**/.svn</ignore>
|
||||
<ignore>build*</ignore>
|
||||
<ignore>data/config.php</ignore>
|
||||
<ignore>data/locales/messages.po</ignore>
|
||||
<ignore>data/locales/*/LC_MESSAGES/messages.po</ignore>
|
||||
<ignore>dist/**</ignore>
|
||||
<ignore>doc/developers/**</ignore>
|
||||
<ignore>scripts/**</ignore>
|
||||
<ignore>src/php-gettext/examples/**</ignore>
|
||||
<ignore>src/php-gettext/bin/**</ignore>
|
||||
<ignore>*.tgz</ignore>
|
||||
<ignore>*.properties</ignore>
|
||||
|
||||
<replacement
|
||||
path="src/SemanticScuttle/header.php"
|
||||
type="pear-config"
|
||||
from="@data_dir@" to="data_dir"
|
||||
/>
|
||||
<replacement
|
||||
path="www/www-header.php"
|
||||
type="pear-config"
|
||||
from="@data_dir@" to="data_dir"
|
||||
/>
|
||||
<replacement
|
||||
path="tests/prepare.php"
|
||||
type="pear-config"
|
||||
from="@data_dir@" to="data_dir"
|
||||
/>
|
||||
|
||||
<changelog version="0.97" date="2010-06-09" license="GPL">
|
||||
- Many SQL optimizations - SemanticScuttle shows bookmarks 4 times faster now
|
||||
- New config option to skip "SET NAMES UTF8" call: $dbneedssetnames
|
||||
- Do not highlight admin bookmarks when $enableAdminColors is disabled
|
||||
- Add russian translation
|
||||
- Make HTML export follow the specifications a bit better
|
||||
- Fix bug #2953732: faulty error message for duplicate bookmarks
|
||||
- Fix bug #2960663: do not send content-type headers twice for ajax/api scripts
|
||||
- Fix bug #2976593: fr_FR locale is vietnamese
|
||||
</changelog>
|
||||
|
||||
<!-- <dirroles key="bin">script</dirroles> -->
|
||||
<!-- <replacement path="bin/doctrine" type="pear-config" from="@php_bin@" to="php_bin" /> -->
|
||||
<!-- <release>
|
||||
<install as="doctrine" name="bin/doctrine" />
|
||||
-->
|
||||
</d51pearpkg2>
|
||||
|
||||
<!-- time to fix the package.xml file since the task does not
|
||||
allow everything we need:
|
||||
- strip the base directory names like src, data and www
|
||||
- remove that dumb baseinstalldir from files
|
||||
- md5sums are generated automatically when packaging
|
||||
-->
|
||||
<!-- yes, we need to generate a 2nd file and move it back -->
|
||||
<copy file="package.xml" tofile="package2.xml" overwrite="true">
|
||||
<filterchain>
|
||||
<replaceregexp>
|
||||
<!-- remove md5sums -->
|
||||
<regexp
|
||||
pattern="md5sum="[a-z0-9]{32}" "
|
||||
replace=""
|
||||
/>
|
||||
<!-- remove baseinstalldir for files -->
|
||||
<regexp
|
||||
pattern="<file baseinstalldir="/""
|
||||
replace="<file"
|
||||
/>
|
||||
<!-- install-as for different directories -->
|
||||
<regexp
|
||||
pattern="(<file name="data/(.+?)")"
|
||||
replace="\1 install-as="\2""
|
||||
/>
|
||||
<regexp
|
||||
pattern="(<file name="doc/(.+?)")"
|
||||
replace="\1 install-as="\2""
|
||||
/>
|
||||
<regexp
|
||||
pattern="(<file name="tests/(.+?)")"
|
||||
replace="\1 install-as="\2""
|
||||
/>
|
||||
<regexp
|
||||
pattern="(<file name="www/(.+?)")"
|
||||
replace="\1 install-as="SemanticScuttle/\2""
|
||||
/>
|
||||
<regexp
|
||||
pattern="(<file name="src/(.+?)")"
|
||||
replace="\1 install-as="\2""
|
||||
/>
|
||||
</replaceregexp>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<move file="package2.xml" tofile="package.xml" overwrite="true" />
|
||||
|
||||
<!-- package up -->
|
||||
<exec command="pear package" passthru="true" />
|
||||
<move file="${pkgfile}" todir="dist/pear/" />
|
||||
|
||||
<delete file="package.xml" failonerror="true" />
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<target name="release" depends="check,zip,package,deploy-sf"
|
||||
description="Release the version on sourceforge"
|
||||
>
|
||||
<!-- meta-target -->
|
||||
@ -80,12 +240,69 @@
|
||||
</target>
|
||||
|
||||
|
||||
<target name="svntag"
|
||||
description="create the svn tag for the current version"
|
||||
|
||||
<target name="deploy-sf-pear" depends="check,package"
|
||||
description="Update PEAR channel on sourceforge"
|
||||
>
|
||||
<available file="${websitedir}"
|
||||
type="dir" property="available.websitedir"
|
||||
/>
|
||||
<fail unless="available.websitedir"
|
||||
message="Website directory not set"
|
||||
/>
|
||||
<!--
|
||||
1. rsync channel data from sourceforge to local, deleting
|
||||
superfluous channel files. Need to do that so pirum knows
|
||||
all previous releases when adding the new package
|
||||
2. update channel with pirum update
|
||||
3. rsync to sourceforge
|
||||
-->
|
||||
<exec
|
||||
command="svn cp ${svnpath}trunk ${svnpath}/tags/${version} -m 'tag version ${version}'"
|
||||
escape="false" checkreturn="true"
|
||||
command="rsync --include-from=.rsync-include-files --delete -avP -e ssh ${sfuser},${sfproject}@web.sourceforge.net:htdocs/ ."
|
||||
dir="${websitedir}"
|
||||
escape="false" checkreturn="false"
|
||||
passthru="true"
|
||||
/>
|
||||
|
||||
<exec
|
||||
command="pirum add ${websitedir} ${distpkgfile}"
|
||||
passthru="true"
|
||||
/>
|
||||
<!-- fix the generated html -->
|
||||
<!-- yes, we need to generate a 2nd file and move it back -->
|
||||
<copy file="${websitedir}/index.html" tofile="${websitedir}/pirum.html" overwrite="true">
|
||||
<filterchain>
|
||||
<replaceregexp>
|
||||
<!-- make meta links relative -->
|
||||
<regexp
|
||||
pattern="href="http://semanticscuttle.sourceforge.net/"
|
||||
replace="href=""
|
||||
/>
|
||||
<!-- add sourceforge logo -->
|
||||
<regexp
|
||||
pattern="powered by "
|
||||
replace="powered by ${html.sflogo} and "
|
||||
/>
|
||||
</replaceregexp>
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<!-- overwrite pirum generated index with our own -->
|
||||
<copy file="${websitedir}/our-index.html" tofile="${websitedir}/index.html" overwrite="true" />
|
||||
|
||||
<!-- add our custom css -->
|
||||
<append
|
||||
destFile="${websitedir}/pirum.css"
|
||||
file="${websitedir}/pirum-custom.css"
|
||||
/>
|
||||
|
||||
<!-- rsync always returns code 23 on sourceforge releases, so we
|
||||
can't check return values -->
|
||||
<exec
|
||||
command="rsync --include-from=.rsync-include-files -avP -e ssh . ${sfuser},${sfproject}@web.sourceforge.net:htdocs/"
|
||||
dir="${websitedir}"
|
||||
escape="false" checkreturn="false"
|
||||
passthru="true"
|
||||
/>
|
||||
</target>
|
||||
|
||||
@ -99,4 +316,4 @@
|
||||
<fail unless="sffilepath" message="Sourceforge project file path not defined!" />
|
||||
</target>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -138,7 +138,7 @@ $dbtype = 'mysql4';
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
$dbhost = 'localhost';
|
||||
$dbhost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Database port.
|
||||
@ -302,7 +302,7 @@ $index_sidebar_blocks = array(
|
||||
* @var string
|
||||
* @link http://php.net/date
|
||||
*/
|
||||
$shortdate = 'd-m-Y';
|
||||
$shortdate = 'Y-m-d';
|
||||
|
||||
/**
|
||||
* Format of long dates.
|
||||
@ -710,4 +710,12 @@ $authEmailSuffix = null;
|
||||
*/
|
||||
$unittestUrl = null;
|
||||
|
||||
/**
|
||||
* Allow "unittestMode=1" in URLs.
|
||||
* Should only be enabled on development systems
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
$allowUnittestMode = false;
|
||||
|
||||
?>
|
||||
|
@ -88,7 +88,7 @@ $dbname = 'scuttle';
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
$dbhost = 'localhost';
|
||||
$dbhost = '127.0.0.1';
|
||||
|
||||
|
||||
/***************************************************
|
||||
|
Binary file not shown.
@ -604,7 +604,7 @@ msgid ""
|
||||
"file to your computer"
|
||||
msgstr ""
|
||||
"Speichern Sie die resultierende <abbr title=\"Extensible Markup Language"
|
||||
"\">XML</abbr-Datei lokal auf Ihrem Computer"
|
||||
"\">XML</abbr>-Datei lokal auf Ihrem Computer"
|
||||
|
||||
#: data/templates/importDelicious.tpl.php:35
|
||||
msgid ""
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-11-16 20:55+0100\n"
|
||||
"POT-Creation-Date: 2010-09-15 19:15+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -17,50 +17,50 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||
|
||||
#: src/SemanticScuttle/functions.php:163
|
||||
#: src/SemanticScuttle/functions.php:189
|
||||
msgid "message_die() was called multiple times."
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:175
|
||||
#: src/SemanticScuttle/functions.php:201
|
||||
msgid "SQL Error"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:181
|
||||
#: src/SemanticScuttle/functions.php:207
|
||||
msgid "Line"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:181
|
||||
#: src/SemanticScuttle/functions.php:207
|
||||
#: data/templates/importDelicious.tpl.php:8
|
||||
#: data/templates/importNetscape.tpl.php:9
|
||||
#: data/templates/importStructure.tpl.php:10
|
||||
msgid "File"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:189
|
||||
#: src/SemanticScuttle/functions.php:215
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:194
|
||||
#: src/SemanticScuttle/functions.php:220
|
||||
msgid "Critical Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:199
|
||||
#: src/SemanticScuttle/functions.php:225
|
||||
msgid "An error occured"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:202
|
||||
#: src/SemanticScuttle/functions.php:228
|
||||
msgid "General Error"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:210
|
||||
#: src/SemanticScuttle/functions.php:236
|
||||
msgid "An critical error occured"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:213
|
||||
#: src/SemanticScuttle/functions.php:239
|
||||
msgid "Critical Error"
|
||||
msgstr ""
|
||||
|
||||
#: src/SemanticScuttle/functions.php:222
|
||||
#: src/SemanticScuttle/functions.php:248
|
||||
msgid "DEBUG MODE"
|
||||
msgstr ""
|
||||
|
||||
@ -150,7 +150,7 @@ msgstr ""
|
||||
msgid "Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/admin.tpl.php:19 data/templates/bookmarks.tpl.php:251
|
||||
#: data/templates/admin.tpl.php:19 data/templates/bookmarks.tpl.php:267
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
@ -169,12 +169,12 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarkcommondescriptionedit.tpl.php:18
|
||||
#: data/templates/bookmarks.tpl.php:137 data/templates/editbookmark.tpl.php:38
|
||||
#: data/templates/bookmarks.tpl.php:137 data/templates/editbookmark.tpl.php:43
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarkcommondescriptionedit.tpl.php:23
|
||||
#: data/templates/editbookmark.tpl.php:44
|
||||
#: data/templates/editbookmark.tpl.php:49
|
||||
#: data/templates/editprofile.tpl.php:47 data/templates/profile.tpl.php:33
|
||||
#: data/templates/tagcommondescriptionedit.tpl.php:13
|
||||
#: data/templates/tagedit.tpl.php:12
|
||||
@ -193,8 +193,8 @@ msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarkcommondescriptionedit.tpl.php:43
|
||||
#: data/templates/editbookmark.tpl.php:98 data/templates/tag2tagadd.tpl.php:24
|
||||
#: data/templates/tag2tagedit.tpl.php:38
|
||||
#: data/templates/editbookmark.tpl.php:103
|
||||
#: data/templates/tag2tagadd.tpl.php:24 data/templates/tag2tagedit.tpl.php:38
|
||||
#: data/templates/tagcommondescriptionedit.tpl.php:33
|
||||
#: data/templates/tagedit.tpl.php:19 data/templates/tagrename.tpl.php:25
|
||||
msgid "Cancel"
|
||||
@ -273,61 +273,61 @@ msgstr ""
|
||||
msgid "Page %d of %d"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:245
|
||||
#: data/templates/bookmarks.tpl.php:261
|
||||
msgid "Tags:"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:251
|
||||
#: data/templates/bookmarks.tpl.php:267
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:255
|
||||
#: data/templates/bookmarks.tpl.php:271
|
||||
msgid "Last update"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:258
|
||||
#: data/templates/bookmarks.tpl.php:274
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:260
|
||||
#: data/templates/bookmarks.tpl.php:276
|
||||
msgid "you"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:274
|
||||
#: data/templates/bookmarks.tpl.php:290
|
||||
#, php-format
|
||||
msgid " and %s1 other%s"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:277
|
||||
#: data/templates/bookmarks.tpl.php:293
|
||||
#, php-format
|
||||
msgid " and %2$s%1$s others%3$s"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:288
|
||||
#: data/templates/bookmarks.tpl.php:304
|
||||
msgid "Copy this bookmark to YOUR bookmarks."
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:289
|
||||
#: data/templates/bookmarks.tpl.php:305
|
||||
msgid "Copy"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:309
|
||||
#: data/templates/bookmarks.tpl.php:325
|
||||
msgid "This bookmark is certified by an admin user."
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:351
|
||||
#: data/templates/bookmarks.tpl.php:371
|
||||
msgid "Private Note on this bookmark"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:363
|
||||
#: data/templates/bookmarks.tpl.php:383
|
||||
msgid "Come back to the top of this page."
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:363
|
||||
#: data/templates/bookmarks.tpl.php:383
|
||||
msgid "Top of the page"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/bookmarks.tpl.php:369
|
||||
#: data/templates/bookmarks.tpl.php:389
|
||||
msgid "No bookmarks available"
|
||||
msgstr ""
|
||||
|
||||
@ -362,133 +362,133 @@ msgstr ""
|
||||
msgid "Popular Tags From All Users"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:33
|
||||
#: data/templates/editbookmark.tpl.php:38
|
||||
msgid "Address"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:35
|
||||
#: data/templates/editbookmark.tpl.php:40
|
||||
#: data/templates/editbookmark.tpl.php:45
|
||||
#: data/templates/editprofile.tpl.php:31 data/templates/tagrename.tpl.php:14
|
||||
#: data/templates/tagrename.tpl.php:19
|
||||
msgid "Required"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:45
|
||||
#: data/templates/editbookmark.tpl.php:50
|
||||
msgid "Add Note"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:48
|
||||
#: data/templates/editbookmark.tpl.php:53
|
||||
msgid ""
|
||||
"You can use anchors to delimite attributes. for example: [publisher]blah[/"
|
||||
"publisher] "
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:51
|
||||
#: data/templates/editbookmark.tpl.php:56
|
||||
msgid "Suggested anchors: "
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:63
|
||||
#: data/templates/editbookmark.tpl.php:68
|
||||
msgid "Private Note"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:65
|
||||
#: data/templates/editbookmark.tpl.php:70
|
||||
msgid "Just visible by you and your contacts."
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:69 data/templates/toolbar.inc.php:10
|
||||
#: data/templates/editbookmark.tpl.php:74 data/templates/toolbar.inc.php:10
|
||||
#: www/tags.php:45 www/tags.php:67
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:73
|
||||
#: data/templates/editbookmark.tpl.php:78
|
||||
msgid "Comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:77 data/templates/tag2tagadd.tpl.php:9
|
||||
#: data/templates/editbookmark.tpl.php:82 data/templates/tag2tagadd.tpl.php:9
|
||||
msgid ""
|
||||
"Note: use \">\" to include one tag in another. e.g.: europe>france>paris"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:81 data/templates/tag2tagadd.tpl.php:8
|
||||
#: data/templates/editbookmark.tpl.php:86 data/templates/tag2tagadd.tpl.php:8
|
||||
msgid "Note: use \"=\" to make synonym two tags. e.g.: france=frenchcountry"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:84
|
||||
#: data/templates/editbookmark.tpl.php:89
|
||||
#: data/templates/importDelicious.tpl.php:15
|
||||
#: data/templates/importNetscape.tpl.php:16
|
||||
msgid "Privacy"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:87
|
||||
#: data/templates/editbookmark.tpl.php:92
|
||||
#: data/templates/importDelicious.tpl.php:18
|
||||
#: data/templates/importNetscape.tpl.php:19
|
||||
msgid "Public"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:88
|
||||
#: data/templates/editbookmark.tpl.php:93
|
||||
msgid "Shared with Watch List"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:89
|
||||
#: data/templates/editbookmark.tpl.php:94
|
||||
#: data/templates/importDelicious.tpl.php:20
|
||||
#: data/templates/importNetscape.tpl.php:21
|
||||
msgid "Private"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:102
|
||||
#: data/templates/editbookmark.tpl.php:107
|
||||
msgid "Delete Bookmark"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:107
|
||||
#: data/templates/editbookmark.tpl.php:112
|
||||
msgid "edit common description"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:134
|
||||
#: data/templates/editbookmark.tpl.php:139
|
||||
msgid "Bookmarklet"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:140
|
||||
#: data/templates/editbookmark.tpl.php:145
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Click one of the following bookmarklets to add a button you can click "
|
||||
"whenever you want to add the page you are on to %s"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:144
|
||||
#: data/templates/editbookmark.tpl.php:149
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Drag one of the following bookmarklets to your browser's bookmarks and click "
|
||||
"it whenever you want to add the page you are on to %s"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:157
|
||||
#: data/templates/editbookmark.tpl.php:162
|
||||
#: data/templates/editbookmark.tpl.php:167
|
||||
#, php-format
|
||||
msgid "Post to %s"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:158
|
||||
#: data/templates/editbookmark.tpl.php:163
|
||||
#: data/templates/editbookmark.tpl.php:168
|
||||
#, php-format
|
||||
msgid "Post to %s (Pop-up)"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:168
|
||||
#: data/templates/editbookmark.tpl.php:173
|
||||
#: data/templates/importDelicious.tpl.php:26
|
||||
#: data/templates/importNetscape.tpl.php:27
|
||||
#: data/templates/importStructure.tpl.php:16
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:170
|
||||
#: data/templates/editbookmark.tpl.php:175
|
||||
msgid "Import bookmarks from bookmark file"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:170
|
||||
#: data/templates/editbookmark.tpl.php:175
|
||||
msgid "Internet Explorer, Mozilla Firefox and Netscape"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/editbookmark.tpl.php:171
|
||||
#: data/templates/editbookmark.tpl.php:176
|
||||
msgid "Import bookmarks from del.icio.us"
|
||||
msgstr ""
|
||||
|
||||
@ -841,7 +841,7 @@ msgid "Edit Tag Description"
|
||||
msgstr ""
|
||||
|
||||
#: data/templates/sidebar.block.tagactions.php:26
|
||||
#: www/tagcommondescriptionedit.php:64
|
||||
#: www/tagcommondescriptionedit.php:76
|
||||
msgid "Edit Tag Common Description"
|
||||
msgstr ""
|
||||
|
||||
@ -1028,12 +1028,12 @@ msgstr ""
|
||||
msgid "Failed to delete bookmark"
|
||||
msgstr ""
|
||||
|
||||
#: www/alltags.php:49
|
||||
#: www/alltags.php:50
|
||||
msgid "All Tags"
|
||||
msgstr ""
|
||||
|
||||
#: www/alltags.php:55 www/bookmarks.php:96 www/populartags.php:52
|
||||
#: www/profile.php:51 www/rss.php:67 www/search.php:109 www/watch.php:45
|
||||
#: www/alltags.php:56 www/bookmarks.php:96 www/populartags.php:52
|
||||
#: www/profile.php:51 www/rss.php:76 www/search.php:109 www/watch.php:45
|
||||
#: www/watchlist.php:61
|
||||
#, php-format
|
||||
msgid "User with username %s was not found"
|
||||
@ -1041,7 +1041,7 @@ msgstr ""
|
||||
|
||||
#: www/bookmarkcommondescriptionedit.php:51 www/tag2tagadd.php:37
|
||||
#: www/tag2tagdelete.php:41 www/tag2tagedit.php:33
|
||||
#: www/tagcommondescriptionedit.php:43 www/tagedit.php:43
|
||||
#: www/tagcommondescriptionedit.php:51 www/tagedit.php:43
|
||||
msgid "Permission denied."
|
||||
msgstr ""
|
||||
|
||||
@ -1179,11 +1179,11 @@ msgstr ""
|
||||
msgid "%s: Recent bookmarks"
|
||||
msgstr ""
|
||||
|
||||
#: www/index.php:78
|
||||
#: www/index.php:75
|
||||
msgid "Store, share and tag your favourite links"
|
||||
msgstr ""
|
||||
|
||||
#: www/index.php:79
|
||||
#: www/index.php:76
|
||||
msgid "All Bookmarks"
|
||||
msgstr ""
|
||||
|
||||
@ -1313,7 +1313,7 @@ msgstr ""
|
||||
msgid "Registration failed. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: www/rss.php:84
|
||||
#: www/rss.php:93
|
||||
#, php-format
|
||||
msgid "Recent bookmarks posted to %s"
|
||||
msgstr ""
|
||||
@ -1358,11 +1358,11 @@ msgstr ""
|
||||
msgid "Edit Link Between Tags"
|
||||
msgstr ""
|
||||
|
||||
#: www/tagcommondescriptionedit.php:55
|
||||
#: www/tagcommondescriptionedit.php:62
|
||||
msgid "Tag common description updated"
|
||||
msgstr ""
|
||||
|
||||
#: www/tagcommondescriptionedit.php:58
|
||||
#: www/tagcommondescriptionedit.php:67
|
||||
msgid "Failed to update the tag common description"
|
||||
msgstr ""
|
||||
|
||||
|
@ -11,7 +11,7 @@ foreach($users as $user) {
|
||||
|
||||
echo '<div class="link">';
|
||||
echo '<a href="'.createURL('profile', $user->getUsername()).'">'.$user->getUsername().'</a>';
|
||||
echo ' - <span title='. T_('Public/Shared/Private') .'>'. $user->getNbBookmarks('public') .' / '. $user->getNbBookmarks('shared') .' / '. $user->getNbBookmarks('private') .' '. T_('bookmark(s)') .'</span>';
|
||||
echo ' - <span title="'. T_('Public/Shared/Private') .'">'. $user->getNbBookmarks('public') .' / '. $user->getNbBookmarks('shared') .' / '. $user->getNbBookmarks('private') .' '. T_('bookmark(s)') .'</span>';
|
||||
echo '</div>';
|
||||
|
||||
if($user->getUsername() != $currentUser->getUsername()) {
|
||||
|
@ -30,7 +30,8 @@ window.onload = function() {
|
||||
if(strlen($description['cdDatetime'])>0) {
|
||||
echo T_('Last modification:').' '.$description['cdDatetime'].', ';
|
||||
$lastUser = $userservice->getUser($description['uId']);
|
||||
echo '<a href="'.createURL('profile', $lastUser['username']).'">'.$lastUser['username'].'</a>';
|
||||
echo '<a href="'.createURL('profile', $lastUser['username']).'">'
|
||||
. SemanticScuttle_Model_UserArray::getName($lastUser) . '</a>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
117
data/templates/bookmarklet.inc.php
Normal file
117
data/templates/bookmarklet.inc.php
Normal file
@ -0,0 +1,117 @@
|
||||
<h3><?php echo T_('Bookmarklet'); ?></h3>
|
||||
<p id="bookmarklet"></p>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var browser = navigator.appName;
|
||||
jQuery(function($) {
|
||||
if (browser == "Opera") {
|
||||
$('#bookmarklet').append(
|
||||
<?php echo json_encode(
|
||||
sprintf(
|
||||
T_("Click one of the following bookmarklets to add a button you can click whenever you want to add the page you are on to %s") . ':',
|
||||
$GLOBALS['sitename']
|
||||
)
|
||||
); ?>
|
||||
);
|
||||
} else {
|
||||
$('#bookmarklet').append(
|
||||
<?php echo json_encode(
|
||||
sprintf(
|
||||
T_("Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s") . ':',
|
||||
$GLOBALS['sitename']
|
||||
)
|
||||
);
|
||||
?>
|
||||
);
|
||||
}
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var selection = '';
|
||||
if (window.getSelection) {
|
||||
selection = 'window.getSelection()';
|
||||
} else if (document.getSelection) {
|
||||
selection = 'document.getSelection()';
|
||||
} else if (document.selection) {
|
||||
selection = 'document.selection.createRange().text';
|
||||
}
|
||||
if (browser == "Opera") {
|
||||
$('#bookmarklet').append(
|
||||
'<ul>'
|
||||
+ '<li>'
|
||||
+ '<a class="bookmarklet" href="'
|
||||
+ '<?php
|
||||
$popupLink = 'javascript:'
|
||||
. "location.href='"
|
||||
. createURL('bookmarks', $GLOBALS['user'])
|
||||
. '?action=add'
|
||||
. "&address='+encodeURIComponent(document.location.href)+'"
|
||||
. "&title='+encodeURIComponent(document.title)+'"
|
||||
. "&description='+encodeURIComponent(SELECTION)"
|
||||
. ";";
|
||||
$link = 'opera:/button/'
|
||||
//Opera command
|
||||
. 'Go to page'
|
||||
//command parameter 1
|
||||
. ',"' . rawurlencode($popupLink) . '"'
|
||||
//command parameter 2
|
||||
. ','
|
||||
//button title
|
||||
. ',"Post to ' . fixOperaButtonName($GLOBALS['sitename']) . '"'
|
||||
//button icon name
|
||||
. ',"Scuttle"';
|
||||
echo jsEscTitle(htmlspecialchars($link));
|
||||
?>'.replace('SELECTION', selection)
|
||||
+ '"><?php echo jsEscTitle(sprintf(T_('Post to %s'), $GLOBALS['sitename'])); ?></a>'
|
||||
+ '</li>'
|
||||
+ '<li>'
|
||||
+ '<a class="bookmarklet" href="'
|
||||
+ '<?php
|
||||
$popupLink = 'javascript:'
|
||||
. 'open('
|
||||
. "'" . createURL('bookmarks', $GLOBALS['user'])
|
||||
. '?action=add'
|
||||
. '&popup=1'
|
||||
. "&address='+encodeURIComponent(document.location.href)+'"
|
||||
. "&title='+encodeURIComponent(document.title)+'"
|
||||
. "&description='+encodeURIComponent(SELECTION)"
|
||||
. ","
|
||||
. "'" . htmlspecialchars(jsEscTitle($GLOBALS['sitename'])) . "',"
|
||||
. "'modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465"
|
||||
. ",left='+(screen.width-790)/2+',top='+(screen.height-425)/2"
|
||||
. ");void 0";
|
||||
$link = 'opera:/button/'
|
||||
. 'Go to page'
|
||||
. ',"' . rawurlencode($popupLink) . '"'
|
||||
. ','
|
||||
. ',"Post to ' . fixOperaButtonName($GLOBALS['sitename']) . ' (Pop-up)"'
|
||||
. ',"Scuttle"';
|
||||
echo jsEscTitle(htmlspecialchars($link));
|
||||
?>'.replace('SELECTION', selection)
|
||||
+ '"><?php echo jsEscTitle(sprintf(T_('Post to %s (Pop-up)'), $GLOBALS['sitename'])); ?></a>'
|
||||
+ '</li>'
|
||||
+ '</ul>'
|
||||
);
|
||||
} else {
|
||||
$('#bookmarklet').append(
|
||||
'<ul>'
|
||||
+ '<li><a class="bookmarklet" href="javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');location.href=\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&address=\'+a+\'&title=\'+t+\'&description=\'+d;void 0;"><?php echo jsEscTitle(sprintf(T_('Post to %s'), $GLOBALS['sitename'])); ?><\/a><\/li>'
|
||||
+ '<li>'
|
||||
+ '<a class="bookmarklet" href="'
|
||||
+ 'javascript:x=document;'
|
||||
+ 'a=encodeURIComponent(x.location.href);'
|
||||
+ 't=encodeURIComponent(x.title);'
|
||||
+ 'd=encodeURIComponent('+selection+');'
|
||||
+ 'open('
|
||||
+ '\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&popup=1&address=\'+a+\'&title=\'+t+\'&description=\'+d,\'<?php echo htmlspecialchars(jsEscTitleDouble($GLOBALS['sitename'])); ?>\',\'modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=\'+(screen.width-790)/2+\',top=\'+(screen.height-425)/2'
|
||||
+ ');void 0;">'
|
||||
+ '<?php echo jsEscTitle(sprintf(T_('Post to %s (Pop-up)'), $GLOBALS['sitename'])); ?>'
|
||||
+ '</a>'
|
||||
+ '</li>'
|
||||
+ '</ul>'
|
||||
);
|
||||
}
|
||||
//]]>
|
||||
</script>
|
@ -1,14 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Show a list of bookmarks.
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @subcategory Templates
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$tagservice =SemanticScuttle_Service_Factory::get('Tag');
|
||||
$cdservice =SemanticScuttle_Service_Factory::get('CommonDescription');
|
||||
$bookmarkservice = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$tagservice = SemanticScuttle_Service_Factory::get('Tag');
|
||||
$cdservice = SemanticScuttle_Service_Factory::get('CommonDescription');
|
||||
|
||||
|
||||
$pageName = isset($pageName)?$pageName:"";
|
||||
$user = isset($user)?$user:"";
|
||||
$currenttag = isset($currenttag)?$currenttag:"";
|
||||
$pageName = isset($pageName) ? $pageName : '';
|
||||
$user = isset($user) ? $user : '';
|
||||
$currenttag = isset($currenttag) ? $currenttag : '';
|
||||
|
||||
|
||||
$this->includeTemplate($GLOBALS['top_include']);
|
||||
@ -46,12 +62,16 @@ if($currenttag!= '' && $cdservice->getLastTagDescription($currenttag)) {
|
||||
}
|
||||
|
||||
//common tag description edit
|
||||
if($userservice->isLoggedOn()) {
|
||||
if($currenttag!= '' && ($GLOBALS['enableCommonTagDescriptionEditedByAll'] || $currentUser->isAdmin())) {
|
||||
if ($userservice->isLoggedOn()) {
|
||||
if ($currenttag != ''
|
||||
&& ($GLOBALS['enableCommonTagDescriptionEditedByAll']
|
||||
|| $currentUser->isAdmin()
|
||||
)
|
||||
) {
|
||||
echo ' <a href="'. createURL('tagcommondescriptionedit', $currenttag).'" title="'.T_('Edit the common description of this tag').'">';
|
||||
echo !is_array($cDescription) || strlen($cDescription['cdDescription'])==0?T_('Edit the common description of this tag'):'';
|
||||
echo ' <img src="'.ROOT.'images/b_edit.png" /></a>';
|
||||
} elseif(isset($hash)) {
|
||||
} else if (isset($hash)) {
|
||||
echo ' (<a href="'.createURL('bookmarkcommondescriptionedit', $hash).'" title="'.T_('Edit the common description of this bookmark').'">';
|
||||
echo T_('Edit the common description of this bookmark').'</a>)';
|
||||
}
|
||||
@ -101,54 +121,54 @@ $votingSort = 'voting_desc';
|
||||
|
||||
switch(getSortOrder()) {
|
||||
case 'date_asc':
|
||||
$dateArrow = ' ↑';
|
||||
$dateArrow = ' ↑';
|
||||
$dateSort = 'date_desc';
|
||||
break;
|
||||
|
||||
case 'title_asc':
|
||||
$titleArrow = ' ↑';
|
||||
$titleArrow = ' ↑';
|
||||
$titleSort = 'title_desc';
|
||||
break;
|
||||
|
||||
case 'title_desc':
|
||||
$titleArrow = ' ↓';
|
||||
$titleArrow = ' ↓';
|
||||
$titleSort = 'title_asc';
|
||||
break;
|
||||
|
||||
case 'voting_asc':
|
||||
$votingArrow = ' ↑';
|
||||
$votingArrow = ' ↑';
|
||||
$votingSort = 'voting_desc';
|
||||
break;
|
||||
|
||||
case 'voting_desc':
|
||||
$votingArrow = ' ↓';
|
||||
$votingArrow = ' ↓';
|
||||
$votingSort = 'voting_asc';
|
||||
break;
|
||||
|
||||
case 'date_desc':
|
||||
default:
|
||||
$dateArrow = ' ↓';
|
||||
$dateArrow = ' ↓';
|
||||
$dateSort = 'date_asc';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<a href="?sort=<?php echo $dateSort ?>"><?php echo T_("Date").$dateArrow; ?></a>
|
||||
<span>/</span>
|
||||
<a href="?sort=<?php echo $titleSort ?>"><?php echo T_("Title").$titleArrow; ?></a>
|
||||
<span>/</span>
|
||||
<a href="?sort=<?php echo $dateSort ?>"><?php echo T_("Date").$dateArrow; ?></a>
|
||||
<span>/</span>
|
||||
<a href="?sort=<?php echo $titleSort ?>"><?php echo T_("Title").$titleArrow; ?></a>
|
||||
<span>/</span>
|
||||
<?php if ($GLOBALS['enableVoting']) { ?>
|
||||
<a href="?sort=<?php echo $votingSort ?>"><?php echo T_("Voting").$votingArrow; ?></a>
|
||||
<span>/</span>
|
||||
<a href="?sort=<?php echo $votingSort ?>"><?php echo T_("Voting").$votingArrow; ?></a>
|
||||
<span>/</span>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
if($currenttag!= '') {
|
||||
if($user!= '') {
|
||||
if ($currenttag!= '') {
|
||||
if ($user!= '') {
|
||||
echo ' - ';
|
||||
echo '<a href="'. createURL('tags', $currenttag) .'">';
|
||||
echo T_('Bookmarks from other users for this tag').'</a>';
|
||||
//echo T_(' for these tags');
|
||||
} else if($userservice->isLoggedOn()){
|
||||
} else if ($userservice->isLoggedOn()){
|
||||
echo ' - ';
|
||||
echo '<a href="'. createURL('bookmarks', $currentUser->getUsername().'/'.$currenttag) .'">';
|
||||
echo T_('Only your bookmarks for this tag').'</a>';
|
||||
@ -199,7 +219,10 @@ if($currenttag!= '') {
|
||||
$brss = '';
|
||||
$size = count($rsschannels);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$brss = '<a style="background:#FFFFFF" href="'. $rsschannels[$i][1] .'" title="' . htmlspecialchars($rsschannels[$i][0]) . '"><img src="'. ROOT .'images/rss.gif" width="16" height="16" alt="'. htmlspecialchars($rsschannels[$i][0]) .'" /></a>';
|
||||
$brss = '<a style="background:#FFFFFF" href="'. htmlspecialchars($rsschannels[$i][1]) . '"'
|
||||
. ' title="' . htmlspecialchars($rsschannels[$i][0]) . '">'
|
||||
. '<img src="' . ROOT . 'images/rss.gif" width="16" height="16" alt="' . htmlspecialchars($rsschannels[$i][0]) .'"/>'
|
||||
. '</a>';
|
||||
}
|
||||
|
||||
$pagesBanner = '<p class="paging">'. $bfirst .'<span> / </span>'. $bprev .'<span> / </span>'. $bnext .'<span> / </span>'. $blast .'<span> / </span>'. sprintf(T_('Page %d of %d'), $page, $totalpages) ." ". $brss ." </p>\n";
|
||||
@ -213,10 +236,8 @@ if($currenttag!= '') {
|
||||
|
||||
|
||||
|
||||
<ol <?php echo ($start > 0 ? ' start="'. ++$start .'"' : ''); ?>
|
||||
id="bookmarks">
|
||||
|
||||
<?php
|
||||
<ol<?php echo ($start > 0 ? ' start="'. ++$start .'"' : ''); ?> id="bookmarks">
|
||||
<?php
|
||||
$addresses = array();
|
||||
foreach ($bookmarks as $key => &$row) {
|
||||
$addresses[$row['bId']] = $row['bAddress'];
|
||||
@ -253,35 +274,52 @@ if($currenttag!= '') {
|
||||
$tagsForCopy = '';
|
||||
$tags = $row['tags'];
|
||||
foreach ($tags as $tkey => &$tag) {
|
||||
$cats .= '<a href="'. sprintf($cat_url, filter($row['username'], 'url'), filter($tag, 'url')) .'" rel="tag">'. filter($tag) .'</a>, ';
|
||||
$tagsForCopy.= $tag.',';
|
||||
$tagcaturl = sprintf(
|
||||
$cat_url,
|
||||
filter($row['username'], 'url'),
|
||||
filter($tag, 'url')
|
||||
);
|
||||
$cats .= sprintf(
|
||||
'<a href="%s" rel="tag">%s</a>, ',
|
||||
$tagcaturl, filter($tag)
|
||||
);
|
||||
$tagsForCopy .= $tag . ',';
|
||||
}
|
||||
$cats = substr($cats, 0, -2);
|
||||
if ($cats != '') {
|
||||
$cats = ' '.T_('Tags:').' '. $cats;
|
||||
$cats = T_('Tags:') . ' ' . $cats;
|
||||
}
|
||||
|
||||
// Edit and delete links
|
||||
$edit = '';
|
||||
if ($bookmarkservice->editAllowed($row)) {
|
||||
$edit = ' - <a href="'. createURL('edit', $row['bId']) .'">'. T_('Edit') .'</a><script type="text/javascript">document.write(" - <a href=\"#\" onclick=\"deleteBookmark(this, '. $row['bId'] .'); return false;\">'. T_('Delete') .'<\/a>");</script>';
|
||||
$edit = ' - <a href="' . createURL('edit', $row['bId']) . '">'
|
||||
. T_('Edit')
|
||||
. '</a>'
|
||||
. ' <a href="#" onclick="deleteBookmark(this, '. $row['bId'] .'); return false;">'
|
||||
. T_('Delete')
|
||||
.'</a>';
|
||||
}
|
||||
|
||||
// Last update
|
||||
$update = ' <small title="'. T_('Last update') .'">('. date($GLOBALS['shortdate'], strtotime($row['bModified'])). ') </small>';
|
||||
$update = ' <small title="'. T_('Last update') .'">('. date($GLOBALS['shortdate'], strtotime($row['bModified'])). ') </small>';
|
||||
|
||||
// User attribution
|
||||
$copy = ' '. T_('by'). ' ';
|
||||
if($userservice->isLoggedOn() && $currentUser->getUsername() == $row['username']) {
|
||||
$copy.= T_('you');
|
||||
$copy = ' ' . T_('by') . ' ';
|
||||
if ($userservice->isLoggedOn()
|
||||
&& $currentUser->getUsername() == $row['username']
|
||||
) {
|
||||
$copy .= T_('you');
|
||||
} else {
|
||||
$copy.= '<a href="'. createURL('bookmarks', $row['username']) .'">'. $row['username'] .'</a>';
|
||||
$copy .= '<a href="' . createURL('bookmarks', $row['username']) . '">'
|
||||
. SemanticScuttle_Model_UserArray::getName($row)
|
||||
. '</a>';
|
||||
}
|
||||
|
||||
// Udders!
|
||||
// others
|
||||
if (!isset($hash)) {
|
||||
$others = $otherCounts[$row['bAddress']];
|
||||
$ostart = '<a href="'. createURL('history', $row['bHash']) .'">';
|
||||
$ostart = '<a href="' . createURL('history', $row['bHash']) . '">';
|
||||
$oend = '</a>';
|
||||
switch ($others) {
|
||||
case 0:
|
||||
@ -300,7 +338,10 @@ if($currenttag!= '') {
|
||||
&& !$existence[$row['bAddress']]
|
||||
) {
|
||||
$copy .= ' - <a href="'
|
||||
. createURL('bookmarks', $currentUser->getUsername() .'?action=add&copyOf='. $row['bId'])
|
||||
. createURL(
|
||||
'bookmarks',
|
||||
$currentUser->getUsername()
|
||||
. '?action=add&copyOf=' . $row['bId'])
|
||||
. '" title="'.T_('Copy this bookmark to YOUR bookmarks.').'">'
|
||||
. T_('Copy')
|
||||
. '</a>';
|
||||
@ -321,11 +362,11 @@ if($currenttag!= '') {
|
||||
|
||||
// Admin specific design
|
||||
if ($userservice->isAdmin($row['username']) && $GLOBALS['enableAdminColors']) {
|
||||
$adminBgClass = 'class="adminBackground"';
|
||||
$adminStar = ' <img src="'. ROOT .'images/logo_24.gif" width="12px" title="'. T_('This bookmark is certified by an admin user.') .'" />';
|
||||
$adminBgClass = ' class="adminBackground"';
|
||||
$adminStar = ' <img src="'. ROOT .'images/logo_24.gif" width="12px" title="'. T_('This bookmark is certified by an admin user.') .'" />';
|
||||
} else {
|
||||
$adminBgClass = '';
|
||||
$adminStar = '';
|
||||
$adminStar = '';
|
||||
}
|
||||
|
||||
// Private Note (just visible by the owner and his/her contacts)
|
||||
@ -346,13 +387,16 @@ if($currenttag!= '') {
|
||||
}
|
||||
|
||||
// Output
|
||||
echo '<li class="xfolkentry'. $access .'" >'."\n";
|
||||
echo ' <li class="xfolkentry'. $access .'">'."\n";
|
||||
include 'bookmarks-thumbnail.inc.tpl.php';
|
||||
include 'bookmarks-vote.inc.tpl.php';
|
||||
|
||||
echo '<div '.$adminBgClass.' >';;
|
||||
echo ' <div' . $adminBgClass . '>' . "\n";
|
||||
|
||||
echo '<div class="link"><a href="'. htmlspecialchars($address) .'"'. $rel .' class="taggedlink" target="_blank">'. filter($row['bTitle']) ."</a>" . $adminStar . "</div>\n";
|
||||
echo ' <div class="link">'
|
||||
. '<a href="'. htmlspecialchars($address) .'"'. $rel .' class="taggedlink">'
|
||||
. filter($row['bTitle'])
|
||||
. '</a>' . $adminStar . "</div>\n";
|
||||
if ($row['bDescription'] == '') {
|
||||
$bkDescription = $GLOBALS['blankDescription'];
|
||||
} else {
|
||||
@ -362,17 +406,23 @@ if($currenttag!= '') {
|
||||
$bkDescription = preg_replace('@((http|https|ftp)://.*?)( |\r|$)@', '<a href="$1" rel="nofollow">$1</a>$3', $bkDescription); // make url clickable
|
||||
|
||||
}
|
||||
echo '<div class="description">'. nl2br($bkDescription) ."</div>\n";
|
||||
//if(!isset($hash)) {
|
||||
echo '<div class="address">' . shortenString($oaddress) . '</div>';
|
||||
//}
|
||||
echo ' <div class="description">'. nl2br($bkDescription) ."</div>\n";
|
||||
echo ' <div class="address">' . shortenString($oaddress) . "</div>\n";
|
||||
|
||||
echo '<div class="meta">'. $cats . $copy . $edit . $update ."</div>\n";
|
||||
echo $privateNoteField!=''?'<div class="privateNote" title="'. T_('Private Note on this bookmark') .'">'.$privateNoteField."</div>\n":'';
|
||||
echo ' <div class="meta">'
|
||||
. $cats . "\n"
|
||||
. $copy . "\n"
|
||||
. $edit . "\n"
|
||||
. $update . "\n"
|
||||
. " </div>\n";
|
||||
echo $privateNoteField != ''
|
||||
? ' <div class="privateNote" title="'. T_('Private Note on this bookmark') .'">'.$privateNoteField."</div>\n"
|
||||
: '';
|
||||
echo ' ';
|
||||
include 'bookmarks-vote-horizontal.inc.tpl.php';
|
||||
echo '</div>';
|
||||
echo " </div>\n";
|
||||
|
||||
echo "</li>\n";
|
||||
echo " </li>\n";
|
||||
}
|
||||
?>
|
||||
|
||||
|
@ -36,28 +36,40 @@ $allPopularTagsCount = count($allPopularTags);
|
||||
|
||||
|
||||
// function printing the cloud
|
||||
function writeTagsProposition($tagsCloud, $title) {
|
||||
echo 'document.write(\'<div class="collapsible">\');';
|
||||
echo 'document.write(\'<h3>'. $title .'<\/h3>\');';
|
||||
echo 'document.write(\'<p id="popularTags" class="tags">\');';
|
||||
function writeTagsProposition($tagsCloud, $title)
|
||||
{
|
||||
static $id = 0;
|
||||
++$id;
|
||||
|
||||
echo <<<JS
|
||||
$('.edit-tagclouds')
|
||||
.append(
|
||||
'<div class="collapsible" id="edit-tagcloud-$id">'
|
||||
+ ' <h3>$title</h3>'
|
||||
+ ' <p class="popularTags tags"></p>'
|
||||
+ '</div>');
|
||||
JS;
|
||||
|
||||
$taglist = '';
|
||||
foreach(array_keys($tagsCloud) as $key) {
|
||||
$row =& $tagsCloud[$key];
|
||||
foreach (array_keys($tagsCloud) as $key) {
|
||||
$row = $tagsCloud[$key];
|
||||
$entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
|
||||
$taglist .= '<span title="'. $row['bCount'] .' '. $entries .'" style="font-size:'. $row['size'] .'" onclick="addTag(this)">'. filter($row['tag']) .'<\/span> ';
|
||||
$taglist .= '<span'
|
||||
. ' title="'. $row['bCount'] . ' ' . $entries . '"'
|
||||
. ' style="font-size:' . $row['size'] . '"'
|
||||
. ' onclick="addTag(this)">'
|
||||
. filter($row['tag'])
|
||||
. '</span> ';
|
||||
}
|
||||
|
||||
echo 'document.write(\''. $taglist .'\');';
|
||||
echo 'document.write(\'<\/p>\');';
|
||||
echo 'document.write(\'<\/div>\');';
|
||||
|
||||
echo '$(\'#edit-tagcloud-' . $id . ' p\').append('
|
||||
. json_encode($taglist)
|
||||
. ");\n";
|
||||
}
|
||||
|
||||
|
||||
if ($allPopularTagsCount > 0 || $userPopularTagsCount > 0 ) { ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
Array.prototype.contains = function (ele) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (this[i] == ele) {
|
||||
@ -87,20 +99,26 @@ function addonload(addition) {
|
||||
}
|
||||
}
|
||||
|
||||
addonload(
|
||||
function () {
|
||||
var taglist = document.getElementById('tags');
|
||||
var tags = taglist.value.split(', ');
|
||||
jQuery(function($) {
|
||||
<?php
|
||||
if ($userPopularTagsCount > 0) {
|
||||
writeTagsProposition($userPopularTagsCloud, T_('Popular Tags'));
|
||||
}
|
||||
if ($allPopularTagsCount > 0) {
|
||||
writeTagsProposition($allPopularTagsCloud, T_('Popular Tags From All Users'));
|
||||
}
|
||||
?>
|
||||
var taglist = $('#tags');
|
||||
var tags = taglist.val().split(', ');
|
||||
|
||||
var populartags = document.getElementById('popularTags').getElementsByTagName('span');
|
||||
var populartags = $('.edit-tagclouds span');
|
||||
|
||||
for (var i = 0; i < populartags.length; i++) {
|
||||
if (tags.contains(populartags[i].innerHTML)) {
|
||||
populartags[i].className = 'selected';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function addTag(ele) {
|
||||
var thisTag = ele.innerHTML;
|
||||
@ -122,20 +140,9 @@ function addTag(ele) {
|
||||
|
||||
document.getElementById('tags').focus();
|
||||
}
|
||||
|
||||
<?php
|
||||
if( $userPopularTagsCount > 0) {
|
||||
writeTagsProposition($userPopularTagsCloud, T_('Popular Tags'));
|
||||
}
|
||||
if( $allPopularTagsCount > 0) {
|
||||
writeTagsProposition($allPopularTagsCloud, T_('Popular Tags From All Users'));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="edit-tagclouds"></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -16,33 +16,41 @@ switch ($row['bStatus']) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->includeTemplate("dojo.inc");
|
||||
|
||||
function jsEscTitle($title)
|
||||
{
|
||||
return addcslashes($title, "'");
|
||||
}
|
||||
function jsEscTitleDouble($title)
|
||||
{
|
||||
return addcslashes(addcslashes($title, "'"), "'\\");
|
||||
}
|
||||
function fixOperaButtonName($name) {
|
||||
//yes, opera has problems with double quotes in button names
|
||||
return str_replace('"', "''", $name);
|
||||
}
|
||||
|
||||
if (is_array($row['tags'])) {
|
||||
$row['tags'] = implode(', ', $row['tags']);
|
||||
}
|
||||
|
||||
$ajaxUrl = ROOT . 'ajax/'
|
||||
. (
|
||||
($GLOBALS['adminsAreAdvisedTagsFromOtherAdmins'] && $currentUser->isAdmin())
|
||||
? 'getadmintags'
|
||||
: 'getcontacttags'
|
||||
) . '.php';
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
//window.onload = function() {
|
||||
// document.getElementById("address").focus();
|
||||
//}
|
||||
</script>
|
||||
|
||||
<form action="<?php echo $formaction; ?>" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Address'); ?></th>
|
||||
<td><input type="text" id="address" name="address" size="75" maxlength="65535" value="<?php echo filter($row['bAddress'], 'xml'); ?>" onblur="useAddress(this)" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Title'); ?></th>
|
||||
<td><input type="text" id="titleField" name="title" size="75" maxlength="255" value="<?php echo filter($row['bTitle'], 'xml'); ?>" onkeypress="this.style.backgroundImage = 'none';" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left">
|
||||
@ -50,7 +58,7 @@ function jsEscTitle($title)
|
||||
<a onclick="var nz = document.getElementById('privateNoteZone'); nz.style.display='';this.style.display='none';"><?php echo T_("Add Note"); ?></a>
|
||||
</th>
|
||||
<td><textarea name="description" id="description" rows="5" cols="63" ><?php echo filter($row['bDescription'], 'xml'); ?></textarea></td>
|
||||
<td>← <?php echo T_('You can use anchors to delimite attributes. for example: [publisher]blah[/publisher] '); ?>
|
||||
<td>← <?php echo T_('You can use anchors to delimite attributes. for example: [publisher]blah[/publisher] '); ?>
|
||||
<?php if(count($GLOBALS['descriptionAnchors'])>0): ?>
|
||||
<br /><br />
|
||||
<?php echo T_('Suggested anchors: '); ?>
|
||||
@ -67,23 +75,23 @@ function jsEscTitle($title)
|
||||
<tr id="privateNoteZone" <?php if(strlen($row['bPrivateNote'])==0):?>style="display:none"<?php endif; ?>>
|
||||
<th align="left"><?php echo T_('Private Note'); ?></th>
|
||||
<td><textarea name="privateNote" id="privateNote" rows="1" cols="63" ><?php echo filter($row['bPrivateNote'], 'xml'); ?></textarea></td>
|
||||
<td>← <?php echo T_('Just visible by you and your contacts.'); ?>
|
||||
<td>← <?php echo T_('Just visible by you and your contacts.'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Tags'); ?></th>
|
||||
<td class="scuttletheme">
|
||||
<span dojoType="dojo.data.ItemFileReadStore" jsId="memberTagStore" url="<?php echo ROOT?>ajax/<?php echo ($GLOBALS['adminsAreAdvisedTagsFromOtherAdmins'] && $currentUser->isAdmin())?'getadmintags':'getcontacttags'?>.php"></span>
|
||||
<input type="text" dojoType="js.MultiComboBox" id="tags" name="tags" size="75" value="<?php echo filter(implode(', ', $row['tags']), 'xml'); ?>" store="memberTagStore" delimiter="," searchAttr="tag" hasDownArrow="false" queryExpr="*${0}*" autoComplete="false" highlightMatch="all"/></td>
|
||||
<td>← <?php echo T_('Comma-separated'); ?></td>
|
||||
<input type="text" id="tags" name="tags" size="75" value="<?php echo filter($row['tags'], 'xml'); ?>"/>
|
||||
</td>
|
||||
<td>← <?php echo T_('Comma-separated'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td align="right"><small><?php echo T_('Note: use ">" to include one tag in another. e.g.: europe>france>paris')?><small></td>
|
||||
<td align="right"><small><?php echo htmlspecialchars(T_('Note: use ">" to include one tag in another. e.g.: europe>france>paris'))?></small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td align="right"><small><?php echo T_('Note: use "=" to make synonym two tags. e.g.: france=frenchcountry')?><small></td>
|
||||
<td align="right"><small><?php echo T_('Note: use "=" to make synonym two tags. e.g.: france=frenchcountry')?></small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Privacy'); ?></th>
|
||||
@ -111,7 +119,7 @@ function jsEscTitle($title)
|
||||
echo ' (<a href="'.createURL('bookmarkcommondescriptionedit', $row['bHash']).'">';
|
||||
echo T_('edit common description').'</a>)';
|
||||
}
|
||||
|
||||
|
||||
if ($popup) {
|
||||
?>
|
||||
<input type="hidden" name="popup" value="1" />
|
||||
@ -124,52 +132,83 @@ function jsEscTitle($title)
|
||||
?>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<link href="<?php echo ROOT ?>js/jquery-ui-1.8.11/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css"/>
|
||||
|
||||
<script type="text/javascript" src="<?php echo ROOT ?>js/jquery-ui-1.8.11/jquery.ui.core.js"></script>
|
||||
<script type="text/javascript" src="<?php echo ROOT ?>js/jquery-ui-1.8.11/jquery.ui.widget.js"></script>
|
||||
<script type="text/javascript" src="<?php echo ROOT ?>js/jquery-ui-1.8.11/jquery.ui.position.js"></script>
|
||||
<script type="text/javascript" src="<?php echo ROOT ?>js/jquery-ui-1.8.11/jquery.ui.autocomplete.js"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
jQuery(document).ready(function() {
|
||||
function split(val)
|
||||
{
|
||||
return val.split(/[,=><]\s*/);
|
||||
}
|
||||
|
||||
function extractLast(term)
|
||||
{
|
||||
return split(term).pop();
|
||||
}
|
||||
//var availableTags = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby"];
|
||||
|
||||
jQuery("input#tags").autocomplete({
|
||||
autoFocus: true,
|
||||
minLength: 1,
|
||||
|
||||
source: function(request, response) {
|
||||
// delegate back to autocomplete, but extract the last term
|
||||
var term = extractLast(request.term);
|
||||
if (term.length < this.options.minLength) {
|
||||
return;
|
||||
}
|
||||
response(
|
||||
/*
|
||||
$.ui.autocomplete.filter(
|
||||
availableTags, extractLast(request.term)
|
||||
)
|
||||
*/
|
||||
$.getJSON(
|
||||
"<?php echo $ajaxUrl; ?>",
|
||||
{ beginsWith: term },
|
||||
response
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
// prevent value inserted on focus
|
||||
return false;
|
||||
},
|
||||
select: function(event, ui) {
|
||||
var terms = split(this.value);
|
||||
// remove the current input
|
||||
terms.pop();
|
||||
// add the selected item
|
||||
terms.push(ui.item.value);
|
||||
// add placeholder to get the comma-and-space at the end
|
||||
terms.push("");
|
||||
this.value = terms.join(", ");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
// Dynamic tag selection
|
||||
$this->includeTemplate('dynamictags.inc');
|
||||
|
||||
// Bookmarklets and import links
|
||||
if (empty($_REQUEST['popup']) && (!isset($showdelete) || !$showdelete)) {
|
||||
|
||||
$this->includeTemplate('bookmarklet.inc.php');
|
||||
?>
|
||||
|
||||
<h3><?php echo T_('Bookmarklet'); ?></h3>
|
||||
<p>
|
||||
<script type="text/javascript">
|
||||
var browser=navigator.appName;
|
||||
if (browser == "Opera")
|
||||
{
|
||||
document.write('<?php echo sprintf(T_("Click one of the following bookmarklets to add a button you can click whenever you want to add the page you are on to %s"), jsEscTitle($GLOBALS['sitename'])); ?>:</p>');
|
||||
}
|
||||
else
|
||||
{
|
||||
document.write('<?php echo sprintf(T_("Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"), jsEscTitle($GLOBALS['sitename'])); ?>:</p>');
|
||||
}
|
||||
var selection = '';
|
||||
if (window.getSelection) {
|
||||
selection = 'window.getSelection()';
|
||||
} else if (document.getSelection) {
|
||||
selection = 'document.getSelection()';
|
||||
} else if (document.selection) {
|
||||
selection = 'document.selection.createRange().text';
|
||||
}
|
||||
document.write('<ul>');
|
||||
if (browser == "Opera")
|
||||
{
|
||||
document.write('<li><a class="bookmarklet" href="opera:/button/Go%20to%20page,%20%22javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');location.href=\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&address=\'+a+\'&title=\'+t+\'&description=\'+d;void 0%22;,,%22Post%20to%20<?php echo jsEscTitle($GLOBALS['sitename']); ?>%22,%22Scuttle%22"><?php echo jsEscTitle(sprintf(T_('Post to %s'), $GLOBALS['sitename'])); ?><\/a><\/li>');
|
||||
document.write('<li><a class="bookmarklet" href="opera:/button/Go%20to%20page,%20%22javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');open(\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&popup=1&address=\'+a+\'&title=\'+t+\'&description=\'+d,\'<?php echo jsEscTitle($GLOBALS['sitename']); ?>\',\'modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=\'+(screen.width-790)/2+\',top=\'+(screen.height-425)/2);void 0;%22,,%22Post%20to%20<?php echo urlencode($GLOBALS['sitename']); ?>%20(Pop-up)%22,%22Scuttle%22"><?php echo jsEscTitle(sprintf(T_('Post to %s (Pop-up)'), $GLOBALS['sitename'])); ?><\/a><\/li>');
|
||||
}
|
||||
else
|
||||
{
|
||||
document.write('<li><a class="bookmarklet" href="javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');location.href=\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&address=\'+a+\'&title=\'+t+\'&description=\'+d;void 0;"><?php echo jsEscTitle(sprintf(T_('Post to %s'), $GLOBALS['sitename'])); ?><\/a><\/li>');
|
||||
document.write('<li><a class="bookmarklet" href="javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');open(\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&popup=1&address=\'+a+\'&title=\'+t+\'&description=\'+d,\'<?php echo jsEscTitle($GLOBALS['sitename']); ?>\',\'modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=\'+(screen.width-790)/2+\',top=\'+(screen.height-425)/2);void 0;"><?php echo jsEscTitle(sprintf(T_('Post to %s (Pop-up)'), $GLOBALS['sitename'])); ?><\/a><\/li>');
|
||||
}
|
||||
document.write('<\/ul>');
|
||||
</script>
|
||||
|
||||
<h3><?php echo T_('Import'); ?></h3>
|
||||
<ul>
|
||||
<li><a href="<?php echo createURL('importNetscape'); ?>"><?php echo T_('Import bookmarks from bookmark file'); ?></a> (<?php echo T_('Internet Explorer, Mozilla Firefox and Netscape'); ?>)</li>
|
||||
@ -178,5 +217,5 @@ document.write('<\/ul>');
|
||||
|
||||
<?php
|
||||
}
|
||||
$this->includeTemplate($GLOBALS['bottom_include']);
|
||||
$this->includeTemplate($GLOBALS['bottom_include']);
|
||||
?>
|
||||
|
@ -3,9 +3,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
||||
?>
|
||||
|
||||
<form action="<?php echo $formaction; ?>" method="post">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
|
||||
</table>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>"/>
|
||||
|
||||
<h3><?php echo T_('Account Details'); ?></h3>
|
||||
|
||||
@ -28,7 +26,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('E-mail'); ?></th>
|
||||
<td><input type="text" name="pMail" size="75" value="<?php echo filter($objectUser->getEmail(), 'xml'); ?>" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -58,7 +56,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
||||
<th align="left"><?php echo T_('Export bookmarks'); ?></th>
|
||||
<td>
|
||||
<a href="../api/export_html.php"><?php echo T_('HTML file (for browsers)')?></a> /
|
||||
<a href="../api/posts/all"><?php echo T_('XML file (like del.icio.us)')?></a> /
|
||||
<a href="../api/posts_all.php"><?php echo T_('XML file (like del.icio.us)')?></a> /
|
||||
<a href="../api/export_csv.php"><?php echo T_('CSV file (for spreadsheet tools)')?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,4 +1,11 @@
|
||||
<?php
|
||||
/*
|
||||
* Used in:
|
||||
* - populartags.php
|
||||
* - bookmarks.php
|
||||
* - alltags.php
|
||||
* - tags.php
|
||||
*/
|
||||
/* Service creation: only useful services are created */
|
||||
$tag2tagservice =SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
|
||||
@ -8,98 +15,52 @@ require_once('sidebar.linkedtags.inc.php');
|
||||
$user = isset($user)?$user:'';
|
||||
$userid = isset($userid)?$userid:0;
|
||||
$currenttag = isset($currenttag)?$currenttag:'';
|
||||
$summarizeLinkedTags = isset($summarizeLinkedTags)?$summarizeLinkedTags:false;
|
||||
|
||||
//$summarizeLinkedTags = isset($summarizeLinkedTags)?$summarizeLinkedTags:false;
|
||||
|
||||
$logged_on_userid = $userservice->getCurrentUserId();
|
||||
if ($logged_on_userid === false) {
|
||||
$logged_on_userid = NULL;
|
||||
}
|
||||
|
||||
$explodedTags = array();
|
||||
if (strlen($currenttag)>0) {
|
||||
$explodedTags = explode('+', $currenttag);
|
||||
} else {
|
||||
if($summarizeLinkedTags == true) {
|
||||
$orphewTags = $tag2tagservice->getOrphewTags('>', $userid, 4, "nb");
|
||||
} else {
|
||||
$orphewTags = $tag2tagservice->getOrphewTags('>', $userid);
|
||||
}
|
||||
|
||||
foreach($orphewTags as $orphewTag) {
|
||||
$explodedTags[] = $orphewTag['tag'];
|
||||
}
|
||||
}
|
||||
|
||||
$editingMode = $logged_on_userid !== false;
|
||||
?>
|
||||
|
||||
<h2><?php echo T_('Linked Tags'); ?></h2>
|
||||
<div id="related">
|
||||
<?php
|
||||
if(($logged_on_userid != null) && ($userid === $logged_on_userid)) {
|
||||
$editingMode = true;
|
||||
} else {
|
||||
$editingMode = false;
|
||||
}
|
||||
|
||||
$this->includeTemplate("dojo.inc");
|
||||
?>
|
||||
|
||||
<?php if(count($explodedTags)>0 || $editingMode):?>
|
||||
|
||||
<h2><?php
|
||||
|
||||
|
||||
echo T_('Linked Tags').' ';
|
||||
//if($userid != null) {
|
||||
$cUser = $userservice->getUser($userid);
|
||||
//echo '<small><a href="'.createURL('alltags', $cUser['username']).'">('.T_('all tags').')</a></small>';
|
||||
//}
|
||||
?></h2>
|
||||
<?php //endif?>
|
||||
|
||||
<div id="related"> <?php
|
||||
if($editingMode) {
|
||||
if ($editingMode) {
|
||||
echo '<p style="margin-bottom: 13px;text-align:center;">';
|
||||
echo ' (<a href="'. createURL('tag2tagadd','') .'" rel="tag">'.T_('Add new link').'</a>) ';
|
||||
echo ' (<a href="'. createURL('tag2tagdelete','') .'" rel="tag">'.T_('Delete link').'</a>)';
|
||||
echo '</p>';
|
||||
}
|
||||
?>
|
||||
<div id="related-content"></div>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
jQuery("#related-content")
|
||||
.jstree({
|
||||
"themes" : {
|
||||
"theme": "default",
|
||||
"dots": false,
|
||||
"icons": true,
|
||||
"url": '<?php echo ROOT_JS ?>themes/default/style.css'
|
||||
},
|
||||
"json_data" : {
|
||||
"ajax" : {
|
||||
"url": function(node) {
|
||||
//-1 is root
|
||||
parentparam = "";
|
||||
if (node == -1 ) {
|
||||
node = <?php echo json_encode($currenttag); ?>;
|
||||
parentparam = "&parent=true";
|
||||
} else if (node.attr('rel')) {
|
||||
node = node.attr('rel');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen($user)==0) {
|
||||
$cat_url = createURL('tags', '%2$s');
|
||||
}
|
||||
|
||||
$stopList = array();
|
||||
foreach($explodedTags as $explodedTag) {
|
||||
if(!in_array($explodedTag, $stopList)) {
|
||||
|
||||
|
||||
|
||||
// fathers tag
|
||||
$fatherTags = $tag2tagservice->getLinkedTags($explodedTag, '>', $userid, true);
|
||||
if(count($fatherTags)>0) {
|
||||
foreach($fatherTags as $fatherTag) {
|
||||
echo '<a href="'. sprintf($cat_url, filter($user, 'url'), filter($fatherTag, 'url')) .'" rel="tag">('. filter($fatherTag) .')</a> ';
|
||||
}
|
||||
}
|
||||
/*
|
||||
$displayLinkedTags = displayLinkedTags($explodedTag, '>', $userid, $cat_url, $user, $editingMode, null, 1);
|
||||
echo $displayLinkedTags['output'];
|
||||
if(is_array($displayLinkedTags['stopList'])) {
|
||||
$stopList = array_merge($stopList, $displayLinkedTags['stopList']);
|
||||
}*/
|
||||
echo '<div dojoType="dojo.data.ItemFileReadStore" url="'.ROOT.'ajax/getlinkedtags.php?tag='.filter($explodedTag, 'url').'&uId='.$userid.'" jsid="linkedTagStore" ></div>';
|
||||
echo '<div dojoType="dijit.Tree" store="linkedTagStore" labelAttr="name" >';
|
||||
echo '<script type="dojo/method" event="onClick" args="item">';
|
||||
$returnUrl = sprintf($cat_url, filter($user, 'url'), filter('', 'url'));
|
||||
echo 'window.location = "'.$returnUrl.'"+item.name';
|
||||
echo '</script>';
|
||||
echo '<script type="dojo/method" event="getLabelClass" args="item">';
|
||||
echo 'return \'treeTag\';';
|
||||
echo '</script>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
}
|
||||
?> </div>
|
||||
|
||||
<?php endif?>
|
||||
return "<?php echo ROOT ?>ajax/getlinkedtags.php?tag=" + node
|
||||
+ parentparam;
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins : [ "themes", "json_data"]
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
</div>
|
@ -65,13 +65,13 @@ if (sizeof($menuTags) > 0 || ($userid != 0 && $userid === $logged_on_userid)) {
|
||||
<?php $cUser = $userservice->getUser($userid); ?>
|
||||
<?php if($userid>0): ?>
|
||||
<?php if($userid==$logged_on_userid): ?>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('alltags', $cUser['username']); ?>" title="<?php echo T_('See all your tags')?>"><?php echo T_('all your tags'); ?></a> →</p>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('alltags', $cUser['username']); ?>" title="<?php echo T_('See all your tags')?>"><?php echo T_('all your tags'); ?></a> →</p>
|
||||
<?php else: ?>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('alltags', $cUser['username']); ?>" title="<?php echo T_('See all tags from this user')?>"><?php echo T_('all tags from this user'); ?></a> →</p>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('alltags', $cUser['username']); ?>" title="<?php echo T_('See all tags from this user')?>"><?php echo T_('all tags from this user'); ?></a> →</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else : ?>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('populartags', $cUser['username']); ?>" title="<?php echo T_('See popular tags')?>"><?php echo T_('Popular Tags'); ?></a> →</p>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('populartags', $cUser['username']); ?>" title="<?php echo T_('See popular tags')?>"><?php echo T_('Popular Tags'); ?></a> →</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
<?php
|
||||
/* Service creation: only useful services are created */
|
||||
$tag2tagservice =SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
|
||||
require_once('sidebar.linkedtags.inc.php');
|
||||
|
||||
/* Manage input */
|
||||
@ -15,44 +12,60 @@ if ($logged_on_userid === false) {
|
||||
}
|
||||
|
||||
|
||||
$cat_url = createURL('tags', '%2$s');
|
||||
$cat_url = createURL('tags', '%s');
|
||||
$menu2Tags = $GLOBALS['menu2Tags'];
|
||||
|
||||
if (sizeOf($menu2Tags) > 0) {
|
||||
$this->includeTemplate("dojo.inc");
|
||||
?>
|
||||
if (count($menu2Tags) > 0) {
|
||||
?>
|
||||
|
||||
<h2><?php echo T_('Featured Menu Tags');?></h2>
|
||||
|
||||
|
||||
<div id="maintagsmenu"
|
||||
<?php echo 'title="'.T_('This menu is composed of keywords (tags) organized by admins.').'"'?>>
|
||||
|
||||
<ul>
|
||||
<?php
|
||||
foreach($menu2Tags as $menu2Tag) {
|
||||
|
||||
echo '<div dojoType="dojo.data.ItemFileReadStore" url="'.ROOT.'ajax/getadminlinkedtags.php?tag='.filter($menu2Tag, 'url').'" jsid="linkedTagStore" ></div>';
|
||||
echo '<div dojoType="dijit.Tree" store="linkedTagStore" labelAttr="name" >';
|
||||
echo '<script type="dojo/method" event="onClick" args="item">';
|
||||
$returnUrl = sprintf($cat_url, filter($user, 'url'), filter('', 'url'));
|
||||
echo 'window.location = "'.$returnUrl.'"+item.name';
|
||||
echo '</script>';
|
||||
//echo '<script type="dojo/method" event="getLabel" args="item">';
|
||||
//echo 'return item.name + "...";';
|
||||
//echo '</script>';
|
||||
//echo '<script type="dojo/method" event="onMouseOver" args="item">';
|
||||
//echo 'i = item.relatedTarget;';
|
||||
//echo 'if(i.innerHTML.charAt(i.innerHTML)=="a") alert(i.innerHTML)';
|
||||
//echo '</script>';
|
||||
//echo '<script type="dojo/method" event="getLabelClass" args="item">';
|
||||
//echo 'return \'treeTag\';';
|
||||
//echo '</script>';
|
||||
echo '</div>';
|
||||
//this is unneeded and replaced by the ajax tree anyway. we keep it for
|
||||
// non-js browsers
|
||||
foreach ($menu2Tags as $menu2Tag) {
|
||||
echo ' <li>'
|
||||
. sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
sprintf($cat_url, $menu2Tag),
|
||||
$menu2Tag
|
||||
)
|
||||
. '</li>' . "\n";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery("#maintagsmenu")
|
||||
.jstree({
|
||||
"themes" : {
|
||||
"theme": "default",
|
||||
"dots": false,
|
||||
"icons": true,
|
||||
"url": '<?php echo ROOT_JS ?>themes/default/style.css'
|
||||
},
|
||||
"json_data" : {
|
||||
"ajax" : {
|
||||
"url": function(node) {
|
||||
//-1 is root
|
||||
if (node == -1 ) {
|
||||
node = "";
|
||||
} else if (node.attr('rel')) {
|
||||
node = node.attr('rel');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return "<?php echo ROOT ?>ajax/getadminlinkedtags.php?tag=" + node;
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins : [ "themes", "json_data"]
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -31,7 +31,7 @@ if ($recentTags && count($recentTags) > 0) {
|
||||
}
|
||||
echo $contents ."</p>\n";
|
||||
?>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('populartags'); ?>"><?php echo T_('Popular Tags'); ?></a> →</p>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('populartags'); ?>"><?php echo T_('Popular Tags'); ?></a> →</p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
@ -1,35 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Show a list of the last searches.
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @subcategory Templates
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
/* Service creation: only useful services are created */
|
||||
$searchhistoryservice =SemanticScuttle_Service_Factory::get('SearchHistory');
|
||||
$searchhistoryservice = SemanticScuttle_Service_Factory::get('SearchHistory');
|
||||
|
||||
$logged_on_userid = $userservice->getCurrentUserId();
|
||||
if ($logged_on_userid === false) {
|
||||
$logged_on_userid = NULL;
|
||||
}
|
||||
|
||||
$lastSearches = $searchhistoryservice->getAllSearches('all', NULL, 3, NULL, true, false);
|
||||
$lastSearches = $searchhistoryservice->getAllSearches(
|
||||
'all', NULL, 3, NULL, true, false
|
||||
);
|
||||
|
||||
if ($lastSearches && count($lastSearches) > 0) {
|
||||
?>
|
||||
|
||||
<h2><?php echo T_('Last Searches'); ?></h2>
|
||||
<div id="searches">
|
||||
<table>
|
||||
<table>
|
||||
<?php
|
||||
foreach ($lastSearches as $row) {
|
||||
echo '<tr><td>';
|
||||
echo '<a href="' . htmlspecialchars(
|
||||
createURL('search', $range.'/'.$row['shTerms'])
|
||||
) . '">';
|
||||
echo ' <tr><td>';
|
||||
echo '<a href="'
|
||||
. htmlspecialchars(createURL('search', $range.'/'.$row['shTerms']))
|
||||
. '">';
|
||||
echo htmlspecialchars($row['shTerms']);
|
||||
echo '</a>';
|
||||
echo ' <span title="'.T_('Number of bookmarks for this query').'">('.$row['shNbResults'].')</span>';
|
||||
echo '</td></tr>';
|
||||
echo ' <span title="'
|
||||
. T_('Number of bookmarks for this query')
|
||||
. '">(' . $row['shNbResults'] . ')</span>';
|
||||
echo '</td></tr>' . "\n";
|
||||
}
|
||||
//echo '<tr><td><a href="'.createURL('users').'">...</a></td></tr>';
|
||||
?>
|
||||
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ if ($lastUsers && count($lastUsers) > 0) {
|
||||
foreach ($lastUsers as $row) {
|
||||
echo '<tr><td>';
|
||||
echo '<a href="'.createURL('profile', $row['username']).'">';
|
||||
echo $row['username'];
|
||||
echo SemanticScuttle_Model_UserArray::getName($row);
|
||||
echo '</a>';
|
||||
echo ' (<a href="'.createURL('bookmarks', $row['username']).'">'.T_('bookmarks').'</a>)';
|
||||
echo '</td></tr>';
|
||||
@ -27,7 +27,7 @@ foreach ($lastUsers as $row) {
|
||||
?>
|
||||
|
||||
</table>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('users'); ?>" title="<?php echo T_('See all users')?>"><?php echo T_('All users'); ?></a> →</p>
|
||||
<p style="text-align:right"><a href="<?php echo createURL('users'); ?>" title="<?php echo T_('See all users')?>"><?php echo T_('All users'); ?></a> →</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ foreach($watching as $watchuser) {
|
||||
?>
|
||||
|
||||
<?php if(count($closeContacts)>0):?>
|
||||
<h2 title="<?php echo T_('Close contacts are mutual contacts');?>"><?php echo ' ↔ '. T_('Close contacts'); ?></h2>
|
||||
<h2 title="<?php echo T_('Close contacts are mutual contacts');?>"><?php echo ' ↔ '. T_('Close contacts'); ?></h2>
|
||||
<div id="watching">
|
||||
<ul>
|
||||
<?php foreach($closeContacts as $watchuser): ?>
|
||||
@ -27,7 +27,7 @@ foreach($watching as $watchuser) {
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<h2><?php echo ' → '. T_('Watching'); ?></h2>
|
||||
<h2><?php echo ' → '. T_('Watching'); ?></h2>
|
||||
<div id="watching">
|
||||
<ul>
|
||||
<?php if($userservice->isLoggedOn() && $currentUser->getUsername() == $user): ?>
|
||||
@ -41,7 +41,7 @@ foreach($watching as $watchuser) {
|
||||
<?php foreach($watching as $watchuser): ?>
|
||||
<li><a href="<?php echo createURL('bookmarks', $watchuser); ?>"><?php echo $watchuser; ?></a>
|
||||
<?php if($userservice->isLoggedOn() && $currentUser->getUsername() == $user): ?>
|
||||
- <a href="<?php echo createUrl('watch','?contact='.$watchuser); ?>" title="<?php echo T_('Remove this contact'); ?>">x<a/>
|
||||
- <a href="<?php echo createUrl('watch','?contact='.$watchuser); ?>" title="<?php echo T_('Remove this contact'); ?>">x</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
@ -49,7 +49,7 @@ foreach($watching as $watchuser) {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2><?php echo ' ← '. T_('Watched By'); ?></h2>
|
||||
<h2><?php echo ' ← '. T_('Watched By'); ?></h2>
|
||||
<div id="watching">
|
||||
<ul>
|
||||
<?php foreach($watchedBy as $watchuser): ?>
|
||||
|
@ -4,7 +4,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
||||
|
||||
<form action="<?php echo $formaction; ?>" method="post">
|
||||
|
||||
<p align=right" style="float:right">
|
||||
<p align="right" style="float:right">
|
||||
<small style="text-align:right"><?php echo T_('Note: use "=" to make synonym two tags. e.g.: france=frenchcountry')?></small><br/>
|
||||
<small style="text-align:right"><?php echo T_('Note: use ">" to include one tag in another. e.g.: europe>france>paris')?></small><br/>
|
||||
</p>
|
||||
|
@ -20,7 +20,8 @@ window.onload = function() {
|
||||
if(strlen($description['cdDatetime'])>0) {
|
||||
echo T_('Last modification:').' '.$description['cdDatetime'].', ';
|
||||
$lastUser = $userservice->getUser($description['uId']);
|
||||
echo '<a href="'.createURL('profile', $lastUser['username']).'">'.$lastUser['username'].'</a>';
|
||||
echo '<a href="' . createURL('profile', $lastUser['username']) . '">'
|
||||
. SemanticScuttle_Model_UserArray::getName($lastUser) . '</a>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
@ -11,12 +11,12 @@ window.onload = function() {
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Old'); ?></th>
|
||||
<td><input type="text" name="old" id="old" value="<?php echo $old; ?>" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('New'); ?></th>
|
||||
<td><input type="text" name="new" id="new" value="" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
|
@ -1,30 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
||||
<title><?php echo filter($GLOBALS['sitename'] .(isset($pagetitle) ? ' » ' . $pagetitle : '')); ?></title>
|
||||
<link rel="icon" type="image/png" href="<?php echo ROOT ?>icon.png" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo ROOT ?>scuttle.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="<?php echo ROOT ?>api/opensearch.php" title="<?php echo htmlspecialchars($GLOBALS['sitename']) ?>"/>
|
||||
<?php
|
||||
if(isset($rsschannels)) {
|
||||
if (isset($rsschannels)) {
|
||||
$size = count($rsschannels);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
echo ' <link rel="alternate" type="application/rss+xml" title="' . htmlspecialchars($rsschannels[$i][0]) . '" href="'. $rsschannels[$i][1] .'" />';
|
||||
echo ' <link rel="alternate" type="application/rss+xml" title="'
|
||||
. htmlspecialchars($rsschannels[$i][0]) . '"'
|
||||
. ' href="'. $rsschannels[$i][1] .'" />';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://ajax.googleapis.com/ajax/libs/dojo/1.2/dijit/themes/nihilo/nihilo.css" />
|
||||
|
||||
<?php if (isset($loadjs)) :?>
|
||||
<?php if (DEBUG_MODE) : ?>
|
||||
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery-1.4.2.js"></script>
|
||||
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.jstree.js"></script>
|
||||
<?php else: ?>
|
||||
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery-1.4.2.min.js"></script>
|
||||
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.jstree.min.js"></script>
|
||||
<?php endif ?>
|
||||
<script type="text/javascript" src="<?php echo ROOT ?>jsScuttle.php"></script>
|
||||
<?php endif ?>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nihilo">
|
||||
<!-- the class is used by Dojo widgets -->
|
||||
<body>
|
||||
|
||||
<?php
|
||||
$headerstyle = '';
|
||||
|
@ -14,7 +14,14 @@ if ($users && count($users) > 0) {
|
||||
<?php
|
||||
$contents = '<';
|
||||
foreach ($users as $row) {
|
||||
echo '<li><strong>'.$row['username'].'</strong> (<a href="'.createURL('profile', $row['username']).'">'.T_('profile').'</a> '.T_('created in').' '.date('M Y',strtotime($row['uDatetime'])).') : <a href="'.createURL('bookmarks', $row['username']).'">'.T_('bookmarks').'</a></li>';
|
||||
echo '<li><strong>'
|
||||
. SemanticScuttle_Model_UserArray::getName($row) . '</strong>'
|
||||
. ' (<a href="' . createURL('profile', $row['username']) . '">'
|
||||
. T_('profile') . '</a> '
|
||||
. T_('created in') . ' '
|
||||
. date('M Y', strtotime($row['uDatetime'])) . ')'
|
||||
. ' : <a href="' . createURL('bookmarks', $row['username']).'">'
|
||||
. T_('bookmarks') . '</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
|
@ -1,9 +1,34 @@
|
||||
ChangeLog for SemantiScuttle
|
||||
============================
|
||||
|
||||
0.9X.X - 2010-XX-XX
|
||||
0.98.0 - 2011-XX-XX
|
||||
-------------------
|
||||
- Fix bug getTagsForBookmarks() that fetched all tags
|
||||
- Switch to jQuery and drop dojo
|
||||
- Fix bug #3187177: Wrong URL / Export XML Bookmarks
|
||||
- Fix bug in getTagsForBookmarks() that fetched all tags
|
||||
- Implement request #3054906: Show user's full name instead of nickname
|
||||
- Implement patch #3059829: update FR_CA translation
|
||||
- Show error message on mysqli connection errors
|
||||
- Update php-gettext library to 1.0.10
|
||||
- api/posts/add respects the "replace" parameter now
|
||||
- Fix privacy issue when fetching tags of several users
|
||||
|
||||
|
||||
0.97.2 - 2011-02-17
|
||||
-------------------
|
||||
- Fix bug #3178597: Broken link to context in gsearch admin index page
|
||||
- Fix bug #3074816: French translation breaks edit javascript
|
||||
- Fix bug #3111254: Search in my_watchlist results in error
|
||||
- Fix bug #3073215: Updating bookmark time does not work
|
||||
- Fix bug #3065284: AjaxVote problem with Webkit browsers
|
||||
|
||||
|
||||
0.97.1 - 2010-09-30
|
||||
-------------------
|
||||
This is a security release! We do highly recommend to update
|
||||
your SemanticScuttle installations!
|
||||
|
||||
- Fix bug #3077187: Permission problem when deleting bookmarks
|
||||
|
||||
|
||||
0.97.0 - 2010-06-09
|
||||
|
@ -39,7 +39,12 @@
|
||||
- Make users inactive by default when registered newly
|
||||
- have to be activated by admins (see #1926991)
|
||||
- Add RDFa to user profile page
|
||||
- use recaptcha or alike -> quickform
|
||||
- tutorial about sidebar
|
||||
- update php-gettext
|
||||
- index on bookmarks->modified, since created is not used in selects/sort
|
||||
- how to optimize sorts, to prevent mysql filesort? -> index enough?
|
||||
- how to optimize DISTINCT bHash
|
||||
|
||||
|
||||
|
||||
|
10
doc/developers/api
Normal file
10
doc/developers/api
Normal file
@ -0,0 +1,10 @@
|
||||
SemanticScuttle API
|
||||
===================
|
||||
|
||||
SemanticScuttle tries to implement the delicious API v1 as closely as sensible.
|
||||
|
||||
Where it makes sense and the delicious API just does things plainly wrong
|
||||
(i.e. when returning a wrong status code on an error), we do it better.
|
||||
|
||||
- http://www.delicious.com/help/api
|
||||
- http://support.delicious.com/forum/comments.php?DiscussionID=5286&page=1
|
9
doc/developers/doc-TODO
Normal file
9
doc/developers/doc-TODO
Normal file
@ -0,0 +1,9 @@
|
||||
- Bookmarklets: Text selection is used as description
|
||||
- Tag nesting: Paris > France > World
|
||||
- Tag alias: Deutschland = Germany
|
||||
|
||||
|
||||
- Which fields are searched?
|
||||
title, description, private note, username, tags
|
||||
|
||||
- What are [isbn] and so for?
|
@ -4,8 +4,8 @@ How to release a new version of SemanticScuttle
|
||||
0. Run unit tests and verify that all of them pass
|
||||
1. Update doc/ChangeLog
|
||||
2. Update doc/UPGRADE.txt
|
||||
3. Update version in data/templates/about.tpl.php
|
||||
and build.xml
|
||||
3. Update version in data/templates/about.tpl.php,
|
||||
build.xml and doc/README.txt
|
||||
4. Create a release zip file via the build script:
|
||||
Just type "phing".
|
||||
5. Make a test installation from your zip file with a fresh
|
||||
|
@ -21,7 +21,7 @@ We keep one base translation file, data/locales/messages.po.
|
||||
This file is auto-generated via xgettext from all our php source files.
|
||||
In case you added a new string to the code that needs translation,
|
||||
update the base translation file by running
|
||||
> php scripts/update-translation-base.php.
|
||||
> php scripts/update-translation-base.php
|
||||
|
||||
After that has been done, the changes to the base messages.po file
|
||||
need to be merged into the single language translation files,
|
||||
|
1
html.properties
Normal file
1
html.properties
Normal file
@ -0,0 +1 @@
|
||||
html.sflogo = <a href="http://sourceforge.net/projects/semanticscuttle"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=211356&type=10" width="80" height="15" alt="Get SemanticScuttle at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a>
|
26
scripts/database-dump.php
Normal file
26
scripts/database-dump.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* Dumps the semanticscuttle database into a file using mysqldump.
|
||||
*
|
||||
* This file is part of
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header-standalone.php';
|
||||
|
||||
passthru(
|
||||
'mysqldump'
|
||||
. ' -h' . escapeshellarg($GLOBALS['dbhost'])
|
||||
. ' -u' . escapeshellarg($GLOBALS['dbuser'])
|
||||
. ' -p' . escapeshellarg($GLOBALS['dbpass'])
|
||||
. ' ' . escapeshellarg($GLOBALS['dbname'])
|
||||
. ' > semanticscuttle-dump.sql'
|
||||
);
|
||||
?>
|
37
scripts/database-restore.php
Normal file
37
scripts/database-restore.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Restores the semanticscuttle database from a given file.
|
||||
*
|
||||
* This file is part of
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
if (!isset($argv[1])) {
|
||||
echo "Please pass the sql file to restore\n";
|
||||
exit(1);
|
||||
}
|
||||
$file = $argv[1];
|
||||
if (!file_exists($file)) {
|
||||
echo "The file does not exist\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header-standalone.php';
|
||||
|
||||
passthru(
|
||||
'mysql'
|
||||
. ' -h' . escapeshellarg($GLOBALS['dbhost'])
|
||||
. ' -u' . escapeshellarg($GLOBALS['dbuser'])
|
||||
. ' -p' . escapeshellarg($GLOBALS['dbpass'])
|
||||
. ' ' . escapeshellarg($GLOBALS['dbname'])
|
||||
. ' < ' . escapeshellarg($file)
|
||||
);
|
||||
?>
|
48
src/SemanticScuttle/Model/RemoteUser.php
Normal file
48
src/SemanticScuttle/Model/RemoteUser.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
/**
|
||||
* Remote User helper methods.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class SemanticScuttle_Model_RemoteUser
|
||||
{
|
||||
/**
|
||||
* Returns the remote user's IP.
|
||||
*
|
||||
* @return string IP address. NULL if not found.
|
||||
*/
|
||||
public static function getIp()
|
||||
{
|
||||
$ip = null;
|
||||
if (getenv('REMOTE_ADDR')) {
|
||||
$ip = getenv('REMOTE_ADDR');
|
||||
} else if (getenv('HTTP_CLIENT_IP')) {
|
||||
$ip = getenv('HTTP_CLIENT_IP');
|
||||
} else if (getenv('HTTP_X_FORWARDED_FOR')) {
|
||||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -15,7 +15,7 @@
|
||||
|
||||
/**
|
||||
* SemanticScuttle user object.
|
||||
* Rare fields are filled if required.
|
||||
* Rarely used fields are filled if required.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
@ -133,7 +133,8 @@ class SemanticScuttle_Model_User
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user creation time
|
||||
* Returns user creation time.
|
||||
* UTC/Zulu time zone is used.
|
||||
*
|
||||
* @return string Datetime value: "YYYY-MM-DD HH:MM:SS"
|
||||
*/
|
||||
|
41
src/SemanticScuttle/Model/UserArray.php
Normal file
41
src/SemanticScuttle/Model/UserArray.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mostly static methods that help working with a user row array from database.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class SemanticScuttle_Model_UserArray
|
||||
{
|
||||
/**
|
||||
* Returns full user name as specified in the profile if it is set,
|
||||
* otherwise the nickname/loginname is returned.
|
||||
*
|
||||
* @param array $row User row array from database
|
||||
*
|
||||
* @return string Full name or username
|
||||
*/
|
||||
public static function getName($row)
|
||||
{
|
||||
if (isset($row['name']) && $row['name']) {
|
||||
return $row['name'];
|
||||
}
|
||||
return $row['username'];
|
||||
}
|
||||
}
|
||||
?>
|
@ -12,6 +12,7 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
require_once 'SemanticScuttle/Model/RemoteUser.php';
|
||||
|
||||
/**
|
||||
* SemanticScuttle bookmark service.
|
||||
@ -44,6 +45,13 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance. Initializes the table name.
|
||||
*
|
||||
* @param DB $db Database object
|
||||
*
|
||||
* @uses $GLOBALS['tableprefix']
|
||||
*/
|
||||
public function __construct($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
@ -168,7 +176,10 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* Retrieves a bookmark with the given URL.
|
||||
* DOES NOT RESPECT PRIVACY SETTINGS!
|
||||
*
|
||||
* @param string $hash URL
|
||||
* @param string $address URL to get bookmarks for
|
||||
* @param boolean $all Retrieve from all users (true)
|
||||
* or only bookmarks owned by the current
|
||||
* user (false)
|
||||
*
|
||||
* @return mixed Array with bookmark data or false in case
|
||||
* of an error (i.e. not found).
|
||||
@ -176,9 +187,9 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* @uses getBookmarkByHash()
|
||||
* @see getBookmarkByShortname()
|
||||
*/
|
||||
public function getBookmarkByAddress($address)
|
||||
public function getBookmarkByAddress($address, $all = true)
|
||||
{
|
||||
return $this->getBookmarkByHash($this->getHash($address));
|
||||
return $this->getBookmarkByHash($this->getHash($address), $all);
|
||||
}
|
||||
|
||||
|
||||
@ -187,16 +198,19 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* Retrieves a bookmark with the given hash.
|
||||
* DOES NOT RESPECT PRIVACY SETTINGS!
|
||||
*
|
||||
* @param string $hash URL hash
|
||||
* @param string $hash URL hash
|
||||
* @param boolean $all Retrieve from all users (true)
|
||||
* or only bookmarks owned by the current
|
||||
* user (false)
|
||||
*
|
||||
* @return mixed Array with bookmark data or false in case
|
||||
* of an error (i.e. not found).
|
||||
*
|
||||
* @see getHash()
|
||||
*/
|
||||
public function getBookmarkByHash($hash)
|
||||
public function getBookmarkByHash($hash, $all = true)
|
||||
{
|
||||
return $this->_getbookmark('bHash', $hash, true);
|
||||
return $this->_getbookmark('bHash', $hash, $all);
|
||||
}
|
||||
|
||||
|
||||
@ -239,18 +253,18 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
/**
|
||||
* Counts bookmarks for a user.
|
||||
*
|
||||
* @param integer $uId User ID
|
||||
* @param string $range Range of bookmarks:
|
||||
* 'public', 'shared', 'private'
|
||||
* or 'all'
|
||||
* @param integer $uId User ID
|
||||
* @param string $status Bookmark visibility/privacy settings:
|
||||
* 'public', 'shared', 'private'
|
||||
* or 'all'
|
||||
*
|
||||
* @return integer Number of bookmarks
|
||||
*/
|
||||
public function countBookmarks($uId, $range = 'public')
|
||||
public function countBookmarks($uId, $status = 'public')
|
||||
{
|
||||
$sql = 'SELECT COUNT(*) as "0" FROM '. $this->getTableName();
|
||||
$sql.= ' WHERE uId = ' . intval($uId);
|
||||
switch ($range) {
|
||||
switch ($status) {
|
||||
case 'all':
|
||||
//no constraints
|
||||
break;
|
||||
@ -425,7 +439,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* @param string $title Bookmark title
|
||||
* @param string $description Long bookmark description
|
||||
* @param string $privateNote Private note for the user.
|
||||
* @param string $status Bookmark visibility:
|
||||
* @param string $status Bookmark visibility / privacy settings:
|
||||
* 0 - public
|
||||
* 1 - shared
|
||||
* 2 - private
|
||||
@ -453,14 +467,6 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
$address = $this->normalize($address);
|
||||
|
||||
if (getenv('HTTP_CLIENT_IP')) {
|
||||
$ip = getenv('HTTP_CLIENT_IP');
|
||||
} else if (getenv('REMOTE_ADDR')) {
|
||||
$ip = getenv('REMOTE_ADDR');
|
||||
} else {
|
||||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that if date is NULL, then it's added with a date and
|
||||
* time of now, and if it's present,
|
||||
@ -480,7 +486,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
// Set up the SQL insert statement and execute it.
|
||||
$values = array(
|
||||
'uId' => intval($sId),
|
||||
'bIp' => $ip,
|
||||
'bIp' => SemanticScuttle_Model_RemoteUser::getIp(),
|
||||
'bDatetime' => $datetime,
|
||||
'bModified' => $datetime,
|
||||
'bTitle' => $title,
|
||||
@ -548,7 +554,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* @param string $title Bookmark title
|
||||
* @param string $description Long bookmark description
|
||||
* @param string $privateNote Private note for the user.
|
||||
* @param string $status Bookmark visibility:
|
||||
* @param string $status Bookmark visibility / privacy setting:
|
||||
* 0 - public
|
||||
* 1 - shared
|
||||
* 2 - private
|
||||
@ -570,15 +576,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the client's IP address and the date; note that the date is in GMT.
|
||||
if (getenv('HTTP_CLIENT_IP'))
|
||||
$ip = getenv('HTTP_CLIENT_IP');
|
||||
else
|
||||
if (getenv('REMOTE_ADDR'))
|
||||
$ip = getenv('REMOTE_ADDR');
|
||||
else
|
||||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||||
|
||||
// Get the the date; note that the date is in GMT.
|
||||
$moddatetime = gmdate('Y-m-d H:i:s', time());
|
||||
|
||||
$address = $this->normalize($address);
|
||||
@ -589,7 +587,11 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
if ($bookmark['bAddress'] != $address
|
||||
&& $this->bookmarkExists($address, $bookmark['uId'])
|
||||
) {
|
||||
message_die(GENERAL_ERROR, 'Could not update bookmark (URL already existing = '.$address.')', '', __LINE__, __FILE__);
|
||||
message_die(
|
||||
GENERAL_ERROR,
|
||||
'Could not update bookmark (URL already exists: ' . $address . ')',
|
||||
'', __LINE__, __FILE__
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -611,25 +613,33 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
if (!is_null($date)) {
|
||||
$datetime = gmdate('Y-m-d H:i:s', strtotime($date));
|
||||
$updates[] = array('bDateTime' => $datetime);
|
||||
$updates['bDatetime'] = $datetime;
|
||||
}
|
||||
|
||||
$sql = 'UPDATE '. $GLOBALS['tableprefix'] .'bookmarks SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE bId = '. intval($bId);
|
||||
$sql = 'UPDATE '. $GLOBALS['tableprefix'] . 'bookmarks'
|
||||
. ' SET '. $this->db->sql_build_array('UPDATE', $updates)
|
||||
. ' WHERE bId = ' . intval($bId);
|
||||
$this->db->sql_transaction('begin');
|
||||
|
||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not update bookmark', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not update bookmark',
|
||||
'', __LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
}
|
||||
|
||||
$uriparts = explode('.', $address);
|
||||
$uriparts = explode('.', $address);
|
||||
$extension = end($uriparts);
|
||||
unset($uriparts);
|
||||
|
||||
$b2tservice = SemanticScuttle_Service_Factory :: get('Bookmark2Tag');
|
||||
if (!$b2tservice->attachTags($bId, $categories, $fromApi, $extension)) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not update bookmark', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not update bookmark',
|
||||
'', __LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
}
|
||||
|
||||
$this->db->sql_transaction('commit');
|
||||
@ -724,7 +734,8 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
if (SQL_LAYER == 'mysql4') {
|
||||
$query_1 .= 'SQL_CALC_FOUND_ROWS ';
|
||||
}
|
||||
$query_1 .= 'B.*, U.'. $userservice->getFieldName('username');
|
||||
$query_1 .= 'B.*, U.'. $userservice->getFieldName('username')
|
||||
. ', U.name';
|
||||
|
||||
$query_2 = ' FROM '. $userservice->getTableName() .' AS U'
|
||||
. ', '. $this->getTableName() .' AS B';
|
||||
@ -745,7 +756,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
$arrWatch = $userservice->getWatchlist($user);
|
||||
if (count($arrWatch) > 0) {
|
||||
$query_3_1 = '';
|
||||
foreach($arrWatch as $row) {
|
||||
foreach ($arrWatch as $row) {
|
||||
$query_3_1 .= 'B.uId = '. intval($row) .' OR ';
|
||||
}
|
||||
$query_3_1 = substr($query_3_1, 0, -3);
|
||||
@ -756,7 +767,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
}
|
||||
|
||||
$query_5 = '';
|
||||
if($hash == null) {
|
||||
if ($hash == null) {
|
||||
$query_5.= ' GROUP BY B.bHash';
|
||||
}
|
||||
|
||||
@ -804,7 +815,9 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
$query_2 .= ', '. $b2tservice->getTableName() .' AS T'. $i;
|
||||
$query_4 .= ' AND (';
|
||||
|
||||
$allLinkedTags = $tag2tagservice->getAllLinkedTags($this->db->sql_escape($tags[$i]), '>', $user);
|
||||
$allLinkedTags = $tag2tagservice->getAllLinkedTags(
|
||||
$this->db->sql_escape($tags[$i]), '>', $user
|
||||
);
|
||||
|
||||
while (is_array($allLinkedTags) && count($allLinkedTags)>0) {
|
||||
$query_4 .= ' T'. $i .'.tag = "'. array_pop($allLinkedTags) .'"';
|
||||
@ -825,7 +838,8 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
// Search terms in tags as well when none given
|
||||
if (!count($tags)) {
|
||||
$query_2 .= ' LEFT JOIN '. $b2tservice->getTableName() .' AS T ON B.bId = T.bId';
|
||||
$query_2 .= ' LEFT JOIN '. $b2tservice->getTableName() .' AS T'
|
||||
. ' ON B.bId = T.bId';
|
||||
$dotags = true;
|
||||
} else {
|
||||
$dotags = false;
|
||||
@ -833,12 +847,24 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
$query_4 = '';
|
||||
for ($i = 0; $i < count($aTerms); $i++) {
|
||||
$query_4 .= ' AND (B.bTitle LIKE "%'. $this->db->sql_escape($aTerms[$i]) .'%"';
|
||||
$query_4 .= ' OR B.bDescription LIKE "%'. $this->db->sql_escape($aTerms[$i]) .'%"';
|
||||
$query_4 .= ' OR B.bPrivateNote LIKE "'. $this->db->sql_escape($aTerms[$i]) .'%"'; //warning : search in private notes of everybody but private notes won't appear if not allowed.
|
||||
$query_4 .= ' OR U.username = "'. $this->db->sql_escape($aTerms[$i]) .'"'; //exact match for username
|
||||
$query_4 .= ' AND (B.bTitle LIKE "%'
|
||||
. $this->db->sql_escape($aTerms[$i])
|
||||
. '%"';
|
||||
$query_4 .= ' OR B.bDescription LIKE "%'
|
||||
. $this->db->sql_escape($aTerms[$i])
|
||||
. '%"';
|
||||
//warning : search in private notes of everybody
|
||||
// but private notes won't appear if not allowed.
|
||||
$query_4 .= ' OR B.bPrivateNote LIKE "'
|
||||
. $this->db->sql_escape($aTerms[$i])
|
||||
.'%"';
|
||||
$query_4 .= ' OR U.username = "'
|
||||
. $this->db->sql_escape($aTerms[$i])
|
||||
. '"'; //exact match for username
|
||||
if ($dotags) {
|
||||
$query_4 .= ' OR T.tag LIKE "'. $this->db->sql_escape($aTerms[$i]) .'%"';
|
||||
$query_4 .= ' OR T.tag LIKE "'
|
||||
. $this->db->sql_escape($aTerms[$i])
|
||||
. '%"';
|
||||
}
|
||||
$query_4 .= ')';
|
||||
}
|
||||
@ -860,22 +886,35 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
|
||||
$query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
|
||||
|
||||
if (!($dbresult = & $this->db->sql_query_limit($query, intval($perpage), intval($start)))) {
|
||||
message_die(GENERAL_ERROR, 'Could not get bookmarks', '', __LINE__, __FILE__, $query, $this->db);
|
||||
$dbresult = $this->db->sql_query_limit(
|
||||
$query, intval($perpage), intval($start)
|
||||
);
|
||||
if (!$dbresult) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get bookmarks',
|
||||
'', __LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
}
|
||||
|
||||
if (SQL_LAYER == 'mysql4') {
|
||||
$totalquery = 'SELECT FOUND_ROWS() AS total';
|
||||
} else {
|
||||
if ($hash) {
|
||||
$totalquery = 'SELECT COUNT(*) AS total'. $query_2 . $query_3 . $query_4;
|
||||
$totalquery = 'SELECT COUNT(*) AS total'. $query_2
|
||||
. $query_3 . $query_4;
|
||||
} else {
|
||||
$totalquery = 'SELECT COUNT(DISTINCT bAddress) AS total'. $query_2 . $query_3 . $query_4;
|
||||
$totalquery = 'SELECT COUNT(DISTINCT bAddress) AS total'
|
||||
. $query_2 . $query_3 . $query_4;
|
||||
}
|
||||
}
|
||||
|
||||
if (!($totalresult = & $this->db->sql_query($totalquery)) || (!($row = & $this->db->sql_fetchrow($totalresult)))) {
|
||||
message_die(GENERAL_ERROR, 'Could not get total bookmarks', '', __LINE__, __FILE__, $totalquery, $this->db);
|
||||
if (!($totalresult = $this->db->sql_query($totalquery))
|
||||
|| (!($row = $this->db->sql_fetchrow($totalresult)))
|
||||
) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get total bookmarks',
|
||||
'', __LINE__, __FILE__, $totalquery, $this->db
|
||||
);
|
||||
}
|
||||
|
||||
$total = $row['total'];
|
||||
@ -962,10 +1001,14 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
*/
|
||||
public function deleteBookmarksForUser($uId)
|
||||
{
|
||||
$query = 'DELETE FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE uId = '. intval($uId);
|
||||
$query = 'DELETE FROM '. $GLOBALS['tableprefix'] . 'bookmarks'
|
||||
. ' WHERE uId = '. intval($uId);
|
||||
|
||||
if (!($dbresult = & $this->db->sql_query($query))) {
|
||||
message_die(GENERAL_ERROR, 'Could not delete bookmarks', '', __LINE__, __FILE__, $query, $this->db);
|
||||
if (!($dbresult = $this->db->sql_query($query))) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not delete bookmarks',
|
||||
'', __LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -977,12 +1020,6 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* Counts the number of bookmarks that have the same address
|
||||
* as the given address.
|
||||
*
|
||||
* @internal
|
||||
* We do support fetching counts for multiple addresses at once
|
||||
* because that allows us to reduce the number of queries
|
||||
* we need in the web interface when displaying i.e.
|
||||
* 10 bookmarks - only one SQL query is needed then.
|
||||
*
|
||||
* @param string|array $addresses Address/URL to look for, string
|
||||
* of one address or array with
|
||||
* multiple ones
|
||||
@ -991,6 +1028,12 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
* In case $addresses was an array, key-value array
|
||||
* with key being the address, value said number of
|
||||
* bookmarks
|
||||
*
|
||||
* @internal
|
||||
* We do support fetching counts for multiple addresses at once
|
||||
* because that allows us to reduce the number of queries
|
||||
* we need in the web interface when displaying i.e.
|
||||
* 10 bookmarks - only one SQL query is needed then.
|
||||
*/
|
||||
public function countOthers($addresses)
|
||||
{
|
||||
|
@ -454,58 +454,155 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
|
||||
return $output;
|
||||
}
|
||||
|
||||
function &getAdminTags($limit = 30, $logged_on_user = NULL, $days = NULL) {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the tags used by admin users
|
||||
*
|
||||
* @param integer $limit Number of tags to return
|
||||
* @param integer $logged_on_user ID of the user that's currently logged in.
|
||||
* If the logged in user equals the $user to find
|
||||
* tags for, tags of private bookmarks are
|
||||
* returned.
|
||||
* @param integer $days Bookmarks have to be changed in the last X days
|
||||
* if their tags shall count
|
||||
* @param string $beginsWith The tag name shall begin with that string
|
||||
*
|
||||
* @return array Array of found tags. Each tag entry is an array with two keys,
|
||||
* 'tag' (tag name) and 'bCount'.
|
||||
*
|
||||
* @see getPopularTags()
|
||||
*/
|
||||
public function getAdminTags(
|
||||
$limit = 30, $logged_on_user = null, $days = null, $beginsWith = null
|
||||
) {
|
||||
// look for admin ids
|
||||
$userservice = SemanticScuttle_Service_Factory :: get('User');
|
||||
$adminIds = $userservice->getAdminIds();
|
||||
$userservice = SemanticScuttle_Service_Factory::get('User');
|
||||
$adminIds = $userservice->getAdminIds();
|
||||
|
||||
// ask for their tags
|
||||
return $this->getPopularTags($adminIds, $limit, $logged_on_user, $days);
|
||||
return $this->getPopularTags(
|
||||
$adminIds, $limit, $logged_on_user, $days, $beginsWith
|
||||
);
|
||||
}
|
||||
|
||||
function &getContactTags($user, $limit = 30, $logged_on_user = NULL, $days = NULL) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the tags used by users that are part of the user's watchlist,
|
||||
* and the current user's own tags.
|
||||
*
|
||||
* @param integer $user ID of the user to get the watchlist from
|
||||
* @param integer $limit Number of tags to return
|
||||
* @param integer $logged_on_user ID of the user that's currently logged in.
|
||||
* If set, that user is added to the list of
|
||||
* people to get the tags from
|
||||
* @param integer $days Bookmarks have to be changed in the last X days
|
||||
* if their tags shall count
|
||||
* @param string $beginsWith The tag name shall begin with that string
|
||||
*
|
||||
* @return array Array of found tags. Each tag entry is an array with two keys,
|
||||
* 'tag' (tag name) and 'bCount'.
|
||||
*
|
||||
* @see getPopularTags()
|
||||
*/
|
||||
public function getContactTags(
|
||||
$user, $limit = 30, $logged_on_user = null, $days = null,
|
||||
$beginsWith = null
|
||||
) {
|
||||
// look for contact ids
|
||||
$userservice = SemanticScuttle_Service_Factory :: get('User');
|
||||
$userservice = SemanticScuttle_Service_Factory::get('User');
|
||||
$contacts = $userservice->getWatchlist($user);
|
||||
|
||||
// add the user (to show him/her also his/her tags)
|
||||
if(!is_null($logged_on_user)) {
|
||||
// add the user (to show him also his own tags)
|
||||
if (!is_null($logged_on_user)) {
|
||||
$contacts[] = $logged_on_user;
|
||||
}
|
||||
|
||||
// ask for their tags
|
||||
return $this->getPopularTags($contacts, $limit, $logged_on_user, $days);
|
||||
return $this->getPopularTags(
|
||||
$contacts, $limit, $logged_on_user, $days, $beginsWith
|
||||
);
|
||||
}
|
||||
|
||||
// $users can be {NULL, an id, an array of id}
|
||||
function &getPopularTags($user = NULL, $limit = 30, $logged_on_user = NULL, $days = NULL) {
|
||||
|
||||
|
||||
/**
|
||||
* The the most popular tags and their usage count
|
||||
*
|
||||
* @param mixed $user Integer user ID or array of user IDs to limit tag
|
||||
* finding to
|
||||
* @param integer $limit Number of tags to return
|
||||
* @param integer $logged_on_user ID of the user that's currently logged in.
|
||||
* If the logged in user equals the $user to find
|
||||
* tags for, tags of private bookmarks are
|
||||
* returned.
|
||||
* @param integer $days Bookmarks have to be changed in the last X days
|
||||
* if their tags shall count
|
||||
* @param string $beginsWith The tag name shall begin with that string
|
||||
*
|
||||
* @return array Array of found tags. Each tag entry is an array with two keys,
|
||||
* 'tag' (tag name) and 'bCount'.
|
||||
*
|
||||
* @see getAdminTags()
|
||||
* @see getContactTags()
|
||||
*/
|
||||
public function getPopularTags(
|
||||
$user = null, $limit = 30, $logged_on_user = null, $days = null,
|
||||
$beginsWith = null
|
||||
) {
|
||||
// Only count the tags that are visible to the current user.
|
||||
if (($user != $logged_on_user) || is_null($user) || ($user === false))
|
||||
$privacy = ' AND B.bStatus = 0';
|
||||
else
|
||||
$privacy = '';
|
||||
|
||||
if (is_null($days) || !is_int($days))
|
||||
$span = '';
|
||||
else
|
||||
$span = ' AND B.bDatetime > "'. date('Y-m-d H:i:s', time() - (86400 * $days)) .'"';
|
||||
|
||||
$query = 'SELECT T.tag, COUNT(T.bId) AS bCount FROM '. $this->getTableName() .' AS T, '. $GLOBALS['tableprefix'] .'bookmarks AS B WHERE ';
|
||||
if (is_null($user) || ($user === false)) {
|
||||
$query .= 'B.bId = T.bId AND B.bStatus = 0';
|
||||
} elseif(is_array($user)) {
|
||||
$query .= ' (1 = 0'; //tricks
|
||||
foreach($user as $u) {
|
||||
$query .= ' OR B.uId = '. $this->db->sql_escape($u) .' AND B.bId = T.bId';
|
||||
}
|
||||
$query .= ' )';
|
||||
if (($user != $logged_on_user) || is_null($user) || ($user === false)) {
|
||||
$privacy = ' AND B.bStatus = 0';
|
||||
} else {
|
||||
$query .= 'B.uId = '. $this->db->sql_escape($user) .' AND B.bId = T.bId'. $privacy;
|
||||
$privacy = '';
|
||||
}
|
||||
$query .= $span .' AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC, tag';
|
||||
|
||||
if (!($dbresult =& $this->db->sql_query_limit($query, $limit))) {
|
||||
message_die(GENERAL_ERROR, 'Could not get popular tags', '', __LINE__, __FILE__, $query, $this->db);
|
||||
$query = 'SELECT'
|
||||
. ' T.tag, COUNT(T.bId) AS bCount'
|
||||
. ' FROM '
|
||||
. $this->getTableName() . ' AS T'
|
||||
. ', ' . $GLOBALS['tableprefix'] . 'bookmarks AS B'
|
||||
. ' WHERE';
|
||||
|
||||
if (is_null($user) || ($user === false)) {
|
||||
$query .= ' B.bId = T.bId AND B.bStatus = 0';
|
||||
} else if (is_array($user)) {
|
||||
$query .= ' (1 = 0'; //tricks
|
||||
foreach ($user as $u) {
|
||||
if (is_numeric($u)) {
|
||||
$query .= ' OR B.uId = ' . $this->db->sql_escape($u)
|
||||
. ' AND B.bId = T.bId';
|
||||
}
|
||||
}
|
||||
$query .= ' )' . $privacy;
|
||||
} else {
|
||||
$query .= ' B.uId = ' . $this->db->sql_escape($user)
|
||||
. ' AND B.bId = T.bId' . $privacy;
|
||||
}
|
||||
|
||||
if (is_int($days)) {
|
||||
$query .= ' AND B.bDatetime > "'
|
||||
. date('Y-m-d H:i:s', time() - (86400 * $days))
|
||||
. '"';
|
||||
}
|
||||
|
||||
if (!is_null($beginsWith)) {
|
||||
$query .= ' AND T.tag LIKE \''
|
||||
. $this->db->sql_escape($beginsWith)
|
||||
. '%\'';
|
||||
}
|
||||
|
||||
$query .= ' AND LEFT(T.tag, 7) <> "system:"'
|
||||
. ' GROUP BY T.tag'
|
||||
. ' ORDER BY bCount DESC, tag';
|
||||
|
||||
if (!($dbresult = $this->db->sql_query_limit($query, $limit))) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get popular tags',
|
||||
'', __LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -514,6 +611,8 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function hasTag($bookmarkid, $tag) {
|
||||
$query = 'SELECT COUNT(*) AS tCount FROM '. $this->getTableName() .' WHERE bId = '. intval($bookmarkid) .' AND tag ="'. $this->db->sql_escape($tag) .'"';
|
||||
|
||||
@ -592,7 +691,15 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
|
||||
return $output;
|
||||
}
|
||||
|
||||
function deleteAll() {
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all tags in bookmarks2tags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAll()
|
||||
{
|
||||
$query = 'TRUNCATE TABLE `'. $this->getTableName() .'`';
|
||||
$this->db->sql_query($query);
|
||||
}
|
||||
|
@ -26,7 +26,18 @@
|
||||
*/
|
||||
class SemanticScuttle_Service_SearchHistory extends SemanticScuttle_DbService
|
||||
{
|
||||
var $sizeSearchHistory;
|
||||
/**
|
||||
* Size of the search history.
|
||||
* If the number of logged searches is larger than this,
|
||||
* adding a new search will delete the oldest one automatically.
|
||||
*
|
||||
* Use -1 to deactivate automatic deletion.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $sizeSearchHistory;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the single service instance
|
||||
@ -44,109 +55,223 @@ class SemanticScuttle_Service_SearchHistory extends SemanticScuttle_DbService
|
||||
return $instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* Sets $this->sizeSearchHistory to $GLOBALS['sizeSearchHistory'] or 10
|
||||
* if the global variable is not defined.
|
||||
*
|
||||
* @param DB $db Database object
|
||||
*/
|
||||
public function __construct($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->tablename = $GLOBALS['tableprefix'] .'searchhistory';
|
||||
if(isset($GLOBALS['sizeSearchHistory'])) {
|
||||
$this->tablename = $GLOBALS['tableprefix'] . 'searchhistory';
|
||||
if (isset($GLOBALS['sizeSearchHistory'])) {
|
||||
$this->sizeSearchHistory = $GLOBALS['sizeSearchHistory'];
|
||||
} else {
|
||||
$this->sizeSearchHistory = 10;
|
||||
}
|
||||
}
|
||||
|
||||
function addSearch($terms, $range, $nbResults, $uId=0) {
|
||||
if(strlen($terms) == 0) {
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new search to the search history.
|
||||
* Automatically deletes the oldest search when the number of
|
||||
* searches is larger than $sizeSearchHistory.
|
||||
*
|
||||
* @param string $terms Search terms separated by spaces
|
||||
* @param string $range - 'all' - search was in all bookmarks
|
||||
* - 'watchlist' - searched in watchlist
|
||||
* - any username to show that the search happened
|
||||
* in his own bookmarks.
|
||||
* @param integer $nbResults Number of search result rows
|
||||
* @param integer $uId ID of user that searched
|
||||
*
|
||||
* @return boolean True if it has been added, false if not
|
||||
*/
|
||||
public function addSearch($terms, $range, $nbResults, $uId = 0)
|
||||
{
|
||||
if (strlen($terms) == 0) {
|
||||
return false;
|
||||
}
|
||||
$datetime = gmdate('Y-m-d H:i:s', time());
|
||||
|
||||
//Insert values
|
||||
$values = array('shTerms'=>$terms, 'shRange'=>$range, 'shDatetime'=>$datetime, 'shNbResults'=>$nbResults, 'uId'=>$uId);
|
||||
$sql = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values);
|
||||
$values = array(
|
||||
'shTerms' => $terms,
|
||||
'shRange' => $range,
|
||||
'shDatetime' => $datetime,
|
||||
'shNbResults' => $nbResults,
|
||||
'uId' => $uId
|
||||
);
|
||||
$sql = 'INSERT INTO ' . $this->getTableName()
|
||||
. ' ' . $this->db->sql_build_array('INSERT', $values);
|
||||
|
||||
$this->db->sql_transaction('begin');
|
||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||
if (!($dbresult = $this->db->sql_query($sql))) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not insert search history', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not insert search history',
|
||||
'', __LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->sizeSearchHistory != -1 &&
|
||||
$this->countSearches() > $this->sizeSearchHistory) {
|
||||
if ($this->sizeSearchHistory != -1
|
||||
&& $this->countSearches() > $this->sizeSearchHistory
|
||||
) {
|
||||
$this->deleteOldestSearch();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getAllSearches($range = NULL, $uId = NULL, $nb = NULL, $start = NULL, $distinct = false, $withResults = false) {
|
||||
$sql = 'SELECT DISTINCT(shTerms), shId, shRange, shNbResults, shDatetime, uId';
|
||||
|
||||
|
||||
/**
|
||||
* Returns searches with the given features.
|
||||
*
|
||||
* @param string $range - 'all' - search was in all bookmarks
|
||||
* - 'watchlist' - searched in watchlist
|
||||
* - any username to show that the search happened
|
||||
* in his own bookmarks.
|
||||
* @param integer $uId Id of the user who searched. null for any users
|
||||
* @param integer $nb Number of bookmarks to retrieve (paging)
|
||||
* @param integer $start Number of bookmark to begin with (paging)
|
||||
* @param boolean $distinct If the search terms shall be distinct
|
||||
* @param boolean $withResults Only return searches that had at least one result
|
||||
*
|
||||
* @return array Array of search history database rows
|
||||
*/
|
||||
public function getAllSearches(
|
||||
$range = null, $uId = null, $nb = null,
|
||||
$start = null, $distinct = false, $withResults = false
|
||||
) {
|
||||
$sql = 'SELECT DISTINCT(shTerms),'
|
||||
. ' shId, shRange, shNbResults, shDatetime, uId';
|
||||
$sql.= ' FROM '. $this->getTableName();
|
||||
$sql.= ' WHERE 1=1';
|
||||
if($range != NULL) {
|
||||
if ($range != null) {
|
||||
$sql.= ' AND shRange = "'.$range.'"';
|
||||
} else {
|
||||
$sql.= ' AND shRange = "all"';
|
||||
}
|
||||
if($uId != NULL) {
|
||||
if ($uId != null) {
|
||||
$sql.= ' AND uId = '.$uId;
|
||||
}
|
||||
if($withResults = true) {
|
||||
if ($withResults == true) {
|
||||
$sql.= ' AND shNbResults > 0';
|
||||
}
|
||||
if($distinct) {
|
||||
if ($distinct) {
|
||||
$sql.= ' GROUP BY shTerms';
|
||||
}
|
||||
$sql.= ' ORDER BY shId DESC';
|
||||
|
||||
if (!($dbresult = & $this->db->sql_query_limit($sql, $nb, $start))) {
|
||||
message_die(GENERAL_ERROR, 'Could not get searches', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
if (!($dbresult = $this->db->sql_query_limit($sql, $nb, $start))) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get searches',
|
||||
'', __LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$searches = array();
|
||||
while ($row = & $this->db->sql_fetchrow($dbresult)) {
|
||||
while ($row = $this->db->sql_fetchrow($dbresult)) {
|
||||
$searches[] = $row;
|
||||
}
|
||||
$this->db->sql_freeresult($dbresult);
|
||||
return $searches;
|
||||
}
|
||||
|
||||
function countSearches() {
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of searches that have been made in total.
|
||||
*
|
||||
* @return integer Number of searches
|
||||
*/
|
||||
public function countSearches()
|
||||
{
|
||||
$sql = 'SELECT COUNT(*) AS `total` FROM '. $this->getTableName();
|
||||
if (!($dbresult = & $this->db->sql_query($sql)) || (!($row = & $this->db->sql_fetchrow($dbresult)))) {
|
||||
message_die(GENERAL_ERROR, 'Could not get total searches', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
if (!($dbresult = $this->db->sql_query($sql))
|
||||
|| (!($row = & $this->db->sql_fetchrow($dbresult)))
|
||||
) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get total searches',
|
||||
'', __LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$this->db->sql_freeresult($dbresult);
|
||||
return $row['total'];
|
||||
}
|
||||
|
||||
/* This function allows to limit the number of saved searches
|
||||
by deleting the oldest one */
|
||||
function deleteOldestSearch() {
|
||||
|
||||
|
||||
/**
|
||||
* This function allows to limit the number of saved searches
|
||||
* by deleting the oldest one
|
||||
*
|
||||
* @return boolean True when all went well, false in case of an error
|
||||
*/
|
||||
public function deleteOldestSearch()
|
||||
{
|
||||
$sql = 'DELETE FROM '.$this->getTableName();
|
||||
$sql.= ' ORDER BY shId ASC LIMIT 1'; // warning: here the limit is important
|
||||
// warning: here the limit is important
|
||||
$sql .= ' ORDER BY shId ASC LIMIT 1';
|
||||
|
||||
$this->db->sql_transaction('begin');
|
||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||
if (!($dbresult = $this->db->sql_query($sql))) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not delete bookmarks', '', __LINE__, __FILE__, $query, $this->db);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteSearchHistoryForUser($uId) {
|
||||
$query = 'DELETE FROM '. $this->getTableName() .' WHERE uId = '. intval($uId);
|
||||
|
||||
if (!($dbresult = & $this->db->sql_query($query))) {
|
||||
message_die(GENERAL_ERROR, 'Could not delete search history', '',
|
||||
__LINE__, __FILE__, $query, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not delete bookmarks',
|
||||
'', __LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function deleteAll() {
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all search history entries that have been made by the user
|
||||
* with the given ID.
|
||||
*
|
||||
* @param integer $uId ID of the user
|
||||
*
|
||||
* @return boolean True when all went well, false in case of an error
|
||||
*/
|
||||
public function deleteSearchHistoryForUser($uId)
|
||||
{
|
||||
$query = 'DELETE FROM '. $this->getTableName()
|
||||
. ' WHERE uId = ' . intval($uId);
|
||||
|
||||
if (!($dbresult = $this->db->sql_query($query))) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not delete search history', '',
|
||||
__LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all search history entries.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAll()
|
||||
{
|
||||
$query = 'TRUNCATE TABLE `'. $this->getTableName() .'`';
|
||||
$this->db->sql_query($query);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* SemanticScuttle tag-to-tag service.
|
||||
* SemanticScuttle tag-to-tag service which works with tag relations.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
@ -102,18 +102,49 @@ class SemanticScuttle_Service_Tag2Tag extends SemanticScuttle_DbService
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return linked tags just for admin users
|
||||
function getAdminLinkedTags($tag, $relationType, $inverseRelation = false, $stopList = array()) {
|
||||
|
||||
|
||||
/**
|
||||
* Same as getLinkedTags(), but only tags that have been created
|
||||
* by admin users are returned.
|
||||
*
|
||||
* @param string $tag Tag to get related tags for
|
||||
* @param string $relationType Type of tag-to-tag relation: >, < or =
|
||||
* @param boolean $inverseRelation Reverse relation (parent -> child)
|
||||
* @param array $stopList Array of tags that shall not be returned
|
||||
*
|
||||
* @return array Array of tag names
|
||||
*
|
||||
* @see getLinkedTags()
|
||||
*/
|
||||
public function getAdminLinkedTags(
|
||||
$tag, $relationType, $inverseRelation = false, $stopList = array()
|
||||
) {
|
||||
// look for admin ids
|
||||
$userservice = SemanticScuttle_Service_Factory :: get('User');
|
||||
$adminIds = $userservice->getAdminIds();
|
||||
$adminIds = $userservice->getAdminIds();
|
||||
|
||||
//ask for their linked tags
|
||||
return $this->getLinkedTags($tag, $relationType, $adminIds, $inverseRelation, $stopList);
|
||||
return $this->getLinkedTags(
|
||||
$tag, $relationType, $adminIds, $inverseRelation, $stopList
|
||||
);
|
||||
}
|
||||
|
||||
// Return the target linked tags. If inverseRelation is true, return the source linked tags.
|
||||
function getLinkedTags($tag, $relationType, $uId = null, $inverseRelation = false, $stopList = array()) {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tags that are in relation to the given $tag.
|
||||
*
|
||||
* @param string $tag Tag to get related tags for
|
||||
* @param string $relationType Type of tag-to-tag relation: >, < or =
|
||||
* @param boolean $inverseRelation Reverse relation (parent -> child)
|
||||
* @param array $stopList Array of tags that shall not be returned
|
||||
*
|
||||
* @return array Array of tag names
|
||||
*/
|
||||
public function getLinkedTags(
|
||||
$tag, $relationType, $uId = null, $inverseRelation = false, $stopList = array()
|
||||
) {
|
||||
// Set up the SQL query.
|
||||
if($inverseRelation) {
|
||||
$queriedTag = "tag1";
|
||||
|
@ -211,18 +211,26 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
}
|
||||
}
|
||||
|
||||
/* Takes an numerical "id" or a string "username"
|
||||
and returns the numerical "id" if the user exists else returns NULL */
|
||||
function getIdFromUser($user) {
|
||||
/**
|
||||
* Obtains the ID of the given user name.
|
||||
* If a user ID is passed, it is returned.
|
||||
* In case the user does not exist, NULL is returned.
|
||||
*
|
||||
* @param string|integer $user User name or user ID
|
||||
*
|
||||
* @return integer NULL if not found or the user ID
|
||||
*/
|
||||
public function getIdFromUser($user)
|
||||
{
|
||||
if (is_int($user)) {
|
||||
return intval($user);
|
||||
} else {
|
||||
$objectUser = $this->getObjectUserByUsername($user);
|
||||
if($objectUser != NULL) {
|
||||
if ($objectUser != null) {
|
||||
return $objectUser->getId();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,10 +412,10 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
public function getCurrentUserId()
|
||||
{
|
||||
if (isset($_SESSION[$this->getSessionKey()])) {
|
||||
return $_SESSION[$this->getSessionKey()];
|
||||
return (int)$_SESSION[$this->getSessionKey()];
|
||||
|
||||
} else if (isset($_COOKIE[$this->getCookieKey()])) {
|
||||
$cook = split(':', $_COOKIE[$this->getCookieKey()]);
|
||||
$cook = explode(':', $_COOKIE[$this->getCookieKey()]);
|
||||
//cookie looks like this: 'id:md5(username+password)'
|
||||
$query = 'SELECT * FROM '. $this->getTableName() .
|
||||
' WHERE MD5(CONCAT('.$this->getFieldName('username') .
|
||||
@ -425,10 +433,10 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
|
||||
if ($row = $this->db->sql_fetchrow($dbresult)) {
|
||||
$this->setCurrentUserId(
|
||||
$row[$this->getFieldName('primary')]
|
||||
(int)$row[$this->getFieldName('primary')]
|
||||
);
|
||||
$this->db->sql_freeresult($dbresult);
|
||||
return $_SESSION[$this->getSessionKey()];
|
||||
return (int)$_SESSION[$this->getSessionKey()];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -716,7 +724,7 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all bookmarks.
|
||||
* Delete all users and their watch states.
|
||||
* Mainly used in unit tests.
|
||||
*
|
||||
* @return void
|
||||
@ -725,6 +733,9 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
{
|
||||
$query = 'TRUNCATE TABLE `'. $this->getTableName() .'`';
|
||||
$this->db->sql_query($query);
|
||||
|
||||
$query = 'TRUNCATE TABLE `' . $GLOBALS['tableprefix'] . 'watched' . '`';
|
||||
$this->db->sql_query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,34 +1,51 @@
|
||||
<?php
|
||||
/*
|
||||
/**
|
||||
* Define constants used in all the application.
|
||||
* Some constants are based on variables from configuration file.
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @subcategory Base
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
// Debug managament
|
||||
if(isset($GLOBALS['debugMode'])) {
|
||||
define('DEBUG_MODE', $GLOBALS['debugMode']);
|
||||
define('DEBUG_EXTRA', $GLOBALS['debugMode']); // Constant used exclusively into db/ directory
|
||||
if (isset($GLOBALS['debugMode'])) {
|
||||
define('DEBUG_MODE', $GLOBALS['debugMode']);
|
||||
// Constant used exclusively into db/ directory
|
||||
define('DEBUG_EXTRA', $GLOBALS['debugMode']);
|
||||
}
|
||||
|
||||
// Determine the base URL as ROOT
|
||||
if (!isset($GLOBALS['root'])) {
|
||||
$pieces = explode('/', $_SERVER['SCRIPT_NAME']);
|
||||
|
||||
$rootTmp = '/';
|
||||
foreach ($pieces as $piece) {
|
||||
//we eliminate possible sscuttle subfolders (like gsearch for example)
|
||||
if ($piece != '' && !strstr($piece, '.php') && $piece != 'gsearch') {
|
||||
$rootTmp .= $piece .'/';
|
||||
}
|
||||
}
|
||||
if (($rootTmp != '/') && (substr($rootTmp, -1, 1) != '/')) {
|
||||
$rootTmp .= '/';
|
||||
}
|
||||
$pieces = explode('/', $_SERVER['SCRIPT_NAME']);
|
||||
|
||||
define('ROOT', 'http://'. $_SERVER['HTTP_HOST'] . $rootTmp);
|
||||
$rootTmp = '/';
|
||||
foreach ($pieces as $piece) {
|
||||
//we eliminate possible sscuttle subfolders (like gsearch for example)
|
||||
if ($piece != '' && !strstr($piece, '.php')
|
||||
&& $piece != 'gsearch' && $piece != 'ajax'
|
||||
) {
|
||||
$rootTmp .= $piece .'/';
|
||||
}
|
||||
}
|
||||
if (($rootTmp != '/') && (substr($rootTmp, -1, 1) != '/')) {
|
||||
$rootTmp .= '/';
|
||||
}
|
||||
|
||||
define('ROOT', 'http://'. $_SERVER['HTTP_HOST'] . $rootTmp);
|
||||
} else {
|
||||
define('ROOT', $GLOBALS['root']);
|
||||
define('ROOT', $GLOBALS['root']);
|
||||
}
|
||||
define('ROOT_JS', ROOT . 'js/jstree-1.0-rc2/');
|
||||
|
||||
// Error codes
|
||||
define('GENERAL_MESSAGE', 200);
|
||||
@ -44,19 +61,21 @@ define('PAGE_WATCHLIST', "watchlist");
|
||||
|
||||
// Miscellanous
|
||||
|
||||
// INSTALLATION_ID is based on directory DB and used as prefix (in session and cookie) to prevent mutual login for different installations on the same host server
|
||||
// INSTALLATION_ID is based on directory DB and used as prefix
|
||||
// (in session and cookie) to prevent mutual login for different
|
||||
// installations on the same host server
|
||||
define('INSTALLATION_ID', md5($GLOBALS['dbname'].$GLOBALS['tableprefix']));
|
||||
|
||||
// Correct bugs with PATH_INFO (maybe for Apache 1 or CGI) -- for 1&1 host...
|
||||
if (isset($_SERVER['PATH_INFO']) && isset($_SERVER['ORIG_PATH_INFO'])) {
|
||||
if(strlen($_SERVER["PATH_INFO"])<strlen($_SERVER["ORIG_PATH_INFO"])) {
|
||||
$_SERVER["PATH_INFO"] = $_SERVER["ORIG_PATH_INFO"];
|
||||
}
|
||||
if(strcasecmp($_SERVER["PATH_INFO"], $_SERVER["SCRIPT_NAME "]) == 0) {
|
||||
unset($_SERVER["PATH_INFO"]);
|
||||
}
|
||||
if(strpos($_SERVER["PATH_INFO"], '.php') !== false) {
|
||||
unset($_SERVER["PATH_INFO"]);
|
||||
}
|
||||
if (strlen($_SERVER["PATH_INFO"])<strlen($_SERVER["ORIG_PATH_INFO"])) {
|
||||
$_SERVER["PATH_INFO"] = $_SERVER["ORIG_PATH_INFO"];
|
||||
}
|
||||
if (strcasecmp($_SERVER["PATH_INFO"], $_SERVER["SCRIPT_NAME "]) == 0) {
|
||||
unset($_SERVER["PATH_INFO"]);
|
||||
}
|
||||
if (strpos($_SERVER["PATH_INFO"], '.php') !== false) {
|
||||
unset($_SERVER["PATH_INFO"]);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -50,7 +50,7 @@ class sql_db
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sql_error('');
|
||||
return $this->sql_error(mysqli_connect_error());
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -14,9 +14,21 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
if (!file_exists(dirname(__FILE__) .'/../../data/config.php')) {
|
||||
|
||||
if ('@data_dir@' == '@' . 'data_dir@') {
|
||||
//non pear-install
|
||||
$datadir = dirname(__FILE__) . '/../../data/';
|
||||
} else {
|
||||
//pear installation; files are in include path
|
||||
$datadir = '@data_dir@/SemanticScuttle/';
|
||||
}
|
||||
|
||||
if (!file_exists($datadir . '/config.php')) {
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
die('Please copy "config.php.dist" to "config.php" in data/ folder.');
|
||||
die(
|
||||
'Please copy "config.php.dist" to "config.php" in data/ folder.'
|
||||
. "\n"
|
||||
);
|
||||
}
|
||||
set_include_path(
|
||||
get_include_path() . PATH_SEPARATOR
|
||||
@ -24,10 +36,23 @@ set_include_path(
|
||||
);
|
||||
|
||||
// 1 // First requirements part (before debug management)
|
||||
$datadir = dirname(__FILE__) . '/../../data/';
|
||||
require_once $datadir . '/config.default.php';
|
||||
require_once $datadir . '/config.php';
|
||||
|
||||
if (isset($_GET['unittestMode']) && $_GET['unittestMode'] == 1
|
||||
) {
|
||||
if ($allowUnittestMode !== true) {
|
||||
header('HTTP/1.0 400 Bad Request');
|
||||
die("Unittestmode is not allowed\n");
|
||||
}
|
||||
|
||||
$unittestConfigFile = $datadir . '/config.unittest.php';
|
||||
if (file_exists($unittestConfigFile)) {
|
||||
require_once $unittestConfigFile;
|
||||
}
|
||||
define('HTTP_UNIT_TEST_MODE', true);
|
||||
define('UNIT_TEST_MODE', true);
|
||||
}
|
||||
if (defined('UNIT_TEST_MODE')) {
|
||||
//make local config vars global - needed for unit tests
|
||||
//run with phpunit
|
||||
@ -57,6 +82,7 @@ require_once 'SemanticScuttle/Service.php';
|
||||
require_once 'SemanticScuttle/DbService.php';
|
||||
require_once 'SemanticScuttle/Service/Factory.php';
|
||||
require_once 'SemanticScuttle/functions.php';
|
||||
require_once 'SemanticScuttle/Model/UserArray.php';
|
||||
|
||||
if (count($GLOBALS['serviceoverrides']) > 0
|
||||
&& !defined('UNIT_TEST_MODE')
|
||||
@ -106,11 +132,18 @@ $tplVars['currentUser'] = $currentUser;
|
||||
$tplVars['userservice'] = $userservice;
|
||||
|
||||
// 6 // Force UTF-8 behaviour for server (cannot be moved into top.inc.php which is not included into every file)
|
||||
if (!defined('UNIT_TEST_MODE')) {
|
||||
if (!defined('UNIT_TEST_MODE') || defined('HTTP_UNIT_TEST_MODE')) {
|
||||
//API files define that, so we need a way to support both of them
|
||||
if (!isset($httpContentType)) {
|
||||
$httpContentType = 'text/html';
|
||||
//$httpContentType = 'application/xhtml+xml';
|
||||
if (DEBUG_MODE) {
|
||||
//using that mime type makes all javascript nice in Chromium
|
||||
// it also serves as test base if the pages really validate
|
||||
$httpContentType = 'application/xhtml+xml';
|
||||
} else {
|
||||
//until we are sure that all pages validate, we
|
||||
// keep the non-strict mode on for normal installations
|
||||
$httpContentType = 'text/html';
|
||||
}
|
||||
}
|
||||
if ($httpContentType !== false) {
|
||||
header('Content-Type: ' . $httpContentType . '; charset=utf-8');
|
||||
|
@ -1,12 +1,11 @@
|
||||
PACKAGE = php-gettext-$(VERSION)
|
||||
VERSION = 1.0.7
|
||||
VERSION = 1.0.10
|
||||
|
||||
DIST_FILES = \
|
||||
gettext.php \
|
||||
gettext.inc \
|
||||
streams.php \
|
||||
AUTHORS \
|
||||
ChangeLog \
|
||||
README \
|
||||
COPYING \
|
||||
Makefile \
|
||||
@ -17,9 +16,14 @@ DIST_FILES = \
|
||||
examples/locale/sr_CS/LC_MESSAGES/messages.mo \
|
||||
examples/locale/de_CH/LC_MESSAGES/messages.po \
|
||||
examples/locale/de_CH/LC_MESSAGES/messages.mo \
|
||||
examples/update
|
||||
examples/update \
|
||||
tests/LocalesTest.php \
|
||||
tests/ParsingTest.php
|
||||
|
||||
dist:
|
||||
check:
|
||||
phpunit --verbose tests
|
||||
|
||||
dist: check
|
||||
if [ -d $(PACKAGE) ]; then \
|
||||
rm -rf $(PACKAGE); \
|
||||
fi; \
|
||||
@ -30,3 +34,5 @@ dist:
|
||||
rm -rf $(PACKAGE); \
|
||||
fi;
|
||||
|
||||
clean:
|
||||
rm -f $(PACKAGE).tar.gz
|
||||
|
@ -1,9 +1,9 @@
|
||||
PHP-gettext 1.0
|
||||
PHP-gettext 1.0 (https://launchpad.net/php-gettext)
|
||||
|
||||
Copyright 2003, 2006 -- Danilo "angry with PHP[1]" Segan
|
||||
Copyright 2003, 2006, 2009 -- Danilo "angry with PHP[1]" Segan
|
||||
Licensed under GPLv2 (or any later version, see COPYING)
|
||||
|
||||
[1] PHP is actually cyrillic, and translates roughly to
|
||||
[1] PHP is actually cyrillic, and translates roughly to
|
||||
"works-doesn't-work" (UTF-8: Ради-Не-Ради)
|
||||
|
||||
|
||||
@ -50,36 +50,16 @@ Features
|
||||
file data, I used imaginary abstract class StreamReader to do all
|
||||
the input (check streams.php). For your convenience, I've already
|
||||
provided two classes for reading files: FileReader and
|
||||
StringReader (CachedFileReader is a combination of the two: it
|
||||
loads entire file contents into a string, and then works on that).
|
||||
See example below for usage. You can for instance use StringReader
|
||||
when you read in data from a database, or you can create your own
|
||||
derivative of StreamReader for anything you like.
|
||||
|
||||
StringReader (CachedFileReader is a combination of the two: it
|
||||
loads entire file contents into a string, and then works on that).
|
||||
See example below for usage. You can for instance use StringReader
|
||||
when you read in data from a database, or you can create your own
|
||||
derivative of StreamReader for anything you like.
|
||||
|
||||
|
||||
Bugs
|
||||
|
||||
Plural-forms field in MO header (translation for empty string,
|
||||
i.e. "") is treated according to PHP syntactic rules (it's
|
||||
eval()ed). Since these should actually follow C syntax, there are
|
||||
some problems.
|
||||
|
||||
For instance, I'm used to using this:
|
||||
Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : \
|
||||
n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
|
||||
but it fails with PHP (it sets $plural=2 instead of 0 for $n==1).
|
||||
|
||||
The fix is usually simple, but I'm lazy to go into the details of
|
||||
PHP operator precedence, and maybe try to fix it. In here, I had
|
||||
to put everything after the first ':' in parenthesis:
|
||||
Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : \
|
||||
(n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
|
||||
That works, and I'm satisfied.
|
||||
|
||||
Besides this one, there are probably a bunch of other bugs, since
|
||||
I hate PHP (did I mention it already? no? strange), and don't
|
||||
know it very well. So, feel free to fix any of those and report
|
||||
them back to me at <danilo@kvota.net>.
|
||||
Report them on https://bugs.launchpad.net/php-gettext
|
||||
|
||||
Usage
|
||||
|
||||
@ -94,19 +74,19 @@ Usage
|
||||
Then, use that as a parameter to gettext_reader constructor:
|
||||
$wohoo = new gettext_reader($streamer);
|
||||
|
||||
If you want to disable pre-loading of entire message catalog in
|
||||
memory (if, for example, you have a multi-thousand message catalog
|
||||
which you'll use only occasionally), use "false" for second
|
||||
If you want to disable pre-loading of entire message catalog in
|
||||
memory (if, for example, you have a multi-thousand message catalog
|
||||
which you'll use only occasionally), use "false" for second
|
||||
parameter to gettext_reader constructor:
|
||||
$wohoo = new gettext_reader($streamer, false);
|
||||
|
||||
From now on, you have all the benefits of gettext data at your
|
||||
disposal, so may run:
|
||||
disposal, so may run:
|
||||
print $wohoo->translate("This is a test");
|
||||
print $wohoo->ngettext("%d bird", "%d birds", $birds);
|
||||
|
||||
You might need to pass parameter "-k" to xgettext to make it
|
||||
extract all the strings. In above example, try with
|
||||
extract all the strings. In above example, try with
|
||||
xgettext -ktranslate -kngettext:1,2 file.php
|
||||
what should create messages.po which contains two messages for
|
||||
translation.
|
||||
@ -118,8 +98,8 @@ Usage
|
||||
|
||||
Usage with gettext.inc (standard gettext interfaces emulation)
|
||||
|
||||
Check example in examples/pig_dropin.php, basically you include
|
||||
gettext.inc and use all the standard gettext interfaces as
|
||||
Check example in examples/pig_dropin.php, basically you include
|
||||
gettext.inc and use all the standard gettext interfaces as
|
||||
documented on:
|
||||
|
||||
http://www.php.net/gettext
|
||||
@ -137,20 +117,12 @@ Example
|
||||
There is also simple "update" script that can be used to generate
|
||||
POT file and to update the translation using msgmerge.
|
||||
|
||||
Interesting TODO:
|
||||
TODO:
|
||||
|
||||
o Try to parse "plural-forms" header field, and to follow C syntax
|
||||
rules. This won't be easy.
|
||||
o Improve speed to be even more comparable to the native gettext
|
||||
implementation.
|
||||
|
||||
Boring TODO:
|
||||
|
||||
o Learn PHP and fix bugs, slowness and other stuff resulting from
|
||||
my lack of knowledge (but *maybe*, it's not my knowledge that is
|
||||
bad, but PHP itself ;-).
|
||||
|
||||
(This is mostly done thanks to Nico Kaiser.)
|
||||
|
||||
o Try to use hash tables in MO files: with pre-loading, would it
|
||||
o Try to use hash tables in MO files: with pre-loading, would it
|
||||
be useful at all?
|
||||
|
||||
Never-asked-questions:
|
||||
@ -160,7 +132,7 @@ Never-asked-questions:
|
||||
|
||||
Well, it's quite simple. I consider that the first released thing
|
||||
should be labeled "version 1" (first, right?). Zero is there to
|
||||
indicate that there's zero improvement and/or change compared to
|
||||
indicate that there's zero improvement and/or change compared to
|
||||
"version 1".
|
||||
|
||||
I plan to use version numbers 1.0.* for small bugfixes, and to
|
||||
@ -173,7 +145,7 @@ Never-asked-questions:
|
||||
Mozart's 40th Symphony (there is one like that, right?).
|
||||
|
||||
o Can I...?
|
||||
|
||||
|
||||
Yes, you can. This is free software (as in freedom, free speech),
|
||||
and you might do whatever you wish with it, provided you do not
|
||||
limit freedom of others (GPL).
|
||||
|
Binary file not shown.
@ -12,7 +12,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#: pigs.php:19
|
||||
msgid ""
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003,2004,2005 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2003,2004,2005,2009 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2005,2006 Steven Armstrong <sa@c-area.ch>
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
@ -21,10 +21,12 @@
|
||||
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// define constants
|
||||
define(PROJECT_DIR, realpath('./'));
|
||||
define(LOCALE_DIR, PROJECT_DIR .'/locale');
|
||||
define(DEFAULT_LOCALE, 'en_US');
|
||||
define('PROJECT_DIR', realpath('./'));
|
||||
define('LOCALE_DIR', PROJECT_DIR .'/locale');
|
||||
define('DEFAULT_LOCALE', 'en_US');
|
||||
|
||||
require_once('../gettext.inc');
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003,2004,2005 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2003,2004,2005,2009 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2005,2006 Steven Armstrong <sa@c-area.ch>
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
@ -21,10 +21,12 @@
|
||||
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// define constants
|
||||
define(PROJECT_DIR, realpath('./'));
|
||||
define(LOCALE_DIR, PROJECT_DIR .'/locale');
|
||||
define(DEFAULT_LOCALE, 'en_US');
|
||||
define('PROJECT_DIR', realpath('./'));
|
||||
define('LOCALE_DIR', PROJECT_DIR .'/locale');
|
||||
define('DEFAULT_LOCALE', 'en_US');
|
||||
|
||||
require_once('../gettext.inc');
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
TEMPLATE=pigs.pot
|
||||
xgettext -kT_ngettext:1,2 -kT_ -L PHP -o $TEMPLATE pigs.php
|
||||
if [ x$1 == 'x-p' ]; then
|
||||
xgettext -kT_ngettext:1,2 -kT_ -L PHP -o $TEMPLATE pigs_dropin.php
|
||||
if [ "x$1" = "x-p" ]; then
|
||||
msgfmt --statistics $TEMPLATE
|
||||
else
|
||||
if [ -f $1.po ]; then
|
||||
|
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
|
||||
|
||||
Copyright (c) 2009 Danilo Segan <danilo@kvota.net>
|
||||
|
||||
Drop in replacement for native gettext.
|
||||
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
|
||||
PHP-gettext is free software; you can redistribute it and/or modify
|
||||
@ -22,15 +23,22 @@
|
||||
|
||||
*/
|
||||
/*
|
||||
LC_CTYPE 0
|
||||
LC_NUMERIC 1
|
||||
LC_TIME 2
|
||||
LC_COLLATE 3
|
||||
LC_MONETARY 4
|
||||
LC_MESSAGES 5
|
||||
LC_ALL 6
|
||||
LC_CTYPE 0
|
||||
LC_NUMERIC 1
|
||||
LC_TIME 2
|
||||
LC_COLLATE 3
|
||||
LC_MONETARY 4
|
||||
LC_MESSAGES 5
|
||||
LC_ALL 6
|
||||
*/
|
||||
|
||||
|
||||
// LC_MESSAGES is not available if php-gettext is not loaded
|
||||
// while the other constants are already available from session extension.
|
||||
if (!defined('LC_MESSAGES')) {
|
||||
define('LC_MESSAGES', 5);
|
||||
}
|
||||
|
||||
require('streams.php');
|
||||
require('gettext.php');
|
||||
|
||||
@ -44,29 +52,96 @@ $LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MO
|
||||
$EMULATEGETTEXT = 0;
|
||||
$CURRENTLOCALE = '';
|
||||
|
||||
/* Class to hold a single domain included in $text_domains. */
|
||||
class domain {
|
||||
var $l10n;
|
||||
var $path;
|
||||
var $codeset;
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
|
||||
/**
|
||||
* Return a list of locales to try for any POSIX-style locale specification.
|
||||
*/
|
||||
function get_list_of_locales($locale) {
|
||||
/* Figure out all possible locale names and start with the most
|
||||
* specific ones. I.e. for sr_CS.UTF-8@latin, look through all of
|
||||
* sr_CS.UTF-8@latin, sr_CS@latin, sr@latin, sr_CS.UTF-8, sr_CS, sr.
|
||||
*/
|
||||
$locale_names = array();
|
||||
$lang = NULL;
|
||||
$country = NULL;
|
||||
$charset = NULL;
|
||||
$modifier = NULL;
|
||||
if ($locale) {
|
||||
if (preg_match("/^(?P<lang>[a-z]{2,3})" // language code
|
||||
."(?:_(?P<country>[A-Z]{2}))?" // country code
|
||||
."(?:\.(?P<charset>[-A-Za-z0-9_]+))?" // charset
|
||||
."(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/", // @ modifier
|
||||
$locale, $matches)) {
|
||||
|
||||
if (isset($matches["lang"])) $lang = $matches["lang"];
|
||||
if (isset($matches["country"])) $country = $matches["country"];
|
||||
if (isset($matches["charset"])) $charset = $matches["charset"];
|
||||
if (isset($matches["modifier"])) $modifier = $matches["modifier"];
|
||||
|
||||
if ($modifier) {
|
||||
if ($country) {
|
||||
if ($charset)
|
||||
array_push($locale_names, "${lang}_$country.$charset@$modifier");
|
||||
array_push($locale_names, "${lang}_$country@$modifier");
|
||||
} elseif ($charset)
|
||||
array_push($locale_names, "${lang}.$charset@$modifier");
|
||||
array_push($locale_names, "$lang@$modifier");
|
||||
}
|
||||
if ($country) {
|
||||
if ($charset)
|
||||
array_push($locale_names, "${lang}_$country.$charset");
|
||||
array_push($locale_names, "${lang}_$country");
|
||||
} elseif ($charset)
|
||||
array_push($locale_names, "${lang}.$charset");
|
||||
array_push($locale_names, $lang);
|
||||
}
|
||||
|
||||
// If the locale name doesn't match POSIX style, just include it as-is.
|
||||
if (!in_array($locale, $locale_names))
|
||||
array_push($locale_names, $locale);
|
||||
}
|
||||
return $locale_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to get a StreamReader for the given text domain.
|
||||
*/
|
||||
function _get_reader($domain=null, $category=5, $enable_cache=true) {
|
||||
global $text_domains, $default_domain, $LC_CATEGORIES;
|
||||
if (!isset($domain)) $domain = $default_domain;
|
||||
if (!isset($text_domains[$domain]->l10n)) {
|
||||
// get the current locale
|
||||
$locale = _setlocale(LC_MESSAGES, 0);
|
||||
$p = isset($text_domains[$domain]->path) ? $text_domains[$domain]->path : './';
|
||||
$path = $p . "$locale/". $LC_CATEGORIES[$category] ."/$domain.mo";
|
||||
if (file_exists($path)) {
|
||||
$input = new FileReader($path);
|
||||
}
|
||||
else {
|
||||
$input = null;
|
||||
}
|
||||
$text_domains[$domain]->l10n = new gettext_reader($input, $enable_cache);
|
||||
}
|
||||
return $text_domains[$domain]->l10n;
|
||||
global $text_domains, $default_domain, $LC_CATEGORIES;
|
||||
if (!isset($domain)) $domain = $default_domain;
|
||||
if (!isset($text_domains[$domain]->l10n)) {
|
||||
// get the current locale
|
||||
$locale = _setlocale(LC_MESSAGES, 0);
|
||||
$bound_path = isset($text_domains[$domain]->path) ?
|
||||
$text_domains[$domain]->path : './';
|
||||
$subpath = $LC_CATEGORIES[$category] ."/$domain.mo";
|
||||
|
||||
$locale_names = get_list_of_locales($locale);
|
||||
$input = null;
|
||||
foreach ($locale_names as $locale) {
|
||||
$full_path = $bound_path . $locale . "/" . $subpath;
|
||||
if (file_exists($full_path)) {
|
||||
$input = new FileReader($full_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!array_key_exists($domain, $text_domains)) {
|
||||
// Initialize an empty domain object.
|
||||
$text_domains[$domain] = new domain();
|
||||
}
|
||||
$text_domains[$domain]->l10n = new gettext_reader($input,
|
||||
$enable_cache);
|
||||
}
|
||||
return $text_domains[$domain]->l10n;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,8 +155,10 @@ function locale_emulation() {
|
||||
/**
|
||||
* Checks if the current locale is supported on this system.
|
||||
*/
|
||||
function _check_locale() {
|
||||
function _check_locale_and_function($function=false) {
|
||||
global $EMULATEGETTEXT;
|
||||
if ($function and !function_exists($function))
|
||||
return false;
|
||||
return !$EMULATEGETTEXT;
|
||||
}
|
||||
|
||||
@ -89,56 +166,70 @@ function _check_locale() {
|
||||
* Get the codeset for the given domain.
|
||||
*/
|
||||
function _get_codeset($domain=null) {
|
||||
global $text_domains, $default_domain, $LC_CATEGORIES;
|
||||
if (!isset($domain)) $domain = $default_domain;
|
||||
return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
|
||||
global $text_domains, $default_domain, $LC_CATEGORIES;
|
||||
if (!isset($domain)) $domain = $default_domain;
|
||||
return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given string to the encoding set by bind_textdomain_codeset.
|
||||
*/
|
||||
function _encode($text) {
|
||||
$source_encoding = mb_detect_encoding($text);
|
||||
$target_encoding = _get_codeset();
|
||||
if ($source_encoding != $target_encoding) {
|
||||
return mb_convert_encoding($text, $target_encoding, $source_encoding);
|
||||
}
|
||||
else {
|
||||
return $text;
|
||||
}
|
||||
$source_encoding = mb_detect_encoding($text);
|
||||
$target_encoding = _get_codeset();
|
||||
if ($source_encoding != $target_encoding) {
|
||||
return mb_convert_encoding($text, $target_encoding, $source_encoding);
|
||||
}
|
||||
else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Custom implementation of the standard gettext related functions
|
||||
|
||||
/**
|
||||
* Returns passed in $locale, or environment variable $LANG if $locale == ''.
|
||||
*/
|
||||
function _get_default_locale($locale) {
|
||||
if ($locale == '') // emulate variable support
|
||||
return getenv('LANG');
|
||||
else
|
||||
return $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a requested locale, if needed emulates it.
|
||||
*/
|
||||
function _setlocale($category, $locale) {
|
||||
global $CURRENTLOCALE, $EMULATEGETTEXT;
|
||||
if ($locale === 0) { // use === to differentiate between string "0"
|
||||
if ($CURRENTLOCALE != '')
|
||||
if ($CURRENTLOCALE != '')
|
||||
return $CURRENTLOCALE;
|
||||
else
|
||||
else
|
||||
// obey LANG variable, maybe extend to support all of LC_* vars
|
||||
// even if we tried to read locale without setting it first
|
||||
return _setlocale($category, $CURRENTLOCALE);
|
||||
} else {
|
||||
$ret = 0;
|
||||
if (function_exists('setlocale')) // I don't know if this ever happens ;)
|
||||
$ret = @setlocale($category, $locale); //the @ hides warning messages on few installations
|
||||
if (($ret and $locale == '') or ($ret == $locale)) {
|
||||
$EMULATEGETTEXT = 0;
|
||||
$CURRENTLOCALE = $ret;
|
||||
} else {
|
||||
if ($locale == '') // emulate variable support
|
||||
$CURRENTLOCALE = getenv('LANG');
|
||||
else
|
||||
$CURRENTLOCALE = $locale;
|
||||
if (function_exists('setlocale')) {
|
||||
$ret = setlocale($category, $locale);
|
||||
if (($locale == '' and !$ret) or // failed setting it by env
|
||||
($locale != '' and $ret != $locale)) { // failed setting it
|
||||
// Failed setting it according to environment.
|
||||
$CURRENTLOCALE = _get_default_locale($locale);
|
||||
$EMULATEGETTEXT = 1;
|
||||
} else {
|
||||
$CURRENTLOCALE = $ret;
|
||||
$EMULATEGETTEXT = 0;
|
||||
}
|
||||
} else {
|
||||
// No function setlocale(), emulate it all.
|
||||
$CURRENTLOCALE = _get_default_locale($locale);
|
||||
$EMULATEGETTEXT = 1;
|
||||
}
|
||||
// Allow locale to be changed on the go for one translation domain.
|
||||
global $text_domains, $default_domain;
|
||||
unset($text_domains[$default_domain]->l10n);
|
||||
return $CURRENTLOCALE;
|
||||
}
|
||||
}
|
||||
@ -147,135 +238,240 @@ function _setlocale($category, $locale) {
|
||||
* Sets the path for a domain.
|
||||
*/
|
||||
function _bindtextdomain($domain, $path) {
|
||||
global $text_domains;
|
||||
// ensure $path ends with a slash
|
||||
if ($path[strlen($path) - 1] != '/') $path .= '/';
|
||||
elseif ($path[strlen($path) - 1] != '\\') $path .= '\\';
|
||||
$text_domains[$domain]->path = $path;
|
||||
global $text_domains;
|
||||
// ensure $path ends with a slash ('/' should work for both, but lets still play nice)
|
||||
if (substr(php_uname(), 0, 7) == "Windows") {
|
||||
if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/')
|
||||
$path .= '\\';
|
||||
} else {
|
||||
if ($path[strlen($path)-1] != '/')
|
||||
$path .= '/';
|
||||
}
|
||||
if (!array_key_exists($domain, $text_domains)) {
|
||||
// Initialize an empty domain object.
|
||||
$text_domains[$domain] = new domain();
|
||||
}
|
||||
$text_domains[$domain]->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
|
||||
*/
|
||||
function _bind_textdomain_codeset($domain, $codeset) {
|
||||
global $text_domains;
|
||||
$text_domains[$domain]->codeset = $codeset;
|
||||
global $text_domains;
|
||||
$text_domains[$domain]->codeset = $codeset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default domain.
|
||||
*/
|
||||
function _textdomain($domain) {
|
||||
global $default_domain;
|
||||
$default_domain = $domain;
|
||||
global $default_domain;
|
||||
$default_domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a message in the current domain.
|
||||
*/
|
||||
function _gettext($msgid) {
|
||||
$l10n = _get_reader();
|
||||
//return $l10n->translate($msgid);
|
||||
return _encode($l10n->translate($msgid));
|
||||
$l10n = _get_reader();
|
||||
return _encode($l10n->translate($msgid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for gettext.
|
||||
*/
|
||||
function __($msgid) {
|
||||
return _gettext($msgid);
|
||||
return _gettext($msgid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plural version of gettext.
|
||||
*/
|
||||
function _ngettext($single, $plural, $number) {
|
||||
$l10n = _get_reader();
|
||||
//return $l10n->ngettext($single, $plural, $number);
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
$l10n = _get_reader();
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the current domain.
|
||||
*/
|
||||
function _dgettext($domain, $msgid) {
|
||||
$l10n = _get_reader($domain);
|
||||
//return $l10n->translate($msgid);
|
||||
return _encode($l10n->translate($msgid));
|
||||
$l10n = _get_reader($domain);
|
||||
return _encode($l10n->translate($msgid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plural version of dgettext.
|
||||
*/
|
||||
function _dngettext($domain, $single, $plural, $number) {
|
||||
$l10n = _get_reader($domain);
|
||||
//return $l10n->ngettext($single, $plural, $number);
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
$l10n = _get_reader($domain);
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the domain and category for a single lookup.
|
||||
*/
|
||||
function _dcgettext($domain, $msgid, $category) {
|
||||
$l10n = _get_reader($domain, $category);
|
||||
//return $l10n->translate($msgid);
|
||||
return _encode($l10n->translate($msgid));
|
||||
$l10n = _get_reader($domain, $category);
|
||||
return _encode($l10n->translate($msgid));
|
||||
}
|
||||
/**
|
||||
* Plural version of dcgettext.
|
||||
*/
|
||||
function _dcngettext($domain, $single, $plural, $number, $category) {
|
||||
$l10n = _get_reader($domain, $category);
|
||||
//return $l10n->ngettext($single, $plural, $number);
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
$l10n = _get_reader($domain, $category);
|
||||
return _encode($l10n->ngettext($single, $plural, $number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Context version of gettext.
|
||||
*/
|
||||
function _pgettext($context, $msgid) {
|
||||
$l10n = _get_reader();
|
||||
return _encode($l10n->pgettext($context, $msgid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the current domain in a context gettext call.
|
||||
*/
|
||||
function _dpgettext($domain, $context, $msgid) {
|
||||
$l10n = _get_reader($domain);
|
||||
return _encode($l10n->pgettext($context, $msgid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the domain and category for a single context-based lookup.
|
||||
*/
|
||||
function _dcpgettext($domain, $context, $msgid, $category) {
|
||||
$l10n = _get_reader($domain, $category);
|
||||
return _encode($l10n->pgettext($context, $msgid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Context version of ngettext.
|
||||
*/
|
||||
function _npgettext($context, $singular, $plural) {
|
||||
$l10n = _get_reader();
|
||||
return _encode($l10n->npgettext($context, $singular, $plural));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the current domain in a context ngettext call.
|
||||
*/
|
||||
function _dnpgettext($domain, $context, $singular, $plural) {
|
||||
$l10n = _get_reader($domain);
|
||||
return _encode($l10n->npgettext($context, $singular, $plural));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the domain and category for a plural context-based lookup.
|
||||
*/
|
||||
function _dcnpgettext($domain, $context, $singular, $plural, $category) {
|
||||
$l10n = _get_reader($domain, $category);
|
||||
return _encode($l10n->npgettext($context, $singular, $plural));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Wrappers to use if the standard gettext functions are available, but the current locale is not supported by the system.
|
||||
// Use the standard impl if the current locale is supported, use the custom impl otherwise.
|
||||
// Wrappers to use if the standard gettext functions are available,
|
||||
// but the current locale is not supported by the system.
|
||||
// Use the standard impl if the current locale is supported, use the
|
||||
// custom impl otherwise.
|
||||
|
||||
function T_setlocale($category, $locale) {
|
||||
return _setlocale($category, $locale);
|
||||
}
|
||||
|
||||
function T_bindtextdomain($domain, $path) {
|
||||
if (_check_locale()) return bindtextdomain($domain, $path);
|
||||
else return _bindtextdomain($domain, $path);
|
||||
if (_check_locale_and_function()) return bindtextdomain($domain, $path);
|
||||
else return _bindtextdomain($domain, $path);
|
||||
}
|
||||
function T_bind_textdomain_codeset($domain, $codeset) {
|
||||
// bind_textdomain_codeset is available only in PHP 4.2.0+
|
||||
if (_check_locale() and function_exists('bind_textdomain_codeset')) return bind_textdomain_codeset($domain, $codeset);
|
||||
else return _bind_textdomain_codeset($domain, $codeset);
|
||||
if (_check_locale_and_function('bind_textdomain_codeset'))
|
||||
return bind_textdomain_codeset($domain, $codeset);
|
||||
else return _bind_textdomain_codeset($domain, $codeset);
|
||||
}
|
||||
function T_textdomain($domain) {
|
||||
if (_check_locale()) return textdomain($domain);
|
||||
else return _textdomain($domain);
|
||||
if (_check_locale_and_function()) return textdomain($domain);
|
||||
else return _textdomain($domain);
|
||||
}
|
||||
function T_gettext($msgid) {
|
||||
if (_check_locale()) return gettext($msgid);
|
||||
else return _gettext($msgid);
|
||||
if (_check_locale_and_function()) return gettext($msgid);
|
||||
else return _gettext($msgid);
|
||||
}
|
||||
function T_($msgid) {
|
||||
if (_check_locale()) return _($msgid);
|
||||
return __($msgid);
|
||||
if (_check_locale_and_function()) return _($msgid);
|
||||
return __($msgid);
|
||||
}
|
||||
function T_ngettext($single, $plural, $number) {
|
||||
if (_check_locale()) return ngettext($single, $plural, $number);
|
||||
else return _ngettext($single, $plural, $number);
|
||||
if (_check_locale_and_function())
|
||||
return ngettext($single, $plural, $number);
|
||||
else return _ngettext($single, $plural, $number);
|
||||
}
|
||||
function T_dgettext($domain, $msgid) {
|
||||
if (_check_locale()) return dgettext($domain, $msgid);
|
||||
else return _dgettext($domain, $msgid);
|
||||
if (_check_locale_and_function()) return dgettext($domain, $msgid);
|
||||
else return _dgettext($domain, $msgid);
|
||||
}
|
||||
function T_dngettext($domain, $single, $plural, $number) {
|
||||
if (_check_locale()) return dngettext($domain, $single, $plural, $number);
|
||||
else return _dngettext($domain, $single, $plural, $number);
|
||||
if (_check_locale_and_function())
|
||||
return dngettext($domain, $single, $plural, $number);
|
||||
else return _dngettext($domain, $single, $plural, $number);
|
||||
}
|
||||
function T_dcgettext($domain, $msgid, $category) {
|
||||
if (_check_locale()) return dcgettext($domain, $msgid, $category);
|
||||
else return _dcgettext($domain, $msgid, $category);
|
||||
if (_check_locale_and_function())
|
||||
return dcgettext($domain, $msgid, $category);
|
||||
else return _dcgettext($domain, $msgid, $category);
|
||||
}
|
||||
function T_dcngettext($domain, $single, $plural, $number, $category) {
|
||||
if (_check_locale()) return dcngettext($domain, $single, $plural, $number, $category);
|
||||
else return _dcngettext($domain, $single, $plural, $number, $category);
|
||||
if (_check_locale_and_function())
|
||||
return dcngettext($domain, $single, $plural, $number, $category);
|
||||
else return _dcngettext($domain, $single, $plural, $number, $category);
|
||||
}
|
||||
|
||||
function T_pgettext($context, $msgid) {
|
||||
if (_check_locale_and_function('pgettext'))
|
||||
return pgettext($context, $msgid);
|
||||
else
|
||||
return _pgettext($context, $msgid);
|
||||
}
|
||||
|
||||
function T_dpgettext($domain, $context, $msgid) {
|
||||
if (_check_locale_and_function('dpgettext'))
|
||||
return dpgettext($domain, $context, $msgid);
|
||||
else
|
||||
return _dpgettext($domain, $context, $msgid);
|
||||
}
|
||||
|
||||
function T_dcpgettext($domain, $context, $msgid, $category) {
|
||||
if (_check_locale_and_function('dcpgettext'))
|
||||
return dcpgettext($domain, $context, $msgid, $category);
|
||||
else
|
||||
return _dcpgettext($domain, $context, $msgid, $category);
|
||||
}
|
||||
|
||||
function T_npgettext($context, $singular, $plural) {
|
||||
if (_check_locale_and_function('npgettext'))
|
||||
return npgettext($context, $single, $plural, $number);
|
||||
else
|
||||
return _npgettext($context, $single, $plural, $number);
|
||||
}
|
||||
|
||||
function T_dnpgettext($domain, $context, $singular, $plural) {
|
||||
if (_check_locale_and_function('dnpgettext'))
|
||||
return dnpgettext($domain, $context, $single, $plural, $number);
|
||||
else
|
||||
return _dnpgettext($domain, $context, $single, $plural, $number);
|
||||
}
|
||||
|
||||
function T_dcnpgettext($domain, $context, $singular, $plural, $category) {
|
||||
if (_check_locale_and_function('dcnpgettext'))
|
||||
return dcnpgettext($domain, $context, $single,
|
||||
$plural, $number, $category);
|
||||
else
|
||||
return _dcnpgettext($domain, $context, $single,
|
||||
$plural, $number, $category);
|
||||
}
|
||||
|
||||
|
||||
@ -283,36 +479,56 @@ function T_dcngettext($domain, $single, $plural, $number, $category) {
|
||||
// Wrappers used as a drop in replacement for the standard gettext functions
|
||||
|
||||
if (!function_exists('gettext')) {
|
||||
function bindtextdomain($domain, $path) {
|
||||
return _bindtextdomain($domain, $path);
|
||||
}
|
||||
function bind_textdomain_codeset($domain, $codeset) {
|
||||
return _bind_textdomain_codeset($domain, $codeset);
|
||||
}
|
||||
function textdomain($domain) {
|
||||
return _textdomain($domain);
|
||||
}
|
||||
function gettext($msgid) {
|
||||
return _gettext($msgid);
|
||||
}
|
||||
function _($msgid) {
|
||||
return __($msgid);
|
||||
}
|
||||
function ngettext($single, $plural, $number) {
|
||||
return _ngettext($single, $plural, $number);
|
||||
}
|
||||
function dgettext($domain, $msgid) {
|
||||
return _dgettext($domain, $msgid);
|
||||
}
|
||||
function dngettext($domain, $single, $plural, $number) {
|
||||
return _dngettext($domain, $single, $plural, $number);
|
||||
}
|
||||
function dcgettext($domain, $msgid, $category) {
|
||||
return _dcgettext($domain, $msgid, $category);
|
||||
}
|
||||
function dcngettext($domain, $single, $plural, $number, $category) {
|
||||
return _dcngettext($domain, $single, $plural, $number, $category);
|
||||
}
|
||||
function bindtextdomain($domain, $path) {
|
||||
return _bindtextdomain($domain, $path);
|
||||
}
|
||||
function bind_textdomain_codeset($domain, $codeset) {
|
||||
return _bind_textdomain_codeset($domain, $codeset);
|
||||
}
|
||||
function textdomain($domain) {
|
||||
return _textdomain($domain);
|
||||
}
|
||||
function gettext($msgid) {
|
||||
return _gettext($msgid);
|
||||
}
|
||||
function _($msgid) {
|
||||
return __($msgid);
|
||||
}
|
||||
function ngettext($single, $plural, $number) {
|
||||
return _ngettext($single, $plural, $number);
|
||||
}
|
||||
function dgettext($domain, $msgid) {
|
||||
return _dgettext($domain, $msgid);
|
||||
}
|
||||
function dngettext($domain, $single, $plural, $number) {
|
||||
return _dngettext($domain, $single, $plural, $number);
|
||||
}
|
||||
function dcgettext($domain, $msgid, $category) {
|
||||
return _dcgettext($domain, $msgid, $category);
|
||||
}
|
||||
function dcngettext($domain, $single, $plural, $number, $category) {
|
||||
return _dcngettext($domain, $single, $plural, $number, $category);
|
||||
}
|
||||
function pgettext($context, $msgid) {
|
||||
return _pgettext($context, $msgid);
|
||||
}
|
||||
function npgettext($context, $single, $plural, $number) {
|
||||
return _npgettext($context, $single, $plural, $number);
|
||||
}
|
||||
function dpgettext($domain, $context, $msgid) {
|
||||
return _dpgettext($domain, $context, $msgid);
|
||||
}
|
||||
function dnpgettext($domain, $context, $single, $plural, $number) {
|
||||
return _dnpgettext($domain, $context, $single, $plural, $number);
|
||||
}
|
||||
function dcpgettext($domain, $context, $msgid, $category) {
|
||||
return _dcpgettext($domain, $context, $msgid, $category);
|
||||
}
|
||||
function dcnpgettext($domain, $context, $single, $plural,
|
||||
$number, $category) {
|
||||
return _dcnpgettext($domain, $context, $single, $plural,
|
||||
$number, $category);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2003, 2009 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
|
||||
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
|
||||
PHP-gettext is free software; you can redistribute it and/or modify
|
||||
@ -20,13 +20,13 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Provides a simple gettext replacement that works independently from
|
||||
* the system's gettext abilities.
|
||||
* It can read MO files and use them for translating strings.
|
||||
* The files are passed to gettext_reader as a Stream (see streams.php)
|
||||
*
|
||||
*
|
||||
* This version has the ability to cache all strings and translations to
|
||||
* speed up the string lookup.
|
||||
* While the cache is enabled by default, it can be switched off with the
|
||||
@ -36,7 +36,7 @@
|
||||
class gettext_reader {
|
||||
//public:
|
||||
var $error = 0; // public variable that holds error code (0 if no error)
|
||||
|
||||
|
||||
//private:
|
||||
var $BYTEORDER = 0; // 0: low endian, 1: big endian
|
||||
var $STREAM = NULL;
|
||||
@ -52,27 +52,33 @@ class gettext_reader {
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32bit Integer from the Stream
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @return Integer from the Stream
|
||||
*/
|
||||
function readint() {
|
||||
if ($this->BYTEORDER == 0) {
|
||||
// low endian
|
||||
return array_shift(unpack('V', $this->STREAM->read(4)));
|
||||
$input=unpack('V', $this->STREAM->read(4));
|
||||
return array_shift($input);
|
||||
} else {
|
||||
// big endian
|
||||
return array_shift(unpack('N', $this->STREAM->read(4)));
|
||||
$input=unpack('N', $this->STREAM->read(4));
|
||||
return array_shift($input);
|
||||
}
|
||||
}
|
||||
|
||||
function read($bytes) {
|
||||
return $this->STREAM->read($bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an array of Integers from the Stream
|
||||
*
|
||||
*
|
||||
* @param int count How many elements should be read
|
||||
* @return Array of Integers
|
||||
*/
|
||||
@ -85,10 +91,10 @@ class gettext_reader {
|
||||
return unpack('N'.$count, $this->STREAM->read(4 * $count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param object Reader the StreamReader object
|
||||
* @param boolean enable_cache Enable or disable caching of strings (default on)
|
||||
*/
|
||||
@ -98,39 +104,37 @@ class gettext_reader {
|
||||
$this->short_circuit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Caching can be turned off
|
||||
$this->enable_cache = $enable_cache;
|
||||
|
||||
// $MAGIC1 = (int)0x950412de; //bug in PHP 5
|
||||
$MAGIC1 = (int) - 1794895138;
|
||||
// $MAGIC2 = (int)0xde120495; //bug
|
||||
$MAGIC2 = (int) - 569244523;
|
||||
$MAGIC1 = "\x95\x04\x12\xde";
|
||||
$MAGIC2 = "\xde\x12\x04\x95";
|
||||
|
||||
$this->STREAM = $Reader;
|
||||
$magic = $this->readint();
|
||||
if ($magic == $MAGIC1 || $magic == ($MAGIC1 & 0xFFFFFFFF)) {
|
||||
$this->BYTEORDER = 0;
|
||||
} elseif ($magic == $MAGIC2 || $magic == ($MAGIC2 & 0xFFFFFFFF)) {
|
||||
$magic = $this->read(4);
|
||||
if ($magic == $MAGIC1) {
|
||||
$this->BYTEORDER = 1;
|
||||
} elseif ($magic == $MAGIC2) {
|
||||
$this->BYTEORDER = 0;
|
||||
} else {
|
||||
$this->error = 1; // not MO file
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Do we care about revision? We should.
|
||||
$revision = $this->readint();
|
||||
|
||||
|
||||
$this->total = $this->readint();
|
||||
$this->originals = $this->readint();
|
||||
$this->translations = $this->readint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the translation tables from the MO file into the cache
|
||||
* If caching is enabled, also loads all strings into a cache
|
||||
* to speed up translation lookups
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function load_tables() {
|
||||
@ -138,13 +142,17 @@ class gettext_reader {
|
||||
is_array($this->table_originals) &&
|
||||
is_array($this->table_translations))
|
||||
return;
|
||||
|
||||
|
||||
/* get original and translations tables */
|
||||
$this->STREAM->seekto($this->originals);
|
||||
$this->table_originals = $this->readintarray($this->total * 2);
|
||||
$this->STREAM->seekto($this->translations);
|
||||
$this->table_translations = $this->readintarray($this->total * 2);
|
||||
|
||||
if (!is_array($this->table_originals)) {
|
||||
$this->STREAM->seekto($this->originals);
|
||||
$this->table_originals = $this->readintarray($this->total * 2);
|
||||
}
|
||||
if (!is_array($this->table_translations)) {
|
||||
$this->STREAM->seekto($this->translations);
|
||||
$this->table_translations = $this->readintarray($this->total * 2);
|
||||
}
|
||||
|
||||
if ($this->enable_cache) {
|
||||
$this->cache_translations = array ();
|
||||
/* read all strings in the cache */
|
||||
@ -157,10 +165,10 @@ class gettext_reader {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string from the "originals" table
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @param int num Offset number of original string
|
||||
* @return string Requested string if found, otherwise ''
|
||||
@ -174,10 +182,10 @@ class gettext_reader {
|
||||
$data = $this->STREAM->read($length);
|
||||
return (string)$data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string from the "translations" table
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @param int num Offset number of original string
|
||||
* @return string Requested string if found, otherwise ''
|
||||
@ -191,10 +199,10 @@ class gettext_reader {
|
||||
$data = $this->STREAM->read($length);
|
||||
return (string)$data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Binary search for string
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @param string string
|
||||
* @param int start (internally used in recursive function)
|
||||
@ -232,10 +240,10 @@ class gettext_reader {
|
||||
return $this->find_string($string, $half, $end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates a string
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @param string string to be translated
|
||||
* @return string translated string (or original, if not found)
|
||||
@ -243,8 +251,8 @@ class gettext_reader {
|
||||
function translate($string) {
|
||||
if ($this->short_circuit)
|
||||
return $string;
|
||||
$this->load_tables();
|
||||
|
||||
$this->load_tables();
|
||||
|
||||
if ($this->enable_cache) {
|
||||
// Caching enabled, get translated string from cache
|
||||
if (array_key_exists($string, $this->cache_translations))
|
||||
@ -261,17 +269,66 @@ class gettext_reader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize plural form expression for use in PHP eval call.
|
||||
*
|
||||
* @access private
|
||||
* @return string sanitized plural form expression
|
||||
*/
|
||||
function sanitize_plural_expression($expr) {
|
||||
// Get rid of disallowed characters.
|
||||
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);
|
||||
|
||||
// Add parenthesis for tertiary '?' operator.
|
||||
$expr .= ';';
|
||||
$res = '';
|
||||
$p = 0;
|
||||
for ($i = 0; $i < strlen($expr); $i++) {
|
||||
$ch = $expr[$i];
|
||||
switch ($ch) {
|
||||
case '?':
|
||||
$res .= ' ? (';
|
||||
$p++;
|
||||
break;
|
||||
case ':':
|
||||
$res .= ') : (';
|
||||
break;
|
||||
case ';':
|
||||
$res .= str_repeat( ')', $p) . ';';
|
||||
$p = 0;
|
||||
break;
|
||||
default:
|
||||
$res .= $ch;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse full PO header and extract only plural forms line.
|
||||
*
|
||||
* @access private
|
||||
* @return string verbatim plural form header field
|
||||
*/
|
||||
function extract_plural_forms_header_from_po_header($header) {
|
||||
if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs))
|
||||
$expr = $regs[2];
|
||||
else
|
||||
$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
|
||||
return $expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get possible plural forms from MO header
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @return string plural form header
|
||||
*/
|
||||
function get_plural_forms() {
|
||||
// lets assume message number 0 is header
|
||||
// lets assume message number 0 is header
|
||||
// this is true, right?
|
||||
$this->load_tables();
|
||||
|
||||
|
||||
// cache header field for plural forms
|
||||
if (! is_string($this->pluralheader)) {
|
||||
if ($this->enable_cache) {
|
||||
@ -279,18 +336,15 @@ class gettext_reader {
|
||||
} else {
|
||||
$header = $this->get_translation_string(0);
|
||||
}
|
||||
if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
|
||||
$expr = $regs[1];
|
||||
else
|
||||
$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
|
||||
$this->pluralheader = $expr;
|
||||
$expr = $this->extract_plural_forms_header_from_po_header($header);
|
||||
$this->pluralheader = $this->sanitize_plural_expression($expr);
|
||||
}
|
||||
return $this->pluralheader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects which plural form to take
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @param n count
|
||||
* @return int array index of the right plural form
|
||||
@ -300,7 +354,7 @@ class gettext_reader {
|
||||
$string = str_replace('nplurals',"\$total",$string);
|
||||
$string = str_replace("n",$n,$string);
|
||||
$string = str_replace('plural',"\$plural",$string);
|
||||
|
||||
|
||||
$total = 0;
|
||||
$plural = 0;
|
||||
|
||||
@ -311,7 +365,7 @@ class gettext_reader {
|
||||
|
||||
/**
|
||||
* Plural version of gettext
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @param string single
|
||||
* @param string plural
|
||||
@ -327,12 +381,12 @@ class gettext_reader {
|
||||
}
|
||||
|
||||
// find out the appropriate form
|
||||
$select = $this->select_string($number);
|
||||
|
||||
$select = $this->select_string($number);
|
||||
|
||||
// this should contains all strings separated by NULLs
|
||||
$key = $single.chr(0).$plural;
|
||||
|
||||
|
||||
$key = $single . chr(0) . $plural;
|
||||
|
||||
|
||||
if ($this->enable_cache) {
|
||||
if (! array_key_exists($key, $this->cache_translations)) {
|
||||
return ($number != 1) ? $plural : $single;
|
||||
@ -353,6 +407,15 @@ class gettext_reader {
|
||||
}
|
||||
}
|
||||
|
||||
function pgettext($context, $msgid) {
|
||||
$key = $context . chr(4) . $msgid;
|
||||
return $this->translate($key);
|
||||
}
|
||||
|
||||
function npgettext($context, $singular, $plural, $number) {
|
||||
$singular = $context . chr(4) . $singular;
|
||||
return $this->ngettext($singular, $plural, $number);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2003, 2005 Danilo Segan <danilo@kvota.net>.
|
||||
Copyright (c) 2003, 2005, 2006, 2009 Danilo Segan <danilo@kvota.net>.
|
||||
|
||||
This file is part of PHP-gettext.
|
||||
|
||||
@ -21,29 +21,29 @@
|
||||
*/
|
||||
|
||||
|
||||
// Simple class to wrap file streams, string streams, etc.
|
||||
// seek is essential, and it should be byte stream
|
||||
// Simple class to wrap file streams, string streams, etc.
|
||||
// seek is essential, and it should be byte stream
|
||||
class StreamReader {
|
||||
// should return a string [FIXME: perhaps return array of bytes?]
|
||||
function read($bytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// should return new position
|
||||
function seekto($position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns current position
|
||||
function currentpos() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns length of entire stream (limit for seekto()s)
|
||||
function length() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class StringReader {
|
||||
var $_pos;
|
||||
@ -78,7 +78,7 @@ class StringReader {
|
||||
return strlen($this->_str);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FileReader {
|
||||
@ -93,8 +93,8 @@ class FileReader {
|
||||
$this->_pos = 0;
|
||||
$this->_fd = fopen($filename,'rb');
|
||||
if (!$this->_fd) {
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->error = 2; // File doesn't exist
|
||||
@ -115,7 +115,7 @@ class FileReader {
|
||||
$bytes -= strlen($chunk);
|
||||
}
|
||||
$this->_pos = ftell($this->_fd);
|
||||
|
||||
|
||||
return $data;
|
||||
} else return '';
|
||||
}
|
||||
@ -138,9 +138,9 @@ class FileReader {
|
||||
fclose($this->_fd);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Preloads entire file in memory first, then creates a StringReader
|
||||
// Preloads entire file in memory first, then creates a StringReader
|
||||
// over it (it assumes knowledge of StringReader internals)
|
||||
class CachedFileReader extends StringReader {
|
||||
function CachedFileReader($filename) {
|
||||
@ -150,8 +150,8 @@ class CachedFileReader extends StringReader {
|
||||
$fd = fopen($filename,'rb');
|
||||
|
||||
if (!$fd) {
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
$this->error = 3; // Cannot read file, probably permissions
|
||||
return false;
|
||||
}
|
||||
$this->_str = fread($fd, $length);
|
||||
fclose($fd);
|
||||
@ -161,7 +161,7 @@ class CachedFileReader extends StringReader {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
?>
|
||||
|
66
src/php-gettext/tests/LocalesTest.php
Normal file
66
src/php-gettext/tests/LocalesTest.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
require_once('PHPUnit/Framework.php');
|
||||
require_once('gettext.inc');
|
||||
|
||||
class LocaleTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function test_setlocale()
|
||||
{
|
||||
// _setlocale defaults to a locale name from environment variable LANG.
|
||||
putenv("LANG=sr_RS");
|
||||
$this->assertEquals('sr_RS', _setlocale(LC_MESSAGES, 0));
|
||||
|
||||
// For an existing locale, it never needs emulation.
|
||||
putenv("LANG=C");
|
||||
_setlocale(LC_MESSAGES, "");
|
||||
$this->assertEquals(0, locale_emulation());
|
||||
|
||||
// If we set it to a non-existent locale, it still works, but uses
|
||||
// emulation.
|
||||
_setlocale(LC_MESSAGES, "xxx_XXX");
|
||||
$this->assertEquals('xxx_XXX', _setlocale(LC_MESSAGES, 0));
|
||||
$this->assertEquals(1, locale_emulation());
|
||||
}
|
||||
|
||||
public function test_get_list_of_locales()
|
||||
{
|
||||
// For a locale containing country code, we prefer
|
||||
// full locale name, but if that's not found, fall back
|
||||
// to the language only locale name.
|
||||
$this->assertEquals(array("sr_RS", "sr"),
|
||||
get_list_of_locales("sr_RS"));
|
||||
|
||||
// If language code is used, it's the only thing returned.
|
||||
$this->assertEquals(array("sr"),
|
||||
get_list_of_locales("sr"));
|
||||
|
||||
// There is support for language and charset only.
|
||||
$this->assertEquals(array("sr.UTF-8", "sr"),
|
||||
get_list_of_locales("sr.UTF-8"));
|
||||
|
||||
// It can also split out character set from the full locale name.
|
||||
$this->assertEquals(array("sr_RS.UTF-8", "sr_RS", "sr"),
|
||||
get_list_of_locales("sr_RS.UTF-8"));
|
||||
|
||||
// There is support for @modifier in locale names as well.
|
||||
$this->assertEquals(array("sr_RS.UTF-8@latin", "sr_RS@latin", "sr@latin",
|
||||
"sr_RS.UTF-8", "sr_RS", "sr"),
|
||||
get_list_of_locales("sr_RS.UTF-8@latin"));
|
||||
|
||||
// We can pass in only language and modifier.
|
||||
$this->assertEquals(array("sr@latin", "sr"),
|
||||
get_list_of_locales("sr@latin"));
|
||||
|
||||
|
||||
// If locale name is not following the regular POSIX pattern,
|
||||
// it's used verbatim.
|
||||
$this->assertEquals(array("something"),
|
||||
get_list_of_locales("something"));
|
||||
|
||||
// Passing in an empty string returns an empty array.
|
||||
$this->assertEquals(array(),
|
||||
get_list_of_locales(""));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
43
src/php-gettext/tests/ParsingTest.php
Normal file
43
src/php-gettext/tests/ParsingTest.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
require_once('PHPUnit/Framework.php');
|
||||
//require_once('gettext.php');
|
||||
|
||||
class ParsingTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function test_extract_plural_forms_header_from_po_header()
|
||||
{
|
||||
$parser = new gettext_reader(NULL);
|
||||
// It defaults to a "Western-style" plural header.
|
||||
$this->assertEquals(
|
||||
'nplurals=2; plural=n == 1 ? 0 : 1;',
|
||||
$parser->extract_plural_forms_header_from_po_header(""));
|
||||
|
||||
// Extracting it from the middle of the header works.
|
||||
$this->assertEquals(
|
||||
'nplurals=1; plural=0;',
|
||||
$parser->extract_plural_forms_header_from_po_header(
|
||||
"Content-type: text/html; charset=UTF-8\n"
|
||||
."Plural-Forms: nplurals=1; plural=0;\n"
|
||||
."Last-Translator: nobody\n"
|
||||
));
|
||||
|
||||
// It's also case-insensitive.
|
||||
$this->assertEquals(
|
||||
'nplurals=1; plural=0;',
|
||||
$parser->extract_plural_forms_header_from_po_header(
|
||||
"PLURAL-forms: nplurals=1; plural=0;\n"
|
||||
));
|
||||
|
||||
// It falls back to default if it's not on a separate line.
|
||||
$this->assertEquals(
|
||||
'nplurals=2; plural=n == 1 ? 0 : 1;',
|
||||
$parser->extract_plural_forms_header_from_po_header(
|
||||
"Content-type: text/html; charset=UTF-8" // note the missing \n here
|
||||
."Plural-Forms: nplurals=1; plural=0;\n"
|
||||
."Last-Translator: nobody\n"
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
@ -17,9 +17,6 @@ if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
require_once 'PHPUnit/Framework/TestSuite.php';
|
||||
|
||||
PHPUnit_Util_Filter::addFileToFilter(__FILE__);
|
||||
|
||||
/**
|
||||
* SemanticScuttle unit tests.
|
||||
@ -64,6 +61,10 @@ class AllTests extends PHPUnit_Framework_TestSuite
|
||||
$suite->addTestFile($tdir . '/TagTest.php');
|
||||
$suite->addTestFile($tdir . '/VoteTest.php');
|
||||
$suite->addTestFile($tdir . '/UserTest.php');
|
||||
$suite->addTestFile($tdir . '/Api/ExportCsvTest.php');
|
||||
$suite->addTestFile($tdir . '/Api/PostsAddTest.php');
|
||||
$suite->addTestFile($tdir . '/Api/PostsDeleteTest.php');
|
||||
$suite->addTestFile($tdir . '/Api/PostsUpdateTest.php');
|
||||
return $suite;
|
||||
}
|
||||
|
||||
|
435
tests/Api/PostsAddTest.php
Normal file
435
tests/Api/PostsAddTest.php
Normal file
@ -0,0 +1,435 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Api_PostsAddTest::main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle post addition API.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class Api_PostsAddTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'api/posts/add';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to run this test class standalone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function main()
|
||||
{
|
||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||
PHPUnit_TextUI_TestRunner::run(
|
||||
new PHPUnit_Framework_TestSuite(__CLASS__)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending no auth data
|
||||
*/
|
||||
public function testAuthWithoutAuthData()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending wrong user data
|
||||
*/
|
||||
public function testAuthWrongCredentials()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$req->setAuth('user', 'password', HTTP_Request2::AUTH_BASIC);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if adding a bookmark via POST works.
|
||||
*/
|
||||
public function testAddBookmarkPost()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bmUrl = 'http://example.org/tag-1';
|
||||
$bmTags = array('foo', 'bar', 'baz');
|
||||
$bmDatetime = '2010-09-08T03:02:01Z';
|
||||
$bmTitle = 'This is a foo title';
|
||||
$bmDescription = <<<TXT
|
||||
This is the description of
|
||||
my bookmark with some
|
||||
newlines and <some>?&\$ÄÖ'"§special"'
|
||||
characters
|
||||
TXT;
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $bmUrl);
|
||||
$req->addPostParameter('description', $bmTitle);
|
||||
$req->addPostParameter('extended', $bmDescription);
|
||||
$req->addPostParameter('tags', implode(' ', $bmTags));
|
||||
$req->addPostParameter('dt', $bmDatetime);
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user should have one bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$bm = $data['bookmarks'][0];
|
||||
|
||||
$this->assertEquals($bmUrl, $bm['bAddress']);
|
||||
$this->assertEquals($bmTitle, $bm['bTitle']);
|
||||
$this->assertEquals($bmDescription, $bm['bDescription']);
|
||||
$this->assertEquals($bmTags, $bm['tags']);
|
||||
$this->assertEquals(
|
||||
gmdate('Y-m-d H:i:s', strtotime($bmDatetime)),
|
||||
$bm['bDatetime']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if adding a bookmark via GET works.
|
||||
*/
|
||||
public function testAddBookmarkGet()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bmUrl = 'http://example.org/tag-1';
|
||||
$bmTags = array('foo', 'bar', 'baz');
|
||||
$bmDatetime = '2010-09-08T03:02:01Z';
|
||||
$bmTitle = 'This is a foo title';
|
||||
$bmDescription = <<<TXT
|
||||
This is the description of
|
||||
my bookmark with some
|
||||
newlines and <some>?&\$ÄÖ'"§special"'
|
||||
characters
|
||||
TXT;
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest(
|
||||
'?url=' . urlencode($bmUrl)
|
||||
. '&description=' . urlencode($bmTitle)
|
||||
. '&extended=' . urlencode($bmDescription)
|
||||
. '&tags=' . urlencode(implode(' ', $bmTags))
|
||||
. '&dt=' . urlencode($bmDatetime)
|
||||
);
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user should have one bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$bm = $data['bookmarks'][0];
|
||||
|
||||
$this->assertEquals($bmUrl, $bm['bAddress']);
|
||||
$this->assertEquals($bmTitle, $bm['bTitle']);
|
||||
$this->assertEquals($bmDescription, $bm['bDescription']);
|
||||
$this->assertEquals($bmTags, $bm['tags']);
|
||||
$this->assertEquals(
|
||||
gmdate('Y-m-d H:i:s', strtotime($bmDatetime)),
|
||||
$bm['bDatetime']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the URL and description/title are enough parameters
|
||||
* to add a bookmark.
|
||||
*/
|
||||
public function testUrlDescEnough()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', 'http://example.org/tag2');
|
||||
$req->addPostParameter('description', 'foo bar');
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user has 1 bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the URL is required
|
||||
*/
|
||||
public function testUrlRequired()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
//$req->addPostParameter('url', 'http://example.org/tag2');
|
||||
$req->addPostParameter('description', 'foo bar');
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(400, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'URL missing')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user still has 0 bookmarks
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the description/title is required
|
||||
*/
|
||||
public function testDescriptionRequired()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', 'http://example.org/tag2');
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(400, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'Description missing')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user still has 0 bookmarks
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the replace=no parameter prevents the bookmark from being
|
||||
* overwritten.
|
||||
*/
|
||||
public function testReplaceNo()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$url = 'http://example.org/tag2';
|
||||
$title1 = 'foo bar 1';
|
||||
$title2 = 'bar 2 foo';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $url);
|
||||
$req->addPostParameter('description', $title1);
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
|
||||
//send it a second time, with different title
|
||||
list($req, $dummy) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $url);
|
||||
$req->addPostParameter('description', $title2);
|
||||
$req->addPostParameter('replace', 'no');
|
||||
$res = $req->send();
|
||||
|
||||
//this time we should get an error
|
||||
$this->assertEquals(409, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'bookmark does already exist')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user still has 1 bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$this->assertEquals($title1, $data['bookmarks'][0]['bTitle']);
|
||||
|
||||
//send it a third time, without the replace parameter
|
||||
// it defaults to "no", so the bookmark should not get overwritten
|
||||
list($req, $dummy) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $url);
|
||||
$req->addPostParameter('description', $title2);
|
||||
$res = $req->send();
|
||||
|
||||
//this time we should get an error
|
||||
$this->assertEquals(409, $res->getStatus());
|
||||
|
||||
//bookmark should not have changed
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$this->assertEquals($title1, $data['bookmarks'][0]['bTitle']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the replace=yes parameter causes the bookmark to be updated.
|
||||
*/
|
||||
public function testReplaceYes()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$url = 'http://example.org/tag2';
|
||||
$title1 = 'foo bar 1';
|
||||
$title2 = 'bar 2 foo';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $url);
|
||||
$req->addPostParameter('description', $title1);
|
||||
$res = $req->send();
|
||||
|
||||
//all should be well
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
|
||||
//send it a second time, with different title
|
||||
list($req, $dummy) = $this->getAuthRequest();
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $url);
|
||||
$req->addPostParameter('description', $title2);
|
||||
$req->addPostParameter('replace', 'yes');
|
||||
$res = $req->send();
|
||||
|
||||
//no error
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//user still has 1 bookmark now, but with the new title
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$this->assertEquals($title2, $data['bookmarks'][0]['bTitle']);
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Api_PostsAddTest::main') {
|
||||
Api_PostsAddTest::main();
|
||||
}
|
||||
?>
|
303
tests/Api/PostsDeleteTest.php
Normal file
303
tests/Api/PostsDeleteTest.php
Normal file
@ -0,0 +1,303 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Api_PostsDeleteTest::main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle post deletion API.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class Api_PostsDeleteTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'api/posts/delete';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to run this test class standalone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function main()
|
||||
{
|
||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||
PHPUnit_TextUI_TestRunner::run(
|
||||
new PHPUnit_Framework_TestSuite(__CLASS__)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending no auth data
|
||||
*/
|
||||
public function testAuthWithoutAuthData()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending wrong user data
|
||||
|
||||
*/
|
||||
public function testAuthWrongCredentials()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$req->setAuth('user', 'password', HTTP_Request2::AUTH_BASIC);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if deleting an own bookmark works.
|
||||
*/
|
||||
public function testDeleteOwnBookmark()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bookmarkUrl = 'http://example.org/tag-1';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest(
|
||||
'?url=' . urlencode($bookmarkUrl)
|
||||
);
|
||||
|
||||
$bId = $this->addBookmark(
|
||||
$uId, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
//user has one bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
|
||||
//send request
|
||||
$res = $req->send();
|
||||
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//bookmark should be deleted now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if deleting an own bookmark via POST works.
|
||||
*/
|
||||
public function testDeleteOwnBookmarkPost()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bookmarkUrl = 'http://example.org/tag-1';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
|
||||
$bId = $this->addBookmark(
|
||||
$uId, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
//user has one bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
|
||||
//send request
|
||||
$req->setMethod(HTTP_Request2::METHOD_POST);
|
||||
$req->addPostParameter('url', $bookmarkUrl);
|
||||
$res = $req->send();
|
||||
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
null, false
|
||||
);
|
||||
|
||||
//bookmark should be deleted now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verify that deleting a bookmark of a different does not work
|
||||
*/
|
||||
public function testDeleteOtherBookmark()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bookmarkUrl = 'http://example.org/tag-1';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest(
|
||||
'?url=' . urlencode($bookmarkUrl)
|
||||
);
|
||||
$uId2 = $this->addUser();
|
||||
|
||||
$bId = $this->addBookmark(
|
||||
$uId2, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
//user 1 has no bookmarks
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
//user 2 has one bookmark
|
||||
$data = $this->bs->getBookmarks(0, null, $uId2);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
|
||||
//send request
|
||||
$res = $req->send();
|
||||
|
||||
//404 - user does not have that bookmark
|
||||
$this->assertEquals(404, $res->getStatus());
|
||||
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'item not found')
|
||||
),
|
||||
$res->getBody(),
|
||||
'', false
|
||||
);
|
||||
|
||||
//bookmark should still be there
|
||||
$data = $this->bs->getBookmarks(0, null, $uId2);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if deleting a bookmark works that also other users
|
||||
* bookmarked.
|
||||
*/
|
||||
public function testDeleteBookmarkOneOfTwo()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$bookmarkUrl = 'http://example.org/tag-1';
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest(
|
||||
'?url=' . urlencode($bookmarkUrl)
|
||||
);
|
||||
$uId2 = $this->addUser();
|
||||
$uId3 = $this->addUser();
|
||||
|
||||
//important: the order of addition is crucial here
|
||||
$this->addBookmark(
|
||||
$uId2, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
$bId = $this->addBookmark(
|
||||
$uId, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
$this->addBookmark(
|
||||
$uId3, $bookmarkUrl, 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
|
||||
//user one and two have a bookmark now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$data = $this->bs->getBookmarks(0, null, $uId2);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
|
||||
//send request
|
||||
$res = $req->send();
|
||||
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'result',
|
||||
'attributes' => array('code' => 'done')
|
||||
),
|
||||
$res->getBody(),
|
||||
'', false
|
||||
);
|
||||
|
||||
//bookmark should be deleted now
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(0, $data['total']);
|
||||
//user 2 should still have his
|
||||
$data = $this->bs->getBookmarks(0, null, $uId2);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
//user 3 should still have his, too
|
||||
$data = $this->bs->getBookmarks(0, null, $uId3);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Api_PostsDeleteTest::main') {
|
||||
Api_PostsDeleteTest::main();
|
||||
}
|
||||
?>
|
135
tests/Api/PostsUpdateTest.php
Normal file
135
tests/Api/PostsUpdateTest.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Api_PostsUpdateTest::main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle last-update time API.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class Api_PostsUpdateTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'api/posts/update';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to run this test class standalone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function main()
|
||||
{
|
||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||
PHPUnit_TextUI_TestRunner::run(
|
||||
new PHPUnit_Framework_TestSuite(__CLASS__)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending no auth data
|
||||
*/
|
||||
public function testAuthWithoutAuthData()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test if authentication is required when sending wrong user data
|
||||
|
||||
*/
|
||||
public function testAuthWrongCredentials()
|
||||
{
|
||||
$req = $this->getRequest(null, false);
|
||||
$req->setAuth('user', 'password', HTTP_Request2::AUTH_BASIC);
|
||||
$res = $req->send();
|
||||
$this->assertEquals(401, $res->getStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* See if posts/update behaves correct if there is one bookmark
|
||||
*/
|
||||
public function testPostUpdateOneBookmark()
|
||||
{
|
||||
$this->bs->deleteAll();
|
||||
|
||||
list($req, $uId) = $this->getAuthRequest();
|
||||
$bId = $this->addBookmark(
|
||||
$uId, 'http://example.org/tag1', 0,
|
||||
array('unittest', 'tag1')
|
||||
);
|
||||
|
||||
$data = $this->bs->getBookmarks(0, null, $uId);
|
||||
$this->assertEquals(1, $data['total']);
|
||||
$bookmark = $data['bookmarks'][0];
|
||||
|
||||
//send request
|
||||
$res = $req->send();
|
||||
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
//verify MIME content type
|
||||
$this->assertEquals(
|
||||
'text/xml; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
|
||||
//verify xml
|
||||
$this->assertTag(
|
||||
array(
|
||||
'tag' => 'update',
|
||||
'attributes' => array(
|
||||
'inboxnew' => '0'
|
||||
)
|
||||
),
|
||||
$res->getBody(),
|
||||
'', false
|
||||
);
|
||||
//check time
|
||||
$xml = simplexml_load_string($res->getBody());
|
||||
$this->assertTrue(isset($xml['time']));
|
||||
$this->assertEquals(
|
||||
strtotime($bookmark['bDatetime']),
|
||||
strtotime(
|
||||
(string)$xml['time']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Api_PostsUpdateTest::main') {
|
||||
Api_PostsUpdateTest::main();
|
||||
}
|
||||
?>
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Bookmark2TagTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle bookmark-tag combination service.
|
||||
*
|
||||
@ -38,6 +37,26 @@ class Bookmark2TagTest extends TestBase
|
||||
protected $tts;
|
||||
|
||||
|
||||
/**
|
||||
* Create a bookmark. Like addBookmark(), just with other paramter order
|
||||
* to make some tests in that class easier to write.
|
||||
*
|
||||
* @param integer $user User ID the bookmark shall belong
|
||||
* @param array $tags Array of tags to attach. If "null" is given,
|
||||
* it will automatically be "unittest"
|
||||
* @param string $date strtotime-compatible string
|
||||
* @param string $title Bookmark title
|
||||
*
|
||||
* @return integer ID of bookmark
|
||||
*/
|
||||
protected function addTagBookmark($user, $tags, $date = null, $title = null)
|
||||
{
|
||||
return $this->addBookmark(
|
||||
$user, null, 0, $tags, $title, $date
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to run this test class standalone
|
||||
@ -57,6 +76,7 @@ class Bookmark2TagTest extends TestBase
|
||||
protected function setUp()
|
||||
{
|
||||
$this->us = SemanticScuttle_Service_Factory::get('User');
|
||||
$this->us->deleteAll();
|
||||
$this->bs = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$this->bs->deleteAll();
|
||||
$this->b2ts= SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
@ -74,7 +94,7 @@ class Bookmark2TagTest extends TestBase
|
||||
/**
|
||||
* Test getTagsForBookmark() when the bookmark has no tags
|
||||
*
|
||||
* @return void
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getTagsForBookmark
|
||||
*/
|
||||
public function testGetTagsForBookmarkNone()
|
||||
{
|
||||
@ -92,7 +112,7 @@ class Bookmark2TagTest extends TestBase
|
||||
/**
|
||||
* Test getTagsForBookmark() when the bookmark has one tag
|
||||
*
|
||||
* @return void
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getTagsForBookmark
|
||||
*/
|
||||
public function testGetTagsForBookmarkOne()
|
||||
{
|
||||
@ -111,9 +131,9 @@ class Bookmark2TagTest extends TestBase
|
||||
/**
|
||||
* Test getTagsForBookmark() when the bookmark has three tags
|
||||
*
|
||||
* @return void
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getTagsForBookmark
|
||||
*/
|
||||
public function testGetTagsForBookmarkThree()
|
||||
public function testGetTagsForBookmarkThr()
|
||||
{
|
||||
$this->addBookmark(null, null, 0, array('forz', 'barz'));
|
||||
|
||||
@ -121,7 +141,7 @@ class Bookmark2TagTest extends TestBase
|
||||
$this->b2ts->attachTags($bid, array('foo', 'bar', 'fuu'));
|
||||
|
||||
$tags = $this->b2ts->getTagsForBookmark($bid);
|
||||
$this->assertType('array', $tags);
|
||||
$this->assertInternalType('array', $tags);
|
||||
$this->assertContains('foo', $tags);
|
||||
$this->assertContains('bar', $tags);
|
||||
$this->assertContains('fuu', $tags);
|
||||
@ -132,7 +152,7 @@ class Bookmark2TagTest extends TestBase
|
||||
/**
|
||||
* Test getTagsForBookmarks() when no bookmarks have tags.
|
||||
*
|
||||
* @return void
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getTagsForBookmarks
|
||||
*/
|
||||
public function testGetTagsForBookmarksNone()
|
||||
{
|
||||
@ -142,10 +162,10 @@ class Bookmark2TagTest extends TestBase
|
||||
$alltags = $this->b2ts->getTagsForBookmarks(
|
||||
array($bid1, $bid2)
|
||||
);
|
||||
$this->assertType('array', $alltags);
|
||||
$this->assertInternalType('array', $alltags);
|
||||
$this->assertEquals(2, count($alltags));
|
||||
$this->assertType('array', $alltags[$bid1]);
|
||||
$this->assertType('array', $alltags[$bid2]);
|
||||
$this->assertInternalType('array', $alltags[$bid1]);
|
||||
$this->assertInternalType('array', $alltags[$bid2]);
|
||||
$this->assertEquals(0, count($alltags[$bid1]));
|
||||
$this->assertEquals(0, count($alltags[$bid2]));
|
||||
}
|
||||
@ -155,7 +175,7 @@ class Bookmark2TagTest extends TestBase
|
||||
/**
|
||||
* Test getTagsForBookmarks() when most bookmarks have tags.
|
||||
*
|
||||
* @return void
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getTagsForBookmarks
|
||||
*/
|
||||
public function testGetTagsForBookmarksMost()
|
||||
{
|
||||
@ -180,9 +200,9 @@ class Bookmark2TagTest extends TestBase
|
||||
$alltags = $this->b2ts->getTagsForBookmarks(
|
||||
array($bid1, $bid2, $bid3, $bid4)
|
||||
);
|
||||
$this->assertType('array', $alltags);
|
||||
$this->assertInternalType('array', $alltags);
|
||||
foreach ($alltags as $bid => $btags) {
|
||||
$this->assertType('array', $btags);
|
||||
$this->assertInternalType('array', $btags);
|
||||
if ($bid == $bid1) {
|
||||
$this->assertEquals(3, count($btags));
|
||||
$this->assertContains('foo', $btags);
|
||||
@ -205,6 +225,408 @@ class Bookmark2TagTest extends TestBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fetch the most popular tags in descending order
|
||||
*
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsOrder()
|
||||
{
|
||||
$user = $this->addUser();
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
$this->addTagBookmark($user, array('one', 'thr'));
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags();
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
|
||||
$this->assertInternalType('array', $arTags[0]);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '3'),
|
||||
array('tag' => 'two', 'bCount' => '2'),
|
||||
array('tag' => 'thr', 'bCount' => '1')
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsLimit()
|
||||
{
|
||||
$user = $this->addUser();
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
$this->addTagBookmark($user, array('one', 'thr'));
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags();
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 2);
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '3'),
|
||||
array('tag' => 'two', 'bCount' => '2'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 1);
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '3'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsDays()
|
||||
{
|
||||
$user = $this->addUser();
|
||||
$this->addTagBookmark($user, array('one', 'two'), 'today');
|
||||
$this->addTagBookmark($user, array('one', 'thr'), 'today');
|
||||
$this->addTagBookmark($user, array('one', 'two'), '-1 day 1 hour');
|
||||
$this->addTagBookmark($user, array('one', 'thr'), '-3 days 1 hour');
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, 1);
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'thr', 'bCount' => '1'), $arTags);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, 2);
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '3'),
|
||||
array('tag' => 'two', 'bCount' => '2'),
|
||||
array('tag' => 'thr', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, 5);
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '4'), $arTags);
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'thr', 'bCount' => '2'), $arTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsBeginsWith()
|
||||
{
|
||||
$user = $this->addUser();
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
$this->addTagBookmark($user, array('one', 'thr'));
|
||||
$this->addTagBookmark($user, array('one', 'two'));
|
||||
$this->addTagBookmark($user, array('one', 'thr'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, null, 'o');
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '4'), $arTags);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, null, 'tw');
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '2'), $arTags);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(null, 10, null, null, 't');
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'thr', 'bCount' => '2'), $arTags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsExcludesSystemTags()
|
||||
{
|
||||
$user = $this->addUser();
|
||||
$this->addTagBookmark($user, array('one', 'system:test'));
|
||||
$this->addTagBookmark($user, array('one', 'system:unittest'));
|
||||
$this->addTagBookmark($user, array('one', 'sys:unittest'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags();
|
||||
$this->assertInternalType('array', $arTags);
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '3'),
|
||||
array('tag' => 'sys:unittest', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsUserTags()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$user2 = $this->addUser();
|
||||
$user3 = $this->addUser();
|
||||
$this->addTagBookmark($user1, array('one'));
|
||||
$this->addTagBookmark($user2, array('one', 'two'));
|
||||
$this->addTagBookmark($user2, array('two'));
|
||||
$this->addTagBookmark($user3, array('one', 'thr'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags($user1);
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags($user2);
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'two', 'bCount' => '2'),
|
||||
array('tag' => 'one', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(array($user2, $user3));
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'thr', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This may happen when the method is called with a problematic user array.
|
||||
* In that case we may not generate invalid SQL or so.
|
||||
*
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsUserArrayWithNull()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$this->addTagBookmark($user1, array('one'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(array(null));
|
||||
$this->assertEquals(0, count($arTags));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsPublicOnlyNoUser()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('one'));
|
||||
$this->addBookmark($user1, null, 1, array('one', 'two'));
|
||||
$this->addBookmark($user1, null, 2, array('thr'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags();
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsPublicOnlySingleUser()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('one'));
|
||||
$this->addBookmark($user1, null, 1, array('one', 'two'));
|
||||
$this->addBookmark($user1, null, 2, array('thr'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags($user1);
|
||||
$this->assertEquals(1, count($arTags));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('tag' => 'one', 'bCount' => '1'),
|
||||
),
|
||||
$arTags
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsPublicOnlySeveralUsers()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$user2 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('one'));
|
||||
$this->addBookmark($user1, null, 1, array('one', 'two'));
|
||||
$this->addBookmark($user1, null, 2, array('thr'));
|
||||
$this->addBookmark($user2, null, 0, array('fou'));
|
||||
$this->addBookmark($user2, null, 1, array('fiv'));
|
||||
$this->addBookmark($user2, null, 2, array('six'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags(array($user1, $user2));
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'fou', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getPopularTags
|
||||
*/
|
||||
public function testGetPopularTagsUserPrivatesWhenLoggedIn()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('one'));
|
||||
$this->addBookmark($user1, null, 1, array('one', 'two'));
|
||||
$this->addBookmark($user1, null, 2, array('thr'));
|
||||
|
||||
$arTags = $this->b2ts->getPopularTags($user1, 10, $user1);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'one', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'two', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'thr', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getAdminTags
|
||||
*/
|
||||
public function testGetAdminTags()
|
||||
{
|
||||
$admin1 = $this->addUser('admin1');
|
||||
$admin2 = $this->addUser('admin2');
|
||||
$user1 = $this->addUser();
|
||||
$this->addBookmark($admin1, null, 0, array('admintag', 'admintag1'));
|
||||
$this->addBookmark($admin2, null, 0, array('admintag', 'admintag2'));
|
||||
$this->addBookmark($user1, null, 0, array('usertag'));
|
||||
|
||||
$GLOBALS['admin_users'] = array('admin1', 'admin2');
|
||||
|
||||
$arTags = $this->b2ts->getAdminTags(4);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'admintag', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'admintag1', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'admintag2', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getAdminTags
|
||||
*/
|
||||
public function testGetAdminTagsBeginsWith()
|
||||
{
|
||||
$admin1 = $this->addUser('admin1');
|
||||
$this->addBookmark($admin1, null, 0, array('admintag', 'admintag1'));
|
||||
$this->addBookmark($admin1, null, 0, array('tester', 'testos'));
|
||||
|
||||
$GLOBALS['admin_users'] = array('admin1');
|
||||
|
||||
$arTags = $this->b2ts->getAdminTags(4, null, null, 'test');
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertContains(array('tag' => 'tester', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'testos', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getContactTags
|
||||
*/
|
||||
public function testGetContactTagsWatchlistOnly()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$user2 = $this->addUser();
|
||||
$user3 = $this->addUser();
|
||||
$this->us->setCurrentUserId($user1);
|
||||
$this->us->setWatchStatus($user2);
|
||||
//user1 watches user2 now
|
||||
|
||||
$this->addBookmark($user1, null, 0, array('usertag', 'usertag1'));
|
||||
$this->addBookmark($user2, null, 0, array('usertag', 'usertag2'));
|
||||
$this->addBookmark($user3, null, 0, array('usertag', 'usertag3'));
|
||||
|
||||
$arTags = $this->b2ts->getContactTags($user1, 10);
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertContains(array('tag' => 'usertag', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usertag2', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getContactTags
|
||||
*/
|
||||
public function testGetContactTagsIncludingUser()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$user2 = $this->addUser();
|
||||
$user3 = $this->addUser();
|
||||
$this->us->setCurrentUserId($user1);
|
||||
$this->us->setWatchStatus($user2);
|
||||
//user1 watches user2 now
|
||||
|
||||
$this->addBookmark($user1, null, 0, array('usertag', 'usertag1'));
|
||||
$this->addBookmark($user2, null, 0, array('usertag', 'usertag2'));
|
||||
$this->addBookmark($user3, null, 0, array('usertag', 'usertag3'));
|
||||
|
||||
$arTags = $this->b2ts->getContactTags($user1, 10, $user1);
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'usertag', 'bCount' => '2'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usertag1', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usertag2', 'bCount' => '1'), $arTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_Bookmark2Tag::getContactTags
|
||||
*/
|
||||
public function testGetContactTagsBeginsWith()
|
||||
{
|
||||
$user1 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('usertag', 'usertag1'));
|
||||
$this->addBookmark($user1, null, 0, array('usable', 'undefined'));
|
||||
$this->addBookmark($user1, null, 0, array('fußbad', 'usable'));
|
||||
|
||||
$arTags = $this->b2ts->getContactTags($user1, 10, $user1, null, 'user');
|
||||
$this->assertEquals(2, count($arTags));
|
||||
$this->assertContains(array('tag' => 'usertag', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usertag1', 'bCount' => '1'), $arTags);
|
||||
|
||||
$arTags = $this->b2ts->getContactTags($user1, 10, $user1, null, 'us');
|
||||
$this->assertEquals(3, count($arTags));
|
||||
$this->assertContains(array('tag' => 'usertag', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usertag1', 'bCount' => '1'), $arTags);
|
||||
$this->assertContains(array('tag' => 'usable', 'bCount' => '2'), $arTags);
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Bookmark2TagTest::main') {
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'BookmarkTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle bookmark service.
|
||||
*
|
||||
@ -264,7 +263,7 @@ class BookmarkTest extends TestBase
|
||||
$bookmark = $this->bs->getBookmark($bid);
|
||||
|
||||
$ret = $this->bs->bookmarksExist(array($bookmark['bAddress']));
|
||||
$this->assertType('array', $ret);
|
||||
$this->assertInternalType('array', $ret);
|
||||
$this->assertEquals(1, count($ret));
|
||||
$this->assertTrue($ret[$bookmark['bAddress']]);
|
||||
}
|
||||
@ -292,7 +291,7 @@ class BookmarkTest extends TestBase
|
||||
$bookmark2['bAddress']
|
||||
)
|
||||
);
|
||||
$this->assertType('array', $ret);
|
||||
$this->assertInternalType('array', $ret);
|
||||
$this->assertEquals(2, count($ret));
|
||||
$this->assertTrue($ret[$bookmark['bAddress']]);
|
||||
$this->assertTrue($ret[$bookmark2['bAddress']]);
|
||||
@ -309,7 +308,7 @@ class BookmarkTest extends TestBase
|
||||
public function testBookmarksExistFalseSingle()
|
||||
{
|
||||
$ret = $this->bs->bookmarksExist(array('does-not-exist'));
|
||||
$this->assertType('array', $ret);
|
||||
$this->assertInternalType('array', $ret);
|
||||
$this->assertEquals(1, count($ret));
|
||||
$this->assertFalse($ret['does-not-exist']);
|
||||
}
|
||||
@ -330,7 +329,7 @@ class BookmarkTest extends TestBase
|
||||
'does-not-exist-3',
|
||||
);
|
||||
$ret = $this->bs->bookmarksExist($bms);
|
||||
$this->assertType('array', $ret);
|
||||
$this->assertInternalType('array', $ret);
|
||||
$this->assertEquals(3, count($ret));
|
||||
$this->assertFalse($ret['does-not-exist']);
|
||||
$this->assertFalse($ret['does-not-exist-2']);
|
||||
@ -367,7 +366,7 @@ class BookmarkTest extends TestBase
|
||||
'does-not-exist-3'
|
||||
)
|
||||
);
|
||||
$this->assertType('array', $ret);
|
||||
$this->assertInternalType('array', $ret);
|
||||
$this->assertEquals(5, count($ret));
|
||||
$this->assertTrue($ret[$bookmark['bAddress']]);
|
||||
$this->assertTrue($ret[$bookmark2['bAddress']]);
|
||||
@ -476,7 +475,7 @@ class BookmarkTest extends TestBase
|
||||
|
||||
foreach ($bms['bookmarks'] as $bm) {
|
||||
$this->assertArrayHasKey('tags', $bm);
|
||||
$this->assertType('array', $bm['tags']);
|
||||
$this->assertInternalType('array', $bm['tags']);
|
||||
if ($bm['bId'] == $bid) {
|
||||
$this->assertContains('foo', $bm['tags']);
|
||||
$this->assertContains('bar', $bm['tags']);
|
||||
@ -757,7 +756,7 @@ class BookmarkTest extends TestBase
|
||||
|
||||
$bm = $this->bs->getBookmark($bid, true);
|
||||
$this->assertArrayHasKey('tags', $bm);
|
||||
$this->assertType('array', $bm['tags']);
|
||||
$this->assertInternalType('array', $bm['tags']);
|
||||
$this->assertContains('foo', $bm['tags']);
|
||||
$this->assertContains('bar', $bm['tags']);
|
||||
}
|
||||
@ -875,7 +874,7 @@ class BookmarkTest extends TestBase
|
||||
$bid = $this->addBookmark($uid, $url);
|
||||
|
||||
$bm = $this->bs->getBookmarkByAddress($url);
|
||||
$this->assertType('array', $bm);
|
||||
$this->assertInternalType('array', $bm);
|
||||
$this->assertEquals($url, $bm['bAddress']);
|
||||
}
|
||||
|
||||
@ -901,7 +900,7 @@ class BookmarkTest extends TestBase
|
||||
$bid = $this->addBookmark($uid, $url);
|
||||
|
||||
$bm = $this->bs->getBookmarkByAddress($incomplete);
|
||||
$this->assertType('array', $bm);
|
||||
$this->assertInternalType('array', $bm);
|
||||
$this->assertEquals($url, $bm['bAddress']);
|
||||
}
|
||||
|
||||
@ -952,7 +951,7 @@ class BookmarkTest extends TestBase
|
||||
$this->assertEquals('new description', $bm['bDescription']);
|
||||
$this->assertEquals('new private note', $bm['bPrivateNote']);
|
||||
$this->assertEquals(1, $bm['bStatus']);
|
||||
$this->assertType('array', $bm['tags']);
|
||||
$this->assertInternalType('array', $bm['tags']);
|
||||
$this->assertEquals(1, count($bm['tags']));
|
||||
$this->assertContains('new', $bm['tags']);
|
||||
}
|
||||
@ -982,6 +981,38 @@ class BookmarkTest extends TestBase
|
||||
$this->assertEquals('newShortNambb', $bm['bShort']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if updating a bookmark's date works.
|
||||
* This once was a bug, see bug #3073215.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @link https://sourceforge.net/tracker/?func=detail&atid=1017430&aid=3073215&group_id=211356
|
||||
*/
|
||||
public function testUpdateBookmarkDate()
|
||||
{
|
||||
$bid = $this->bs->addBookmark(
|
||||
'http://example.org', 'title', 'desc', 'priv',
|
||||
0, array(), 'myShortName'
|
||||
);
|
||||
$bm = $this->bs->getBookmark($bid);
|
||||
$this->assertEquals('myShortName', $bm['bShort']);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->bs->updateBookmark(
|
||||
$bid, 'http://example2.org', 'my title', 'desc',
|
||||
'priv', 0, array(), 'newShortNambb',
|
||||
//we need to use zulu (GMT) time zone here
|
||||
// since the dates/times are stored as that
|
||||
// in the database
|
||||
'2002-03-04T05:06:07Z'
|
||||
)
|
||||
);
|
||||
$bm = $this->bs->getBookmark($bid);
|
||||
$this->assertEquals('newShortNambb', $bm['bShort']);
|
||||
$this->assertEquals('2002-03-04 05:06:07', $bm['bDatetime']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -1085,6 +1116,92 @@ class BookmarkTest extends TestBase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test what countOther() returns when the user is logged in
|
||||
* and a friend (people on the watchlist) has bookmarked
|
||||
* and the same address with public status.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCountOthersWatchlistPublic()
|
||||
{
|
||||
$uid = $this->addUser();
|
||||
$address = 'http://example.org';
|
||||
|
||||
//create other user and add main user to his watchlist
|
||||
$friendPublic1 = $this->addUser();
|
||||
$this->us->setCurrentUserId($friendPublic1);
|
||||
$this->us->setWatchStatus($uid);
|
||||
|
||||
//create bookmarks for main user and other one
|
||||
$this->addBookmark($uid, $address, 0);
|
||||
$this->addBookmark($friendPublic1, $address, 0);//0 is public
|
||||
|
||||
//log main user in
|
||||
$this->us->setCurrentUserId($uid);
|
||||
|
||||
$this->assertEquals(1, $this->bs->countOthers($address));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test what countOther() returns when the user is logged in
|
||||
* and a friend (people on the watchlist) has bookmarked
|
||||
* and shared the same address for the watchlist.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCountOthersWatchlistShared()
|
||||
{
|
||||
$uid = $this->addUser();
|
||||
$address = 'http://example.org';
|
||||
|
||||
//create other user and add main user to his watchlist
|
||||
$friendPublic1 = $this->addUser();
|
||||
$this->us->setCurrentUserId($friendPublic1);
|
||||
$this->us->setWatchStatus($uid);
|
||||
|
||||
//create bookmarks for main user and other one
|
||||
$this->addBookmark($uid, $address, 0);
|
||||
$this->addBookmark($friendPublic1, $address, 1);//1 is shared
|
||||
|
||||
//log main user in
|
||||
$this->us->setCurrentUserId($uid);
|
||||
|
||||
$this->assertEquals(1, $this->bs->countOthers($address));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test what countOther() returns when the user is logged in
|
||||
* and one friends (people on the watchlist) has bookmarked
|
||||
* the same address but made it private.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCountOthersWatchlistPrivate()
|
||||
{
|
||||
$uid = $this->addUser();
|
||||
$address = 'http://example.org';
|
||||
|
||||
//create other user and add main user to his watchlist
|
||||
$friendPublic1 = $this->addUser();
|
||||
$this->us->setCurrentUserId($friendPublic1);
|
||||
$this->us->setWatchStatus($uid);
|
||||
|
||||
//create bookmarks for main user and other one
|
||||
$this->addBookmark($uid, $address, 0);
|
||||
$this->addBookmark($friendPublic1, $address, 2);//2 is private
|
||||
|
||||
//log main user in
|
||||
$this->us->setCurrentUserId($uid);
|
||||
|
||||
$this->assertEquals(0, $this->bs->countOthers($address));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test what countOther() returns when the user is logged in
|
||||
* and friends (people on the watchlist) have bookmarked
|
||||
@ -1092,7 +1209,7 @@ class BookmarkTest extends TestBase
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCountOthersWatchlist()
|
||||
public function testCountOthersWatchlistComplex()
|
||||
{
|
||||
$uid = $this->addUser();
|
||||
$address = 'http://example.org';
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'CommonDescriptionTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle common description service.
|
||||
*
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'SearchHistoryTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle search history service.
|
||||
*
|
||||
@ -55,63 +54,341 @@ class SearchHistoryTest extends TestBase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set up all services
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->us =SemanticScuttle_Service_Factory::get('User');
|
||||
$this->bs =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$this->bs->deleteAll();
|
||||
$this->b2ts =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$this->b2ts->deleteAll();
|
||||
$this->tts =SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$this->tts->deleteAll();
|
||||
$this->tsts =SemanticScuttle_Service_Factory::get('TagStat');
|
||||
$this->tsts->deleteAll();
|
||||
$this->shs =SemanticScuttle_Service_Factory::get('SearchHistory');
|
||||
$this->shs->deleteAll();
|
||||
$this->us = SemanticScuttle_Service_Factory::get('User');
|
||||
$this->bs = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$this->bs->deleteAll();
|
||||
|
||||
$this->b2ts =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$this->b2ts->deleteAll();
|
||||
|
||||
$this->tts = SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$this->tts->deleteAll();
|
||||
|
||||
$this->tsts = SemanticScuttle_Service_Factory::get('TagStat');
|
||||
$this->tsts->deleteAll();
|
||||
|
||||
$this->shs = SemanticScuttle_Service_Factory::get('SearchHistory');
|
||||
$this->shs->deleteAll();
|
||||
}
|
||||
|
||||
public function testSearchHistory()
|
||||
/**
|
||||
* Tests if adding searches to the database works
|
||||
*
|
||||
* @covers SemanticScuttle_Service_SearchHistory::addSearch
|
||||
*/
|
||||
public function testAddSearch()
|
||||
{
|
||||
$shs = $this->shs;
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$terms = 'bbqsdkbb;,:,:q;,qddds&é"\'\\\\\(-è_çà)';
|
||||
$terms2 = '~#{|`]';
|
||||
$range = 'all';
|
||||
$nbResults = 10908;
|
||||
$uId = 10;
|
||||
$this->assertTrue(
|
||||
$this->shs->addSearch('testsearchterm', 'all', 0)
|
||||
);
|
||||
$this->assertEquals(1, $this->shs->countSearches());
|
||||
}
|
||||
|
||||
$shs->addSearch($terms, $range, $nbResults, $uId);
|
||||
$shs->addSearch($terms2, $range, $nbResults, $uId);
|
||||
$shs->addSearch('', $range, $nbResults, $uId); // A void search must not be saved
|
||||
/**
|
||||
* Tests if adding a search without terms should fail
|
||||
*
|
||||
* @covers SemanticScuttle_Service_SearchHistory::addSearch
|
||||
*/
|
||||
public function testAddSearchNoTerms()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$searches = $shs->getAllSearches();
|
||||
$this->assertSame(2, count($searches));
|
||||
$searches = $shs->getAllSearches($range, $uId);
|
||||
$this->assertEquals(2, count($searches));
|
||||
$searches = $shs->getAllSearches($range, 20); // fake userid
|
||||
$this->assertEquals(0, count($searches));
|
||||
$searches = $shs->getAllSearches($range, $uId, 1);
|
||||
$this->assertEquals(1, count($searches));
|
||||
$searches = $shs->getAllSearches($range, null, 1, 1);
|
||||
$this->assertEquals(1, count($searches));
|
||||
$this->assertFalse(
|
||||
$this->shs->addSearch('', 'all', 0)
|
||||
);
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
}
|
||||
|
||||
//test content of results
|
||||
$searches = $shs->getAllSearches();
|
||||
$this->assertSame($terms2, $searches[0]['shTerms']);
|
||||
$this->assertSame($range, $searches[0]['shRange']);
|
||||
$this->assertEquals($nbResults, $searches[0]['shNbResults']);
|
||||
$this->assertEquals($uId, $searches[0]['uId']);
|
||||
$this->assertSame($terms, $searches[1]['shTerms']);
|
||||
$this->assertSame($range, $searches[1]['shRange']);
|
||||
$this->assertEquals($nbResults, $searches[1]['shNbResults']);
|
||||
$this->assertEquals($uId, $searches[1]['uId']);
|
||||
/**
|
||||
* Tests if adding a search deletes the history if it is too
|
||||
* large.
|
||||
*
|
||||
* @covers SemanticScuttle_Service_SearchHistory::addSearch
|
||||
*/
|
||||
public function testAddSearchDeleteHistory()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
//test distinct parameter
|
||||
$shs->addSearch($terms, $range, $nbResults, 30); // we repeat a search (same terms)
|
||||
$searches = $shs->getAllSearches();
|
||||
$this->assertSame(3, count($searches));
|
||||
$searches = $shs->getAllSearches(NULL, NULL, NULL, NULL, true);
|
||||
$this->assertSame(2, count($searches));
|
||||
$this->shs->sizeSearchHistory = 5;
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
$this->shs->addSearch('zwei', 'all', 1);
|
||||
$this->shs->addSearch('drei', 'all', 1);
|
||||
$this->shs->addSearch('view', 'all', 1);
|
||||
$this->shs->addSearch('fünf', 'all', 1);
|
||||
$this->assertEquals(5, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('sechs', 'all', 1);
|
||||
$this->assertEquals(5, $this->shs->countSearches());
|
||||
|
||||
$this->shs->sizeSearchHistory = 6;
|
||||
$this->shs->addSearch('sieben', 'all', 1);
|
||||
$this->assertEquals(6, $this->shs->countSearches());
|
||||
$this->shs->addSearch('acht', 'all', 1);
|
||||
$this->assertEquals(6, $this->shs->countSearches());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() without any parameters
|
||||
*/
|
||||
public function testGetAllSearches()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
$this->shs->addSearch('zwei', 'all', 1);
|
||||
$this->shs->addSearch('drei', 'all', 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches();
|
||||
$this->assertEquals(3, count($rows));
|
||||
|
||||
$terms = array();
|
||||
foreach ($rows as $row) {
|
||||
$terms[] = $row['shTerms'];
|
||||
}
|
||||
sort($terms);
|
||||
$this->assertEquals(
|
||||
array('drei', 'eins', 'zwei'),
|
||||
$terms
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() return value row array keys.
|
||||
*/
|
||||
public function testGetAllSearchesTypes()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches();
|
||||
$this->assertEquals(1, count($rows));
|
||||
$row = reset($rows);
|
||||
|
||||
$this->assertArrayHasKey('shTerms', $row);
|
||||
$this->assertArrayHasKey('shId', $row);
|
||||
$this->assertArrayHasKey('shRange', $row);
|
||||
$this->assertArrayHasKey('shNbResults', $row);
|
||||
$this->assertArrayHasKey('shDatetime', $row);
|
||||
$this->assertArrayHasKey('uId', $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() range parameter
|
||||
*/
|
||||
public function testGetAllSearchesRange()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
$this->shs->addSearch('zwei', 'watchlist', 1);
|
||||
$this->shs->addSearch('drei', 'watchlist', 1);
|
||||
$this->shs->addSearch('vier', 'user1', 1);
|
||||
$this->shs->addSearch('fünf', 'user2', 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches('all');
|
||||
$this->assertEquals(1, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches('watchlist');
|
||||
$this->assertEquals(2, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches('user0');
|
||||
$this->assertEquals(0, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches('user1');
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals('vier', $rows[0]['shTerms']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() uId parameter
|
||||
*/
|
||||
public function testGetAllSearchesUid()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1, 0);
|
||||
$this->shs->addSearch('zwei', 'all', 1, 0);
|
||||
$this->shs->addSearch('drei', 'all', 1, 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null);
|
||||
$this->assertEquals(3, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, 1);
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals('drei', $rows[0]['shTerms']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() number parameter
|
||||
*/
|
||||
public function testGetAllSearchesNb()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1, 0);
|
||||
$this->shs->addSearch('zwei', 'all', 1, 0);
|
||||
$this->shs->addSearch('drei', 'all', 1, 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 1);
|
||||
$this->assertEquals(1, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 2);
|
||||
$this->assertEquals(2, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 3);
|
||||
$this->assertEquals(3, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 4);
|
||||
$this->assertEquals(3, count($rows));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() paging start parameter
|
||||
*/
|
||||
public function testGetAllSearchesStart()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1, 0);
|
||||
$this->shs->addSearch('zwei', 'all', 1, 0);
|
||||
$this->shs->addSearch('drei', 'all', 1, 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 1, 0);
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals('drei', $rows[0]['shTerms']);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 1, 1);
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals('zwei', $rows[0]['shTerms']);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, 3, 2);
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals('eins', $rows[0]['shTerms']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() distinct parameter
|
||||
*/
|
||||
public function testGetAllSearchesDistinct()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
$this->shs->addSearch('eins', 'all', 1);
|
||||
$this->shs->addSearch('drei', 'all', 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, null, null, false);
|
||||
$this->assertEquals(3, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, null, null, true);
|
||||
$this->assertEquals(2, count($rows));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getAllSearches() withResults parameter
|
||||
*/
|
||||
public function testGetAllSearchesWithResults()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 0);
|
||||
$this->shs->addSearch('zwei', 'all', 0);
|
||||
$this->shs->addSearch('drei', 'all', 1);
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, null, null, false, false);
|
||||
$this->assertEquals(3, count($rows));
|
||||
|
||||
$rows = $this->shs->getAllSearches(null, null, null, null, false, true);
|
||||
$this->assertEquals(1, count($rows));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleting the oldest search without any historical searches
|
||||
*
|
||||
* @covers SemanticScuttle_Service_SearchHistory::deleteOldestSearch
|
||||
*/
|
||||
public function testDeleteOldestSearchNone()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
$this->assertTrue($this->shs->deleteOldestSearch());
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deleting the oldest search
|
||||
*
|
||||
* @covers SemanticScuttle_Service_SearchHistory::deleteOldestSearch
|
||||
*/
|
||||
public function testDeleteOldestSearchSome()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
$this->shs->addSearch('testsearchterm1', 'all', 0);
|
||||
$this->shs->addSearch('testsearchterm2', 'all', 0);
|
||||
|
||||
$rows = $this->shs->getAllSearches();
|
||||
$this->assertEquals(2, count($rows));
|
||||
|
||||
$highestId = -1;
|
||||
foreach ($rows as $row) {
|
||||
if ($row['shId'] > $highestId) {
|
||||
$highestId = $row['shId'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->shs->deleteOldestSearch();
|
||||
|
||||
$this->assertEquals(1, $this->shs->countSearches());
|
||||
|
||||
$rows = $this->shs->getAllSearches();
|
||||
$this->assertEquals(1, count($rows));
|
||||
$this->assertEquals(
|
||||
$highestId,
|
||||
$rows[0]['shId']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if deleting the search history for a certain user works
|
||||
*/
|
||||
public function testDeleteSearchHistoryForUser()
|
||||
{
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
|
||||
$this->shs->addSearch('eins', 'all', 1, 0);
|
||||
$this->shs->addSearch('zwei', 'all', 1, 22);
|
||||
$this->shs->addSearch('drei', 'all', 1, 1);
|
||||
$this->shs->addSearch('vier', 'all', 1, 22);
|
||||
|
||||
$this->shs->deleteSearchHistoryForUser(22);
|
||||
$this->assertEquals(2, $this->shs->countSearches());
|
||||
|
||||
$this->shs->deleteSearchHistoryForUser(20);
|
||||
$this->assertEquals(2, $this->shs->countSearches());
|
||||
|
||||
$this->shs->deleteSearchHistoryForUser(1);
|
||||
$this->assertEquals(1, $this->shs->countSearches());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test deleting all of the search history
|
||||
*/
|
||||
public function testDeleteAll()
|
||||
{
|
||||
$this->shs->addSearch('testsearchterm1', 'all', 0);
|
||||
$this->shs->addSearch('testsearchterm2', 'all', 0);
|
||||
$this->shs->deleteAll();
|
||||
$this->assertEquals(0, $this->shs->countSearches());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Tag2TagTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle tag2tag service.
|
||||
*
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'TagTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle tag service.
|
||||
*
|
||||
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'TagsCacheTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle tags cache service.
|
||||
*
|
||||
@ -54,9 +53,6 @@ class TagsCacheTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
global $dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbpersist, $dbtype, $tableprefix, $TEMPLATES_DIR, $debugMode;
|
||||
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header.php';
|
||||
|
||||
$this->us =SemanticScuttle_Service_Factory::get('User');
|
||||
$this->bs =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$this->bs->deleteAll();
|
||||
|
@ -11,10 +11,6 @@
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
PHPUnit_Util_Filter::addFileToFilter(__FILE__);
|
||||
|
||||
/**
|
||||
* Base unittest class that provides several helper methods.
|
||||
*
|
||||
@ -35,6 +31,7 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
* @param array $tags Array of tags to attach. If "null" is given,
|
||||
* it will automatically be "unittest"
|
||||
* @param string $title Bookmark title
|
||||
* @param string $date strtotime-compatible string
|
||||
*
|
||||
* @return integer ID of bookmark
|
||||
*
|
||||
@ -42,7 +39,7 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
protected function addBookmark(
|
||||
$user = null, $address = null, $status = 0,
|
||||
$tags = null, $title = null
|
||||
$tags = null, $title = null, $date = null
|
||||
) {
|
||||
if ($user === null) {
|
||||
$user = $this->addUser();
|
||||
@ -68,7 +65,7 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
null,
|
||||
$status,
|
||||
$tags,
|
||||
null, null, false, false,
|
||||
null, $date, false, false,
|
||||
$user
|
||||
);
|
||||
return $bid;
|
||||
@ -83,8 +80,25 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
* @param string $password Password
|
||||
*
|
||||
* @return integer ID of user
|
||||
*
|
||||
* @uses addUserData()
|
||||
*/
|
||||
protected function addUser($username = null, $password = null)
|
||||
{
|
||||
return reset($this->addUserData($username, $password));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new user in the database and returns id, username and password.
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
*
|
||||
* @return array ID of user, Name of user, password of user
|
||||
*/
|
||||
protected function addUserData($username = null, $password = null)
|
||||
{
|
||||
$us = SemanticScuttle_Service_Factory::get('User');
|
||||
$rand = rand();
|
||||
@ -101,9 +115,37 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
$password,
|
||||
'unittest-' . $rand . '@example.org'
|
||||
);
|
||||
return $uid;
|
||||
return array($uid, $username, $password);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the UID of an admin user.
|
||||
* If that user does not exist in the database, it is created.
|
||||
*
|
||||
* @return integer UID of admin user
|
||||
*/
|
||||
protected function getAdminUser()
|
||||
{
|
||||
if (count($GLOBALS['admin_users']) == 0) {
|
||||
$this->fail('No admin users configured');
|
||||
}
|
||||
$adminUserName = reset($GLOBALS['admin_users']);
|
||||
|
||||
$us = SemanticScuttle_Service_Factory::get('User');
|
||||
$uid = $us->getIdFromUser($adminUserName);
|
||||
if ($uid === null) {
|
||||
//that user does not exist in the database; create it
|
||||
$uid = $us->addUser(
|
||||
$adminUserName,
|
||||
rand(),
|
||||
'unittest-admin-' . $adminUserName . '@example.org'
|
||||
);
|
||||
}
|
||||
|
||||
return $uid;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -11,10 +11,6 @@
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
PHPUnit_Util_Filter::addFileToFilter(__FILE__);
|
||||
|
||||
/**
|
||||
* Base unittest class for web API tests.
|
||||
*
|
||||
@ -29,6 +25,16 @@ class TestBaseApi extends TestBase
|
||||
protected $url;
|
||||
protected $urlPart = null;
|
||||
|
||||
/**
|
||||
* @var SemanticScuttle_Service_User
|
||||
*/
|
||||
protected $us;
|
||||
|
||||
/**
|
||||
* @var SemanticScuttle_Service_Bookmark
|
||||
*/
|
||||
protected $bs;
|
||||
|
||||
|
||||
|
||||
protected function setUp()
|
||||
@ -52,11 +58,26 @@ class TestBaseApi extends TestBase
|
||||
|
||||
|
||||
/**
|
||||
* Gets a HTTP request object
|
||||
* Clean up after test
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
if (file_exists($GLOBALS['datadir'] . '/config.unittest.php')) {
|
||||
unlink($GLOBALS['datadir'] . '/config.unittest.php');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets a HTTP request object.
|
||||
* Uses $this->url plus $urlSuffix as request URL.
|
||||
*
|
||||
* @param string $urlSuffix Suffix for the URL
|
||||
*
|
||||
* @return HTTP_Request2 HTTP request object
|
||||
*
|
||||
* @uses $url
|
||||
*/
|
||||
protected function getRequest($urlSuffix = null)
|
||||
{
|
||||
@ -71,13 +92,20 @@ class TestBaseApi extends TestBase
|
||||
|
||||
|
||||
/**
|
||||
* Gets a HTTP request object
|
||||
* Creates a user and a HTTP request object and prepares
|
||||
* the request object with authentication details, so that
|
||||
* the user is logged in.
|
||||
*
|
||||
* Useful for HTTP API methods only, cannot be used with
|
||||
* "normal" HTML pages since they do not support HTTP auth.
|
||||
*
|
||||
* @param string $urlSuffix Suffix for the URL
|
||||
* @param mixed $auth If user authentication is needed (true/false)
|
||||
* or array with username and password
|
||||
*
|
||||
* @return array(HTTP_Request2, integer) HTTP request object and user id
|
||||
*
|
||||
* @uses getRequest()
|
||||
*/
|
||||
protected function getAuthRequest($urlSuffix = null, $auth = true)
|
||||
{
|
||||
@ -96,5 +124,102 @@ class TestBaseApi extends TestBase
|
||||
return array($req, $uid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a user and a HTTP_Request2 object, does a normal login
|
||||
* and prepares the cookies for the HTTP request object so that
|
||||
* the user is seen as logged in when requesting any HTML page.
|
||||
*
|
||||
* Useful for testing HTML pages or ajax URLs.
|
||||
*
|
||||
* @param string $urlSuffix Suffix for the URL
|
||||
* @param mixed $auth If user authentication is needed (true/false)
|
||||
* or array with username and password
|
||||
*
|
||||
* @return array(HTTP_Request2, integer) HTTP request object and user id
|
||||
*
|
||||
* @uses getRequest()
|
||||
*/
|
||||
protected function getLoggedInRequest($urlSuffix = null, $auth = true)
|
||||
{
|
||||
if (is_array($auth)) {
|
||||
list($username, $password) = $auth;
|
||||
} else {
|
||||
$username = 'testuser';
|
||||
$password = 'testpassword';
|
||||
}
|
||||
$uid = $this->addUser($username, $password);
|
||||
|
||||
$req = new HTTP_Request2(
|
||||
$GLOBALS['unittestUrl'] . '/login.php',
|
||||
HTTP_Request2::METHOD_POST
|
||||
);
|
||||
$cookies = $req->setCookieJar()->getCookieJar();
|
||||
$req->addPostParameter('username', $username);
|
||||
$req->addPostParameter('password', $password);
|
||||
$req->addPostParameter('submitted', 'Log In');
|
||||
$res = $req->send();
|
||||
|
||||
//after login, we normally get redirected
|
||||
$this->assertEquals(302, $res->getStatus(), 'Login failure');
|
||||
|
||||
$req = $this->getRequest($urlSuffix);
|
||||
$req->setCookieJar($cookies);
|
||||
|
||||
return array($req, $uid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the HTTP response has status code 200 and
|
||||
* content-type application/json; charset=utf-8
|
||||
*
|
||||
* @param HTTP_Request2_Response $res HTTP Response object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function assertResponseJson200(HTTP_Request2_Response $res)
|
||||
{
|
||||
$this->assertEquals(200, $res->getStatus());
|
||||
$this->assertEquals(
|
||||
'application/json; charset=utf-8',
|
||||
$res->getHeader('content-type')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Writes a special unittest configuration file.
|
||||
* The unittest config file is read when a GET request with unittestMode=1
|
||||
* is sent, and the user allowed unittestmode in config.php.
|
||||
*
|
||||
* @param array $arConfig Array with config names as key and their value as
|
||||
* value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUnittestConfig($arConfig)
|
||||
{
|
||||
$str = '<' . "?php\r\n";
|
||||
foreach ($arConfig as $name => $value) {
|
||||
$str .= '$' . $name . ' = '
|
||||
. var_export($value, true) . ";\n";
|
||||
}
|
||||
|
||||
if (!is_dir($GLOBALS['datadir'])) {
|
||||
$this->fail(
|
||||
'datadir not set or not a directory: ' . $GLOBALS['datadir']
|
||||
);
|
||||
}
|
||||
|
||||
$this->assertInternalType(
|
||||
'integer',
|
||||
file_put_contents($GLOBALS['datadir'] . '/config.unittest.php', $str),
|
||||
'Writing config.unittest.php failed'
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
68
tests/UserArrayTest.php
Normal file
68
tests/UserArrayTest.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle user array model.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class UserArrayTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testGetNameLongName()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'John Doe',
|
||||
SemanticScuttle_Model_UserArray::getName(
|
||||
array(
|
||||
'name' => 'John Doe',
|
||||
'username' => 'jdoe'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetNameUsernameIfNameIsEmpty()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'jdoe',
|
||||
SemanticScuttle_Model_UserArray::getName(
|
||||
array(
|
||||
'name' => '',
|
||||
'username' => 'jdoe'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetNameUsernameIfNameIsNotSet()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'jdoe',
|
||||
SemanticScuttle_Model_UserArray::getName(
|
||||
array(
|
||||
'username' => 'jdoe'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -12,13 +12,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'UserTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle user service.
|
||||
*
|
||||
@ -211,7 +210,7 @@ class UserTest extends TestBase
|
||||
$uid = $this->addUser();
|
||||
$users = $this->us->getObjectUsers();
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertType('SemanticScuttle_Model_User', reset($users));
|
||||
$this->assertInstanceOf('SemanticScuttle_Model_User', reset($users));
|
||||
}
|
||||
|
||||
|
||||
@ -228,7 +227,7 @@ class UserTest extends TestBase
|
||||
$uid3 = $this->addUser();
|
||||
$users = $this->us->getObjectUsers();
|
||||
$this->assertEquals(3, count($users));
|
||||
$this->assertType('SemanticScuttle_Model_User', reset($users));
|
||||
$this->assertInstanceOf('SemanticScuttle_Model_User', reset($users));
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,13 +10,12 @@
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'VoteTest::main');
|
||||
}
|
||||
|
||||
require_once 'prepare.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the SemanticScuttle voting system.
|
||||
*
|
||||
|
146
tests/ajax/GetAdminLinkedTagsTest.php
Normal file
146
tests/ajax/GetAdminLinkedTagsTest.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'ajax_GetAdminLinkedTagsTest::main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the ajax linked admin tags script
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class ajax_GetAdminLinkedTagsTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'ajax/getadminlinkedtags.php';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to run this test class standalone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function main()
|
||||
{
|
||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||
PHPUnit_TextUI_TestRunner::run(
|
||||
new PHPUnit_Framework_TestSuite(__CLASS__)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verify that we get the configured root tags if
|
||||
* we do not pass any parameters
|
||||
*/
|
||||
public function testRootTags()
|
||||
{
|
||||
$req = $this->getRequest();
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
|
||||
//same number of elements as the menu2Tags array
|
||||
$this->assertEquals(
|
||||
count($GLOBALS['menu2Tags']),
|
||||
count($data)
|
||||
);
|
||||
|
||||
//and the same contents
|
||||
foreach ($data as $tagObj) {
|
||||
$tagName = $tagObj->data->title;
|
||||
$this->assertContains($tagName, $GLOBALS['menu2Tags']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that we get subtags of a given tag
|
||||
*/
|
||||
public function testSubTags()
|
||||
{
|
||||
$t2t = SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$t2t->deleteAll();
|
||||
|
||||
$menu2Tag = reset($GLOBALS['menu2Tags']);
|
||||
//we have a subtag now
|
||||
$this->addBookmark(
|
||||
$this->getAdminUser(),
|
||||
null,
|
||||
0,
|
||||
$menu2Tag . '>adminsubtag'
|
||||
);
|
||||
|
||||
$res = $this->getRequest('?tag=' . $menu2Tag)->send();
|
||||
$this->assertResponseJson200($res);
|
||||
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
|
||||
//only one subtag
|
||||
$this->assertEquals(1, count($data));
|
||||
$this->assertEquals('adminsubtag', $data[0]->data->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that we only get admin tags, not tags from
|
||||
* non-admin people
|
||||
*/
|
||||
public function testOnlyAdminTags()
|
||||
{
|
||||
$t2t = SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$t2t->deleteAll();
|
||||
|
||||
$menu2Tag = reset($GLOBALS['menu2Tags']);
|
||||
//we have a subtag now
|
||||
$this->addBookmark(
|
||||
$this->getAdminUser(),
|
||||
null,
|
||||
0,
|
||||
$menu2Tag . '>adminsubtag'
|
||||
);
|
||||
//add another bookmark now, but for a normal user
|
||||
$this->addBookmark(
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
$menu2Tag . '>normalsubtag'
|
||||
);
|
||||
|
||||
$res = $this->getRequest('?tag=' . $menu2Tag)->send();
|
||||
$this->assertResponseJson200($res);
|
||||
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
|
||||
//we should have only one subtag now, the admin one
|
||||
$this->assertEquals(1, count($data));
|
||||
$this->assertEquals('adminsubtag', $data[0]->data->title);
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'ajax_GetAdminLinkedTagsTest::main') {
|
||||
ajax_GetAdminLinkedTagsTest::main();
|
||||
}
|
||||
?>
|
122
tests/ajax/GetAdminTagsTest.php
Normal file
122
tests/ajax/GetAdminTagsTest.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the ajax getadmintags.php script
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class ajax_GetAdminTagsTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'ajax/getadmintags.php';
|
||||
|
||||
|
||||
public function testTags()
|
||||
{
|
||||
list($user1, $uname1) = $this->addUserData();
|
||||
$user2 = $this->addUser();
|
||||
$this->addBookmark($user1, null, 0, array('admintag', 'admintag2'));
|
||||
$this->addBookmark($user2, null, 0, array('lusertag', 'lusertag2'));
|
||||
|
||||
$this->setUnittestConfig(
|
||||
array(
|
||||
'admin_users' => array($uname1)
|
||||
)
|
||||
);
|
||||
|
||||
$req = $this->getRequest('?unittestMode=1');
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(2, count($data));
|
||||
$this->assertContains('admintag', $data);
|
||||
$this->assertContains('admintag2', $data);
|
||||
}
|
||||
|
||||
public function testParameterBeginsWith()
|
||||
{
|
||||
list($user1, $uname1) = $this->addUserData();
|
||||
$this->addBookmark($user1, null, 0, array('foo', 'foobar', 'bar'));
|
||||
|
||||
$this->setUnittestConfig(
|
||||
array(
|
||||
'admin_users' => array($uname1)
|
||||
)
|
||||
);
|
||||
|
||||
$req = $this->getRequest('?unittestMode=1&beginsWith=foo');
|
||||
$res = $req->send();
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertResponseJson200($res);
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(2, count($data));
|
||||
$this->assertContains('foo', $data);
|
||||
$this->assertContains('foobar', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testParameterLimit()
|
||||
{
|
||||
list($user1, $uname1) = $this->addUserData();
|
||||
list($user2, $uname2) = $this->addUserData();
|
||||
$this->addBookmark($user1, null, 0, array('foo', 'foobar'));
|
||||
$this->addBookmark($user2, null, 0, array('foo', 'bar'));
|
||||
|
||||
$this->setUnittestConfig(
|
||||
array(
|
||||
'admin_users' => array($uname1, $uname2)
|
||||
)
|
||||
);
|
||||
|
||||
$req = $this->getRequest('?unittestMode=1&limit=1');
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(1, count($data));
|
||||
$this->assertContains('foo', $data);
|
||||
|
||||
$req = $this->getRequest('?unittestMode=1&limit=2');
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(2, count($data));
|
||||
$this->assertContains('foo', $data);
|
||||
|
||||
$req = $this->getRequest('?unittestMode=1&limit=3');
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(3, count($data));
|
||||
$this->assertContains('foo', $data);
|
||||
$this->assertContains('foobar', $data);
|
||||
$this->assertContains('bar', $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
102
tests/ajax/GetContactTagsTest.php
Normal file
102
tests/ajax/GetContactTagsTest.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../prepare.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
/**
|
||||
* Unit tests for the ajax getcontacttags.php script
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
class ajax_GetContactTagsTest extends TestBaseApi
|
||||
{
|
||||
protected $urlPart = 'ajax/getcontacttags.php';
|
||||
|
||||
|
||||
/**
|
||||
* If no user is logged in, no data are returned
|
||||
*/
|
||||
public function testNoUserLoggedIn()
|
||||
{
|
||||
$res = $this->getRequest()->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(0, count($data));
|
||||
}
|
||||
|
||||
|
||||
public function testUserLoggedInWatchlist()
|
||||
{
|
||||
list($req, $uId) = $this->getLoggedInRequest();
|
||||
$this->addBookmark($uId, null, 0, array('public', 'public2'));
|
||||
|
||||
$user2 = $this->addUser();
|
||||
$this->us->setCurrentUserId($uId);
|
||||
$this->us->setWatchStatus($user2);
|
||||
//uId watches user2 now
|
||||
$this->addBookmark($user2, null, 0, array('user2tag'));
|
||||
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(3, count($data));
|
||||
$this->assertContains('public', $data);
|
||||
$this->assertContains('public2', $data);
|
||||
$this->assertContains('user2tag', $data);
|
||||
}
|
||||
|
||||
public function testParameterBeginsWith()
|
||||
{
|
||||
list($req, $uId) = $this->getLoggedInRequest('?beginsWith=bar');
|
||||
$this->addBookmark($uId, null, 0, array('foobar', 'barmann'));
|
||||
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(1, count($data));
|
||||
$this->assertContains('barmann', $data);
|
||||
}
|
||||
|
||||
public function testParameterLimit()
|
||||
{
|
||||
list($req, $uId) = $this->getLoggedInRequest('?limit=2');
|
||||
$this->addBookmark($uId, null, 0, array('foo', 'bar', 'baz', 'omg'));
|
||||
|
||||
$res = $req->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(2, count($data));
|
||||
|
||||
$req2 = $this->getRequest('?limit=3');
|
||||
$req2->setCookieJar($req->getCookieJar());
|
||||
$res = $req2->send();
|
||||
$this->assertResponseJson200($res);
|
||||
$data = json_decode($res->getBody());
|
||||
$this->assertInternalType('array', $data);
|
||||
$this->assertEquals(3, count($data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
8
tests/phpunit.xml
Normal file
8
tests/phpunit.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<phpunit>
|
||||
<filter>
|
||||
<blacklist>
|
||||
<directory suffix=".php">.</directory>
|
||||
</blacklist>
|
||||
</filter>
|
||||
</phpunit>
|
@ -19,7 +19,13 @@
|
||||
$_SERVER['HTTP_HOST'] = 'http://localhost/';
|
||||
define('UNIT_TEST_MODE', true);
|
||||
|
||||
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header.php';
|
||||
if ('@data_dir@' == '@' . 'data_dir@') {
|
||||
//non pear-install
|
||||
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header.php';
|
||||
} else {
|
||||
//pear installation; files are in include path
|
||||
require_once 'SemanticScuttle/header.php';
|
||||
}
|
||||
require_once dirname(__FILE__) . '/TestBase.php';
|
||||
require_once dirname(__FILE__) . '/TestBaseApi.php';
|
||||
|
||||
|
@ -1,64 +1,92 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
Copyright (C) 2004 - 2006 Scuttle project
|
||||
http://sourceforge.net/projects/scuttle/
|
||||
http://scuttle.org/
|
||||
/**
|
||||
* Returns a list of tags managed by the admins, in json format
|
||||
* suitable for jsTree consumption.
|
||||
*
|
||||
* @param string $tag Tag for which the children tags shall be returned
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @subcategory Templates
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
/* Return a json file with list of linked tags */
|
||||
$httpContentType = 'application/json';
|
||||
require_once '../www-header.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Tag');
|
||||
$tagstatservice =SemanticScuttle_Service_Factory::get('TagStat');
|
||||
/**
|
||||
* Creates and returns an array of tags for the jsTree ajax loader.
|
||||
* If the tag is empty, the configured menu2 (admin) main tags are used.
|
||||
*
|
||||
* @param string $tag Tag name to fetch subtags for
|
||||
* @param SemanticScuttle_Service_Tag2Tag $t2t Tag relation service
|
||||
*
|
||||
* @return array Array of tag data suitable for the jsTree ajax loader
|
||||
*/
|
||||
function assembleAdminTagData($tag, SemanticScuttle_Service_Tag2Tag $t2t)
|
||||
{
|
||||
if ($tag == '') {
|
||||
$linkedTags = $GLOBALS['menu2Tags'];
|
||||
} else {
|
||||
$linkedTags = $t2t->getAdminLinkedTags($tag, '>');
|
||||
}
|
||||
|
||||
/* Managing all possible inputs */
|
||||
isset($_GET['tag']) ? define('GET_TAG', $_GET['tag']): define('GET_TAG', '');
|
||||
isset($_GET['uId']) ? define('GET_UID', $_GET['uId']): define('GET_UID', '');
|
||||
$tagData = array();
|
||||
foreach ($linkedTags as $tag) {
|
||||
//FIXME: the hasChildren code is nasty, because it causes too many
|
||||
// queries onto the database
|
||||
$hasChildren = 0 < count($t2t->getAdminLinkedTags($tag, '>'));
|
||||
$tagData[] = createTagArray($tag, $hasChildren);
|
||||
}
|
||||
|
||||
|
||||
function displayTag($tag, $uId) {
|
||||
$uId = ($uId==0)?NULL:$uId; // if user is nobody, NULL allows to look for every public tags
|
||||
|
||||
$tag2tagservice =SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$output = '{ id:'.rand().', name:\''.$tag.'\'';
|
||||
|
||||
$linkedTags = $tag2tagservice->getAdminLinkedTags($tag, '>');
|
||||
if(count($linkedTags) > 0) {
|
||||
$output.= ', children: [';
|
||||
foreach($linkedTags as $linkedTag) {
|
||||
$output.= displayTag($linkedTag, $uId);
|
||||
}
|
||||
$output = substr($output, 0, -1); // remove final comma avoiding IE6 Dojo bug
|
||||
$output.= "]";
|
||||
}
|
||||
|
||||
$output.= '},';
|
||||
return $output;
|
||||
return $tagData;
|
||||
}
|
||||
|
||||
?>
|
||||
/**
|
||||
* Creates an jsTree json array for the given tag
|
||||
*
|
||||
* @param string $tag Tag name
|
||||
* @param boolean $hasChildren If the tag has subtags (children) or not.
|
||||
* If unsure, set it to "true".
|
||||
*
|
||||
* @return array Array to be sent back to the browser as json
|
||||
*/
|
||||
function createTagArray($tag, $hasChildren = true)
|
||||
{
|
||||
$ar = array(
|
||||
'data' => array(
|
||||
//<a> attributes
|
||||
'title' => $tag,
|
||||
'attr' => array(
|
||||
'href' => createUrl('tags', $tag)
|
||||
)
|
||||
),
|
||||
//<li> attributes
|
||||
'attr' => array(
|
||||
'rel' => $tag,//needed for identifying the tag in html
|
||||
),
|
||||
);
|
||||
if ($hasChildren) {
|
||||
//jstree needs that to show the arrows
|
||||
$ar['state'] = 'closed';
|
||||
}
|
||||
|
||||
{ label: 'name', identifier: 'id', items: [
|
||||
<?php
|
||||
$json = displayTag(GET_TAG, intval(GET_UID));
|
||||
$json = substr($json, 0, -1); // remove final comma avoiding IE6 Dojo bug
|
||||
echo $json;
|
||||
?>
|
||||
] }
|
||||
return $ar;
|
||||
}
|
||||
|
||||
|
||||
$tag = isset($_GET['tag']) ? trim($_GET['tag']) : '';
|
||||
$tagData = assembleAdminTagData(
|
||||
$tag,
|
||||
SemanticScuttle_Service_Factory::get('Tag2Tag')
|
||||
);
|
||||
echo json_encode($tagData);
|
||||
?>
|
@ -1,44 +1,47 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
Copyright (C) 2004 - 2006 Scuttle project
|
||||
http://sourceforge.net/projects/scuttle/
|
||||
http://scuttle.org/
|
||||
/**
|
||||
* Return a json file with list of public tags used by admins and sorted
|
||||
* by popularity.
|
||||
*
|
||||
* The following GET parameters are accepted:
|
||||
* @param string $beginsWith The tag name shall start with that string.
|
||||
* No default.
|
||||
* @param integer $limit Number of tags to return. Defaults to 1000
|
||||
*
|
||||
* Part of SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
/* Return a json file with list of tags according to current user and sort by popularity*/
|
||||
$httpContentType = 'application/json';
|
||||
require_once '../www-header.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Tag');
|
||||
|
||||
?>
|
||||
|
||||
{identifier:"tag",
|
||||
items: [
|
||||
<?php
|
||||
$listTags = $b2tservice->getAdminTags(1000, $userservice->getCurrentUserId());
|
||||
foreach($listTags as $t) {
|
||||
echo "{tag: \"".$t['tag']."\"},";
|
||||
}
|
||||
?>
|
||||
]}
|
||||
|
||||
$limit = 30;
|
||||
$beginsWith = null;
|
||||
$currentUserId = $userservice->getCurrentUserId();
|
||||
|
||||
if (isset($_GET['limit']) && is_numeric($_GET['limit'])) {
|
||||
$limit = (int)$_GET['limit'];
|
||||
}
|
||||
if (isset($_GET['beginsWith']) && strlen(trim($_GET['beginsWith']))) {
|
||||
$beginsWith = trim($_GET['beginsWith']);
|
||||
}
|
||||
|
||||
$listTags = SemanticScuttle_Service_Factory::get('Bookmark2Tag')->getAdminTags(
|
||||
$limit, $currentUserId, null, $beginsWith
|
||||
);
|
||||
$tags = array();
|
||||
foreach ($listTags as $t) {
|
||||
$tags[] = $t['tag'];
|
||||
}
|
||||
|
||||
echo json_encode($tags);
|
||||
?>
|
@ -1,44 +1,47 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
Copyright (C) 2004 - 2006 Scuttle project
|
||||
http://sourceforge.net/projects/scuttle/
|
||||
http://scuttle.org/
|
||||
/**
|
||||
* Return a json file with list of tags according to current user
|
||||
* and sorted by popularity.
|
||||
*
|
||||
* The following GET parameters are accepted:
|
||||
* @param string $beginsWith The tag name shall start with that string.
|
||||
* No default.
|
||||
* @param integer $limit Number of tags to return. Defaults to 1000
|
||||
*
|
||||
* Part of SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
/* Return a json file with list of tags according to current user and sort by popularity*/
|
||||
$httpContentType = 'application/json';
|
||||
require_once '../www-header.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Tag');
|
||||
$limit = 30;
|
||||
$beginsWith = null;
|
||||
$currentUserId = $userservice->getCurrentUserId();
|
||||
|
||||
if (isset($_GET['limit']) && is_numeric($_GET['limit'])) {
|
||||
$limit = (int)$_GET['limit'];
|
||||
}
|
||||
if (isset($_GET['beginsWith']) && strlen(trim($_GET['beginsWith']))) {
|
||||
$beginsWith = trim($_GET['beginsWith']);
|
||||
}
|
||||
|
||||
$listTags = SemanticScuttle_Service_Factory::get('Bookmark2Tag')->getContactTags(
|
||||
$currentUserId, $limit, $currentUserId, null, $beginsWith
|
||||
);
|
||||
$tags = array();
|
||||
foreach ($listTags as $t) {
|
||||
$tags[] = $t['tag'];
|
||||
}
|
||||
|
||||
echo json_encode($tags);
|
||||
?>
|
||||
|
||||
{identifier:"tag",
|
||||
items: [
|
||||
<?php
|
||||
$listTags = $b2tservice->getContactTags($userservice->getCurrentUserId(), 1000, $userservice->getCurrentUserId());
|
||||
foreach($listTags as $t) {
|
||||
echo "{tag: \"".$t['tag']."\"},";
|
||||
}
|
||||
?>
|
||||
]}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,64 +1,142 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
Copyright (C) 2004 - 2006 Scuttle project
|
||||
http://sourceforge.net/projects/scuttle/
|
||||
http://scuttle.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
/* Return a json file with list of linked tags */
|
||||
/**
|
||||
* Returns a list of tags linked to the given one,
|
||||
* suitable for jsTree consumption.
|
||||
*
|
||||
* Accepted GET parameters:
|
||||
*
|
||||
* @param string $tag Tag for which the children tags shall be returned
|
||||
* Multiple tags (separated with space or "+") are
|
||||
* supported.
|
||||
* If no tag is given, all top-level tags are loaded.
|
||||
* @param integer $uId User ID to fetch the tags for
|
||||
* @param boolean $parent Load parent tags
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @subpackage Templates
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
$httpContentType = 'application/json';
|
||||
require_once '../www-header.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Tag');
|
||||
$tagstatservice =SemanticScuttle_Service_Factory::get('TagStat');
|
||||
$tag = isset($_GET['tag']) ? $_GET['tag'] : null;
|
||||
$uId = isset($_GET['uId']) ? (int)$_GET['uId'] : 0;
|
||||
$loadParentTags = isset($_GET['parent']) ? (bool)$_GET['parent'] : false;
|
||||
|
||||
/* Managing all possible inputs */
|
||||
isset($_GET['tag']) ? define('GET_TAG', $_GET['tag']): define('GET_TAG', '');
|
||||
isset($_GET['uId']) ? define('GET_UID', $_GET['uId']): define('GET_UID', '');
|
||||
|
||||
|
||||
function displayTag($tag, $uId) {
|
||||
$uId = ($uId==0)?NULL:$uId; // if user is nobody, NULL allows to look for every public tags
|
||||
|
||||
$tag2tagservice =SemanticScuttle_Service_Factory::get('Tag2Tag');
|
||||
$output = '{ id:'.rand().', name:\''.$tag.'\'';
|
||||
|
||||
$linkedTags = $tag2tagservice->getLinkedTags($tag, '>', $uId);
|
||||
if(count($linkedTags) > 0) {
|
||||
$output.= ', children: [';
|
||||
foreach($linkedTags as $linkedTag) {
|
||||
$output.= displayTag($linkedTag, $uId);
|
||||
}
|
||||
$output = substr($output, 0, -1); // remove final comma avoiding IE6 Dojo bug
|
||||
$output.= "]";
|
||||
}
|
||||
|
||||
$output.= '},';
|
||||
return $output;
|
||||
$tags = explode(' ', trim($tag));
|
||||
if (count($tags) == 1 && $tags[0] == '') {
|
||||
//no tags
|
||||
$tags = array();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
{ label: 'name', identifier: 'id', items: [
|
||||
<?php
|
||||
$json = displayTag(GET_TAG, intval(GET_UID));
|
||||
$json = substr($json, 0, -1); // remove final comma avoiding IE6 Dojo bug
|
||||
echo $json;
|
||||
?>
|
||||
] }
|
||||
function assembleLinkedTagData(
|
||||
$tags, $uId, $loadParentTags, SemanticScuttle_Service_Tag2Tag $t2t
|
||||
) {
|
||||
$tagData = array();
|
||||
|
||||
if (count($tags) == 0) {
|
||||
//no tags given -> show the 4 most used top-level tags
|
||||
$orphewTags = $t2t->getOrphewTags('>', $uId, 4, 'nb');
|
||||
#$orphewTags = $t2t->getOrphewTags('>', $uId);
|
||||
foreach ($orphewTags as $orphewTag) {
|
||||
$tags[] = $orphewTag['tag'];
|
||||
}
|
||||
$loadParentTags = true;
|
||||
}
|
||||
|
||||
if ($loadParentTags) {
|
||||
//find parent tags + append the selected tags as children afterwards
|
||||
foreach ($tags as $tag) {
|
||||
$parentTags = $t2t->getLinkedTags($tag, '>', $uId, true);
|
||||
if (count($parentTags) > 0) {
|
||||
foreach ($parentTags as $parentTag) {
|
||||
$ta = createTagArray(
|
||||
$parentTag, true, true, true
|
||||
);
|
||||
//FIXME: find out if there are subtags
|
||||
$tac = createTagArray($tag, true);
|
||||
$ta['children'][] = $tac;
|
||||
$tagData[] = $ta;
|
||||
}
|
||||
} else {
|
||||
//no parent tags -> display it normally
|
||||
//FIXME: find out if there are subtags
|
||||
$tagData[] = createTagArray($tag, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//just find the linked tags
|
||||
foreach ($tags as $tag) {
|
||||
$linkedTags = $t2t->getLinkedTags($tag, '>', $uId);
|
||||
foreach ($linkedTags as $linkedTag) {
|
||||
//FIXME: find out if there are subtags
|
||||
$tagData[] = createTagArray($linkedTag, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tagData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an jsTree json array for the given tag
|
||||
*
|
||||
* @param string $tag Tag name
|
||||
* @param boolean $hasChildren If the tag has subtags (children) or not.
|
||||
* If unsure, set it to "true".
|
||||
* @param boolean $isOpen If the tag has children: Is the tree node open
|
||||
* or closed?
|
||||
* @param boolean $autoParent If the tag is an automatically generated parent tag
|
||||
*
|
||||
* @return array Array to be sent back to the browser as json
|
||||
*/
|
||||
function createTagArray($tag, $hasChildren = true, $isOpen = false, $autoParent = false)
|
||||
{
|
||||
if ($autoParent) {
|
||||
$title = '(' . $tag . ')';
|
||||
} else {
|
||||
$title = $tag;
|
||||
}
|
||||
|
||||
$ar = array(
|
||||
'data' => array(
|
||||
//<a> attributes
|
||||
'title' => $title,
|
||||
'attr' => array(
|
||||
'href' => createUrl('tags', $tag)
|
||||
)
|
||||
),
|
||||
//<li> attributes
|
||||
'attr' => array(
|
||||
'rel' => $tag,//needed for identifying the tag in html
|
||||
),
|
||||
);
|
||||
if ($hasChildren) {
|
||||
//jstree needs that to show the arrows
|
||||
$ar['state'] = $isOpen ? 'open' : 'closed';
|
||||
}
|
||||
if ($autoParent) {
|
||||
//FIXME: use css class
|
||||
$ar['data']['attr']['style'] = 'color: #AAA';
|
||||
}
|
||||
|
||||
return $ar;
|
||||
}
|
||||
|
||||
|
||||
$tagData = assembleLinkedTagData(
|
||||
$tags, 0/*$uId*/, $loadParentTags,
|
||||
SemanticScuttle_Service_Factory::get('Tag2Tag')
|
||||
);
|
||||
echo json_encode($tagData);
|
||||
?>
|
@ -22,6 +22,8 @@
|
||||
// del.icio.us behavior:
|
||||
// - doesn't include the filtered tag as an attribute on the root element (we do)
|
||||
|
||||
//this page here is really not valid in any way
|
||||
$httpContentType = 'text/html';
|
||||
// Force HTTP authentication first!
|
||||
require_once 'httpauth.inc.php';
|
||||
|
||||
|
@ -1,10 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Checks if the user is logged on and sends a HTTP basic auth
|
||||
* request to the browser if not. In that case the script ends.
|
||||
* If username and password are available, the user service's
|
||||
* login method is used to log the user in.
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
*/
|
||||
require_once '../www-header.php';
|
||||
|
||||
// Provides HTTP Basic authentication of a user
|
||||
// and logs the user in if necessary
|
||||
|
||||
function authenticate() {
|
||||
/**
|
||||
* Sends HTTP auth headers to the browser
|
||||
*/
|
||||
function authenticate()
|
||||
{
|
||||
header('WWW-Authenticate: Basic realm="SemanticScuttle API"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
|
||||
@ -26,7 +45,9 @@ if (!$userservice->isLoggedOn()) {
|
||||
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
authenticate();
|
||||
} else {
|
||||
$login = $userservice->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
|
||||
$login = $userservice->login(
|
||||
$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']
|
||||
);
|
||||
if ($login) {
|
||||
$currentUser = $userservice->getCurrentObjectUser();
|
||||
} else {
|
||||
|
@ -1,67 +1,105 @@
|
||||
<?php
|
||||
// Implements the del.icio.us API request to add a new post.
|
||||
// http://delicious.com/help/api#posts_add
|
||||
|
||||
// del.icio.us behavior:
|
||||
// - tags can't have spaces
|
||||
// - address and description are mandatory
|
||||
|
||||
// Scuttle behavior:
|
||||
// - Additional 'status' variable for privacy
|
||||
// - No support for 'replace' variable
|
||||
/**
|
||||
* API for adding a new bookmark.
|
||||
*
|
||||
* The following POST and GET parameters are accepted:
|
||||
* @param string $url URL of the bookmark (required)
|
||||
* @param string $description Bookmark title (required)
|
||||
* @param string $extended Extended bookmark description (optional)
|
||||
* @param string $tags Space-separated list of tags (optional)
|
||||
* @param string $dt Date and time of bookmark creation (optional)
|
||||
* Must be of format YYYY-MM-DDTHH:II:SSZ
|
||||
* @param integer $status Visibility status (optional):
|
||||
* - 2 or 'private': Bookmark is totally private
|
||||
* - 1 or 'shared': People on the user's watchlist
|
||||
* can see it
|
||||
* - 0 or 'public': Everyone can see the bookmark
|
||||
* @param string $shared "no" or "yes": Switches between private and
|
||||
* public (optional)
|
||||
* @param string $replace "yes" or "no" - replaces a bookmark with the
|
||||
* same URL (optional)
|
||||
*
|
||||
* Notes:
|
||||
* - tags cannot have spaces
|
||||
* - URL and description (title) are mandatory
|
||||
* - delicious "description" is the "title" in SemanticScuttle
|
||||
* - delicious "extended" is the "description" in SemanticScuttle
|
||||
* - "status" is a SemanticScuttle addition to this API method
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
* @link http://www.delicious.com/help/api
|
||||
*/
|
||||
|
||||
// Force HTTP authentication
|
||||
$httpContentType = 'text/xml';
|
||||
require_once 'httpauth.inc.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$bs = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
|
||||
// Get all the bookmark's passed-in information
|
||||
if (isset($_REQUEST['url']) && (trim($_REQUEST['url']) != ''))
|
||||
if (isset($_REQUEST['url']) && (trim($_REQUEST['url']) != '')) {
|
||||
$url = trim(urldecode($_REQUEST['url']));
|
||||
else
|
||||
$url = NULL;
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['description']) && (trim($_REQUEST['description']) != ''))
|
||||
if (isset($_REQUEST['description']) && (trim($_REQUEST['description']) != '')) {
|
||||
$description = trim($_REQUEST['description']);
|
||||
else
|
||||
$description = NULL;
|
||||
} else {
|
||||
$description = null;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['extended']) && (trim($_REQUEST['extended']) != ""))
|
||||
if (isset($_REQUEST['extended']) && (trim($_REQUEST['extended']) != '')) {
|
||||
$extended = trim($_REQUEST['extended']);
|
||||
else
|
||||
$extended = NULL;
|
||||
} else {
|
||||
$extended = null;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['tags']) && (trim($_REQUEST['tags']) != '') && (trim($_REQUEST['tags']) != ','))
|
||||
if (isset($_REQUEST['tags']) && (trim($_REQUEST['tags']) != '')
|
||||
&& (trim($_REQUEST['tags']) != ',')
|
||||
) {
|
||||
$tags = trim($_REQUEST['tags']);
|
||||
else
|
||||
$tags = NULL;
|
||||
} else {
|
||||
$tags = null;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['dt']) && (trim($_REQUEST['dt']) != ''))
|
||||
if (isset($_REQUEST['dt']) && (trim($_REQUEST['dt']) != '')) {
|
||||
$dt = trim($_REQUEST['dt']);
|
||||
else
|
||||
$dt = NULL;
|
||||
} else {
|
||||
$dt = null;
|
||||
}
|
||||
|
||||
$replace = isset($_REQUEST['replace']) && ($_REQUEST['replace'] == 'yes');
|
||||
|
||||
$status = 0;
|
||||
if (isset($_REQUEST['status'])) {
|
||||
$status_str = trim($_REQUEST['status']);
|
||||
if (is_numeric($status_str)) {
|
||||
$status = intval($status_str);
|
||||
if($status < 0 || $status > 2) {
|
||||
if ($status < 0 || $status > 2) {
|
||||
$status = 0;
|
||||
}
|
||||
} else {
|
||||
switch ($status_str) {
|
||||
case 'private':
|
||||
$status = 2;
|
||||
break;
|
||||
case 'shared':
|
||||
$status = 1;
|
||||
break;
|
||||
default:
|
||||
$status = 0;
|
||||
break;
|
||||
case 'private':
|
||||
$status = 2;
|
||||
break;
|
||||
case 'shared':
|
||||
$status = 1;
|
||||
break;
|
||||
default:
|
||||
$status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,17 +109,38 @@ if (isset($_REQUEST['shared']) && (trim($_REQUEST['shared']) == 'no')) {
|
||||
}
|
||||
|
||||
// Error out if there's no address or description
|
||||
if (is_null($url) || is_null($description)) {
|
||||
$added = false;
|
||||
if (is_null($url)) {
|
||||
header('HTTP/1.0 400 Bad Request');
|
||||
$msg = 'URL missing';
|
||||
} else if (is_null($description)) {
|
||||
header('HTTP/1.0 400 Bad Request');
|
||||
$msg = 'Description missing';
|
||||
} else {
|
||||
// We're good with info; now insert it!
|
||||
if ($bookmarkservice->bookmarkExists($url, $userservice->getCurrentUserId()))
|
||||
$added = false;
|
||||
else
|
||||
$added = $bookmarkservice->addBookmark($url, $description, $extended, '', $status, $tags, null, $dt, true);
|
||||
// We're good with info; now insert it!
|
||||
$exists = $bs->bookmarkExists($url, $userservice->getCurrentUserId());
|
||||
if ($exists) {
|
||||
if (!$replace) {
|
||||
header('HTTP/1.0 409 Conflict');
|
||||
$msg = 'bookmark does already exist';
|
||||
} else {
|
||||
//delete it before we re-add it
|
||||
$bookmark = $bs->getBookmarkByAddress($url, false);
|
||||
$bId = $bookmark['bId'];
|
||||
$bs->deleteBookmark($bId);
|
||||
|
||||
$exists = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$exists) {
|
||||
$added = $bs->addBookmark(
|
||||
$url, $description, $extended, '', $status, $tags, null, $dt, true
|
||||
);
|
||||
$msg = 'done';
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the XML file and output the result.
|
||||
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
|
||||
echo '<result code="'. ($added ? 'done' : 'something went wrong') .'" />';
|
||||
echo '<?xml version="1.0" standalone="yes" ?' . ">\r\n";
|
||||
echo '<result code="' . $msg .'" />';
|
||||
?>
|
@ -1,33 +1,57 @@
|
||||
<?php
|
||||
// Implements the del.icio.us API request to delete a post.
|
||||
|
||||
// del.icio.us behavior:
|
||||
// - returns "done" even if the bookmark doesn't exist;
|
||||
// - does NOT allow the hash for the url parameter;
|
||||
// - doesn't set the Content-Type to text/xml (we do).
|
||||
/**
|
||||
* API for deleting a bookmark.
|
||||
* The delicious API is implemented here.
|
||||
*
|
||||
* The delicious API behaves like that:
|
||||
* - does NOT allow the hash for the url parameter
|
||||
* - doesn't set the Content-Type to text/xml
|
||||
* - we do it correctly, too
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
* @link http://www.delicious.com/help/api
|
||||
*/
|
||||
|
||||
// Force HTTP authentication first!
|
||||
$httpContentType = 'text/xml';
|
||||
require_once 'httpauth.inc.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$bs = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
$uId = $userservice->getCurrentUserId();
|
||||
|
||||
|
||||
// Note that del.icio.us only errors out if no URL was passed in; there's no error on attempting
|
||||
// to delete a bookmark you don't have.
|
||||
|
||||
// Error out if there's no address
|
||||
if (is_null($_REQUEST['url'])) {
|
||||
$deleted = false;
|
||||
if (!isset($_REQUEST['url'])
|
||||
|| $_REQUEST['url'] == ''
|
||||
) {
|
||||
$msg = 'something went wrong';
|
||||
} else if (!$bs->bookmarkExists($_REQUEST['url'], $uId)) {
|
||||
//the user does not have such a bookmark
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$msg = 'item not found';
|
||||
} else {
|
||||
$bookmark = $bookmarkservice->getBookmarkByAddress($_REQUEST['url']);
|
||||
$bid = $bookmark['bId'];
|
||||
$delete = $bookmarkservice->deleteBookmark($bid);
|
||||
$deleted = true;
|
||||
$bookmark = $bs->getBookmarkByAddress($_REQUEST['url'], false);
|
||||
$bId = $bookmark['bId'];
|
||||
$deleted = $bs->deleteBookmark($bId);
|
||||
$msg = 'done';
|
||||
if (!$deleted) {
|
||||
//something really went wrong
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
$msg = 'something really went wrong';
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the XML file and output the result.
|
||||
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
|
||||
echo '<result code="'. ($deleted ? 'done' : 'something went wrong') .'" />';
|
||||
echo '<?xml version="1.0" standalone="yes" ?' . ">\r\n";
|
||||
echo '<result code="' . $msg . '" />';
|
||||
?>
|
@ -1,24 +1,44 @@
|
||||
<?php
|
||||
// Implements the del.icio.us API request for a user's last update time and date.
|
||||
|
||||
// del.icio.us behavior:
|
||||
// - doesn't set the Content-Type to text/xml (we do).
|
||||
/**
|
||||
* API for retrieving a user's last update time.
|
||||
* That is the time the user changed a bookmark lastly.
|
||||
* The delicious API is implemented here.
|
||||
*
|
||||
* Delicious also returns "the number of new items in
|
||||
* the user's inbox since it was last visited." - we do
|
||||
* that too, so we are as close at the API as possible,
|
||||
* not breaking delicious clients.
|
||||
*
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @author Eric Dane <ericdane@users.sourceforge.net>
|
||||
* @license GPL http://www.gnu.org/licenses/gpl.html
|
||||
* @link http://sourceforge.net/projects/semanticscuttle
|
||||
* @link http://www.delicious.com/help/api
|
||||
*/
|
||||
|
||||
// Force HTTP authentication first!
|
||||
$httpContentType = 'text/xml';
|
||||
require_once 'httpauth.inc.php';
|
||||
|
||||
/* Service creation: only useful services are created */
|
||||
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
|
||||
|
||||
// Get the posts relevant to the passed-in variables.
|
||||
$bookmarks =& $bookmarkservice->getBookmarks(0, 1, $userservice->getCurrentUserId());
|
||||
$bs = SemanticScuttle_Service_Factory::get('Bookmark');
|
||||
|
||||
$bookmarks = $bs->getBookmarks(0, 1, $userservice->getCurrentUserId());
|
||||
|
||||
// Set up the XML file and output all the tags.
|
||||
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
|
||||
foreach($bookmarks['bookmarks'] as $row) {
|
||||
echo '<update time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) .'" />';
|
||||
echo '<?xml version="1.0" standalone="yes" ?' . ">\r\n";
|
||||
//foreach is used in case there are no bookmarks
|
||||
foreach ($bookmarks['bookmarks'] as $row) {
|
||||
echo '<update time="'
|
||||
. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime']))
|
||||
. '"'
|
||||
. ' inboxnew="0"'
|
||||
. ' />';
|
||||
}
|
||||
?>
|
@ -41,7 +41,6 @@ isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('PO
|
||||
isset($_POST['description']) ? define('POST_DESCRIPTION', $_POST['description']): define('POST_DESCRIPTION', '');
|
||||
isset($_POST['privateNote']) ? define('POST_PRIVATENOTE', $_POST['privateNote']): define('POST_PRIVATENOTE', '');
|
||||
isset($_POST['status']) ? define('POST_STATUS', $_POST['status']): define('POST_STATUS', '');
|
||||
isset($_POST['tags']) ? define('POST_TAGS', $_POST['tags']): define('POST_TAGS', '');
|
||||
isset($_POST['referrer']) ? define('POST_REFERRER', $_POST['referrer']): define('POST_REFERRER', '');
|
||||
|
||||
isset($_GET['popup']) ? define('GET_POPUP', $_GET['popup']): define('GET_POPUP', '');
|
||||
@ -50,6 +49,10 @@ isset($_POST['popup']) ? define('POST_POPUP', $_POST['popup']): define('POST_POP
|
||||
isset($_GET['page']) ? define('GET_PAGE', $_GET['page']): define('GET_PAGE', 0);
|
||||
isset($_GET['sort']) ? define('GET_SORT', $_GET['sort']): define('GET_SORT', '');
|
||||
|
||||
if (!isset($_POST['tags'])) {
|
||||
$_POST['tags'] = array();
|
||||
}
|
||||
//echo '<p>' . var_export($_POST, true) . '</p>';die();
|
||||
|
||||
|
||||
if ((GET_ACTION == "add") && !$userservice->isLoggedOn()) {
|
||||
@ -143,7 +146,7 @@ if ($userservice->isLoggedOn() && POST_SUBMITTED != '') {
|
||||
$description = trim(POST_DESCRIPTION);
|
||||
$privateNote = trim(POST_PRIVATENOTE);
|
||||
$status = intval(POST_STATUS);
|
||||
$categories = trim(POST_TAGS);
|
||||
$categories = explode(',', $_POST['tags']);
|
||||
$saved = true;
|
||||
if ($bookmarkservice->addBookmark($address, $title, $description, $privateNote, $status, $categories)) {
|
||||
if (POST_POPUP != '') {
|
||||
@ -184,10 +187,10 @@ if ($templatename == 'editbookmark.tpl') {
|
||||
'bAddress' => stripslashes(POST_ADDRESS),
|
||||
'bDescription' => stripslashes(POST_DESCRIPTION),
|
||||
'bPrivateNote' => stripslashes(POST_PRIVATENOTE),
|
||||
'tags' => (POST_TAGS ? explode(',', stripslashes(POST_TAGS)) : array()),
|
||||
'tags' => ($_POST['tags'] ? $_POST['tags'] : array()),
|
||||
'bStatus' => 0,
|
||||
);
|
||||
$tplVars['tags'] = POST_TAGS;
|
||||
$tplVars['tags'] = $_POST['tags'];
|
||||
} else {
|
||||
if(GET_COPYOF != '') { //copy from bookmarks page
|
||||
$tplVars['row'] = $bookmarkservice->getBookmark(intval(GET_COPYOF), true);
|
||||
|
@ -31,7 +31,9 @@ if($GLOBALS['enableGoogleCustomSearch']==false) {
|
||||
echo '<p><small>';
|
||||
echo T_('Admin tips: ');
|
||||
echo T_('To refresh manually Google Custom Search Engine, goes to: ');
|
||||
echo '<a href="http://www.google.com/coop/cse/cref?cref='.ROOT.'search/context.php">http://www.google.com/coop/cse/cref</a><br/>';
|
||||
echo '<a href="http://www.google.com/coop/cse/cref?cref='
|
||||
. ROOT . 'gsearch/context.php">http://www.google.com/coop/cse/cref</a>'
|
||||
. '<br/>';
|
||||
echo T_('If no result appears, check that all the urls are valid in the admin section.');
|
||||
echo '</small></p>';
|
||||
|
||||
|
612
www/js/jquery-ui-1.8.11/jquery.ui.autocomplete.js
vendored
Normal file
612
www/js/jquery-ui-1.8.11/jquery.ui.autocomplete.js
vendored
Normal file
@ -0,0 +1,612 @@
|
||||
/*
|
||||
* jQuery UI Autocomplete 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Autocomplete
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.position.js
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
// used to prevent race conditions with remote data sources
|
||||
var requestIndex = 0;
|
||||
|
||||
$.widget( "ui.autocomplete", {
|
||||
options: {
|
||||
appendTo: "body",
|
||||
autoFocus: false,
|
||||
delay: 300,
|
||||
minLength: 1,
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "left bottom",
|
||||
collision: "none"
|
||||
},
|
||||
source: null
|
||||
},
|
||||
|
||||
pending: 0,
|
||||
|
||||
_create: function() {
|
||||
var self = this,
|
||||
doc = this.element[ 0 ].ownerDocument,
|
||||
suppressKeyPress;
|
||||
|
||||
this.element
|
||||
.addClass( "ui-autocomplete-input" )
|
||||
.attr( "autocomplete", "off" )
|
||||
// TODO verify these actually work as intended
|
||||
.attr({
|
||||
role: "textbox",
|
||||
"aria-autocomplete": "list",
|
||||
"aria-haspopup": "true"
|
||||
})
|
||||
.bind( "keydown.autocomplete", function( event ) {
|
||||
if ( self.options.disabled || self.element.attr( "readonly" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
suppressKeyPress = false;
|
||||
var keyCode = $.ui.keyCode;
|
||||
switch( event.keyCode ) {
|
||||
case keyCode.PAGE_UP:
|
||||
self._move( "previousPage", event );
|
||||
break;
|
||||
case keyCode.PAGE_DOWN:
|
||||
self._move( "nextPage", event );
|
||||
break;
|
||||
case keyCode.UP:
|
||||
self._move( "previous", event );
|
||||
// prevent moving cursor to beginning of text field in some browsers
|
||||
event.preventDefault();
|
||||
break;
|
||||
case keyCode.DOWN:
|
||||
self._move( "next", event );
|
||||
// prevent moving cursor to end of text field in some browsers
|
||||
event.preventDefault();
|
||||
break;
|
||||
case keyCode.ENTER:
|
||||
case keyCode.NUMPAD_ENTER:
|
||||
// when menu is open and has focus
|
||||
if ( self.menu.active ) {
|
||||
// #6055 - Opera still allows the keypress to occur
|
||||
// which causes forms to submit
|
||||
suppressKeyPress = true;
|
||||
event.preventDefault();
|
||||
}
|
||||
//passthrough - ENTER and TAB both select the current element
|
||||
case keyCode.TAB:
|
||||
if ( !self.menu.active ) {
|
||||
return;
|
||||
}
|
||||
self.menu.select( event );
|
||||
break;
|
||||
case keyCode.ESCAPE:
|
||||
self.element.val( self.term );
|
||||
self.close( event );
|
||||
break;
|
||||
default:
|
||||
// keypress is triggered before the input value is changed
|
||||
clearTimeout( self.searching );
|
||||
self.searching = setTimeout(function() {
|
||||
// only search if the value has changed
|
||||
if ( self.term != self.element.val() ) {
|
||||
self.selectedItem = null;
|
||||
self.search( null, event );
|
||||
}
|
||||
}, self.options.delay );
|
||||
break;
|
||||
}
|
||||
})
|
||||
.bind( "keypress.autocomplete", function( event ) {
|
||||
if ( suppressKeyPress ) {
|
||||
suppressKeyPress = false;
|
||||
event.preventDefault();
|
||||
}
|
||||
})
|
||||
.bind( "focus.autocomplete", function() {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.selectedItem = null;
|
||||
self.previous = self.element.val();
|
||||
})
|
||||
.bind( "blur.autocomplete", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout( self.searching );
|
||||
// clicks on the menu (or a button to trigger a search) will cause a blur event
|
||||
self.closing = setTimeout(function() {
|
||||
self.close( event );
|
||||
self._change( event );
|
||||
}, 150 );
|
||||
});
|
||||
this._initSource();
|
||||
this.response = function() {
|
||||
return self._response.apply( self, arguments );
|
||||
};
|
||||
this.menu = $( "<ul></ul>" )
|
||||
.addClass( "ui-autocomplete" )
|
||||
.appendTo( $( this.options.appendTo || "body", doc )[0] )
|
||||
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
|
||||
.mousedown(function( event ) {
|
||||
// clicking on the scrollbar causes focus to shift to the body
|
||||
// but we can't detect a mouseup or a click immediately afterward
|
||||
// so we have to track the next mousedown and close the menu if
|
||||
// the user clicks somewhere outside of the autocomplete
|
||||
var menuElement = self.menu.element[ 0 ];
|
||||
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
|
||||
setTimeout(function() {
|
||||
$( document ).one( 'mousedown', function( event ) {
|
||||
if ( event.target !== self.element[ 0 ] &&
|
||||
event.target !== menuElement &&
|
||||
!$.ui.contains( menuElement, event.target ) ) {
|
||||
self.close();
|
||||
}
|
||||
});
|
||||
}, 1 );
|
||||
}
|
||||
|
||||
// use another timeout to make sure the blur-event-handler on the input was already triggered
|
||||
setTimeout(function() {
|
||||
clearTimeout( self.closing );
|
||||
}, 13);
|
||||
})
|
||||
.menu({
|
||||
focus: function( event, ui ) {
|
||||
var item = ui.item.data( "item.autocomplete" );
|
||||
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
|
||||
// use value to match what will end up in the input, if it was a key event
|
||||
if ( /^key/.test(event.originalEvent.type) ) {
|
||||
self.element.val( item.value );
|
||||
}
|
||||
}
|
||||
},
|
||||
selected: function( event, ui ) {
|
||||
var item = ui.item.data( "item.autocomplete" ),
|
||||
previous = self.previous;
|
||||
|
||||
// only trigger when focus was lost (click on menu)
|
||||
if ( self.element[0] !== doc.activeElement ) {
|
||||
self.element.focus();
|
||||
self.previous = previous;
|
||||
// #6109 - IE triggers two focus events and the second
|
||||
// is asynchronous, so we need to reset the previous
|
||||
// term synchronously and asynchronously :-(
|
||||
setTimeout(function() {
|
||||
self.previous = previous;
|
||||
self.selectedItem = item;
|
||||
}, 1);
|
||||
}
|
||||
|
||||
if ( false !== self._trigger( "select", event, { item: item } ) ) {
|
||||
self.element.val( item.value );
|
||||
}
|
||||
// reset the term after the select event
|
||||
// this allows custom select handling to work properly
|
||||
self.term = self.element.val();
|
||||
|
||||
self.close( event );
|
||||
self.selectedItem = item;
|
||||
},
|
||||
blur: function( event, ui ) {
|
||||
// don't set the value of the text field if it's already correct
|
||||
// this prevents moving the cursor unnecessarily
|
||||
if ( self.menu.element.is(":visible") &&
|
||||
( self.element.val() !== self.term ) ) {
|
||||
self.element.val( self.term );
|
||||
}
|
||||
}
|
||||
})
|
||||
.zIndex( this.element.zIndex() + 1 )
|
||||
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
|
||||
.css({ top: 0, left: 0 })
|
||||
.hide()
|
||||
.data( "menu" );
|
||||
if ( $.fn.bgiframe ) {
|
||||
this.menu.element.bgiframe();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.element
|
||||
.removeClass( "ui-autocomplete-input" )
|
||||
.removeAttr( "autocomplete" )
|
||||
.removeAttr( "role" )
|
||||
.removeAttr( "aria-autocomplete" )
|
||||
.removeAttr( "aria-haspopup" );
|
||||
this.menu.element.remove();
|
||||
$.Widget.prototype.destroy.call( this );
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
$.Widget.prototype._setOption.apply( this, arguments );
|
||||
if ( key === "source" ) {
|
||||
this._initSource();
|
||||
}
|
||||
if ( key === "appendTo" ) {
|
||||
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
|
||||
}
|
||||
if ( key === "disabled" && value && this.xhr ) {
|
||||
this.xhr.abort();
|
||||
}
|
||||
},
|
||||
|
||||
_initSource: function() {
|
||||
var self = this,
|
||||
array,
|
||||
url;
|
||||
if ( $.isArray(this.options.source) ) {
|
||||
array = this.options.source;
|
||||
this.source = function( request, response ) {
|
||||
response( $.ui.autocomplete.filter(array, request.term) );
|
||||
};
|
||||
} else if ( typeof this.options.source === "string" ) {
|
||||
url = this.options.source;
|
||||
this.source = function( request, response ) {
|
||||
if ( self.xhr ) {
|
||||
self.xhr.abort();
|
||||
}
|
||||
self.xhr = $.ajax({
|
||||
url: url,
|
||||
data: request,
|
||||
dataType: "json",
|
||||
autocompleteRequest: ++requestIndex,
|
||||
success: function( data, status ) {
|
||||
if ( this.autocompleteRequest === requestIndex ) {
|
||||
response( data );
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
if ( this.autocompleteRequest === requestIndex ) {
|
||||
response( [] );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
} else {
|
||||
this.source = this.options.source;
|
||||
}
|
||||
},
|
||||
|
||||
search: function( value, event ) {
|
||||
value = value != null ? value : this.element.val();
|
||||
|
||||
// always save the actual value, not the one passed as an argument
|
||||
this.term = this.element.val();
|
||||
|
||||
if ( value.length < this.options.minLength ) {
|
||||
return this.close( event );
|
||||
}
|
||||
|
||||
clearTimeout( this.closing );
|
||||
if ( this._trigger( "search", event ) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this._search( value );
|
||||
},
|
||||
|
||||
_search: function( value ) {
|
||||
this.pending++;
|
||||
this.element.addClass( "ui-autocomplete-loading" );
|
||||
|
||||
this.source( { term: value }, this.response );
|
||||
},
|
||||
|
||||
_response: function( content ) {
|
||||
if ( !this.options.disabled && content && content.length ) {
|
||||
content = this._normalize( content );
|
||||
this._suggest( content );
|
||||
this._trigger( "open" );
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
this.pending--;
|
||||
if ( !this.pending ) {
|
||||
this.element.removeClass( "ui-autocomplete-loading" );
|
||||
}
|
||||
},
|
||||
|
||||
close: function( event ) {
|
||||
clearTimeout( this.closing );
|
||||
if ( this.menu.element.is(":visible") ) {
|
||||
this.menu.element.hide();
|
||||
this.menu.deactivate();
|
||||
this._trigger( "close", event );
|
||||
}
|
||||
},
|
||||
|
||||
_change: function( event ) {
|
||||
if ( this.previous !== this.element.val() ) {
|
||||
this._trigger( "change", event, { item: this.selectedItem } );
|
||||
}
|
||||
},
|
||||
|
||||
_normalize: function( items ) {
|
||||
// assume all items have the right format when the first item is complete
|
||||
if ( items.length && items[0].label && items[0].value ) {
|
||||
return items;
|
||||
}
|
||||
return $.map( items, function(item) {
|
||||
if ( typeof item === "string" ) {
|
||||
return {
|
||||
label: item,
|
||||
value: item
|
||||
};
|
||||
}
|
||||
return $.extend({
|
||||
label: item.label || item.value,
|
||||
value: item.value || item.label
|
||||
}, item );
|
||||
});
|
||||
},
|
||||
|
||||
_suggest: function( items ) {
|
||||
var ul = this.menu.element
|
||||
.empty()
|
||||
.zIndex( this.element.zIndex() + 1 );
|
||||
this._renderMenu( ul, items );
|
||||
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
|
||||
this.menu.deactivate();
|
||||
this.menu.refresh();
|
||||
|
||||
// size and position menu
|
||||
ul.show();
|
||||
this._resizeMenu();
|
||||
ul.position( $.extend({
|
||||
of: this.element
|
||||
}, this.options.position ));
|
||||
|
||||
if ( this.options.autoFocus ) {
|
||||
this.menu.next( new $.Event("mouseover") );
|
||||
}
|
||||
},
|
||||
|
||||
_resizeMenu: function() {
|
||||
var ul = this.menu.element;
|
||||
ul.outerWidth( Math.max(
|
||||
ul.width( "" ).outerWidth(),
|
||||
this.element.outerWidth()
|
||||
) );
|
||||
},
|
||||
|
||||
_renderMenu: function( ul, items ) {
|
||||
var self = this;
|
||||
$.each( items, function( index, item ) {
|
||||
self._renderItem( ul, item );
|
||||
});
|
||||
},
|
||||
|
||||
_renderItem: function( ul, item) {
|
||||
return $( "<li></li>" )
|
||||
.data( "item.autocomplete", item )
|
||||
.append( $( "<a></a>" ).text( item.label ) )
|
||||
.appendTo( ul );
|
||||
},
|
||||
|
||||
_move: function( direction, event ) {
|
||||
if ( !this.menu.element.is(":visible") ) {
|
||||
this.search( null, event );
|
||||
return;
|
||||
}
|
||||
if ( this.menu.first() && /^previous/.test(direction) ||
|
||||
this.menu.last() && /^next/.test(direction) ) {
|
||||
this.element.val( this.term );
|
||||
this.menu.deactivate();
|
||||
return;
|
||||
}
|
||||
this.menu[ direction ]( event );
|
||||
},
|
||||
|
||||
widget: function() {
|
||||
return this.menu.element;
|
||||
}
|
||||
});
|
||||
|
||||
$.extend( $.ui.autocomplete, {
|
||||
escapeRegex: function( value ) {
|
||||
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
},
|
||||
filter: function(array, term) {
|
||||
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
|
||||
return $.grep( array, function(value) {
|
||||
return matcher.test( value.label || value.value || value );
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}( jQuery ));
|
||||
|
||||
/*
|
||||
* jQuery UI Menu (not officially released)
|
||||
*
|
||||
* This widget isn't yet finished and the API is subject to change. We plan to finish
|
||||
* it for the next release. You're welcome to give it a try anyway and give us feedback,
|
||||
* as long as you're okay with migrating your code later on. We can help with that, too.
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Menu
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.widget("ui.menu", {
|
||||
_create: function() {
|
||||
var self = this;
|
||||
this.element
|
||||
.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
|
||||
.attr({
|
||||
role: "listbox",
|
||||
"aria-activedescendant": "ui-active-menuitem"
|
||||
})
|
||||
.click(function( event ) {
|
||||
if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
|
||||
return;
|
||||
}
|
||||
// temporary
|
||||
event.preventDefault();
|
||||
self.select( event );
|
||||
});
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var self = this;
|
||||
|
||||
// don't refresh list items that are already adapted
|
||||
var items = this.element.children("li:not(.ui-menu-item):has(a)")
|
||||
.addClass("ui-menu-item")
|
||||
.attr("role", "menuitem");
|
||||
|
||||
items.children("a")
|
||||
.addClass("ui-corner-all")
|
||||
.attr("tabindex", -1)
|
||||
// mouseenter doesn't work with event delegation
|
||||
.mouseenter(function( event ) {
|
||||
self.activate( event, $(this).parent() );
|
||||
})
|
||||
.mouseleave(function() {
|
||||
self.deactivate();
|
||||
});
|
||||
},
|
||||
|
||||
activate: function( event, item ) {
|
||||
this.deactivate();
|
||||
if (this.hasScroll()) {
|
||||
var offset = item.offset().top - this.element.offset().top,
|
||||
scroll = this.element.attr("scrollTop"),
|
||||
elementHeight = this.element.height();
|
||||
if (offset < 0) {
|
||||
this.element.attr("scrollTop", scroll + offset);
|
||||
} else if (offset >= elementHeight) {
|
||||
this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
|
||||
}
|
||||
}
|
||||
this.active = item.eq(0)
|
||||
.children("a")
|
||||
.addClass("ui-state-hover")
|
||||
.attr("id", "ui-active-menuitem")
|
||||
.end();
|
||||
this._trigger("focus", event, { item: item });
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
if (!this.active) { return; }
|
||||
|
||||
this.active.children("a")
|
||||
.removeClass("ui-state-hover")
|
||||
.removeAttr("id");
|
||||
this._trigger("blur");
|
||||
this.active = null;
|
||||
},
|
||||
|
||||
next: function(event) {
|
||||
this.move("next", ".ui-menu-item:first", event);
|
||||
},
|
||||
|
||||
previous: function(event) {
|
||||
this.move("prev", ".ui-menu-item:last", event);
|
||||
},
|
||||
|
||||
first: function() {
|
||||
return this.active && !this.active.prevAll(".ui-menu-item").length;
|
||||
},
|
||||
|
||||
last: function() {
|
||||
return this.active && !this.active.nextAll(".ui-menu-item").length;
|
||||
},
|
||||
|
||||
move: function(direction, edge, event) {
|
||||
if (!this.active) {
|
||||
this.activate(event, this.element.children(edge));
|
||||
return;
|
||||
}
|
||||
var next = this.active[direction + "All"](".ui-menu-item").eq(0);
|
||||
if (next.length) {
|
||||
this.activate(event, next);
|
||||
} else {
|
||||
this.activate(event, this.element.children(edge));
|
||||
}
|
||||
},
|
||||
|
||||
// TODO merge with previousPage
|
||||
nextPage: function(event) {
|
||||
if (this.hasScroll()) {
|
||||
// TODO merge with no-scroll-else
|
||||
if (!this.active || this.last()) {
|
||||
this.activate(event, this.element.children(".ui-menu-item:first"));
|
||||
return;
|
||||
}
|
||||
var base = this.active.offset().top,
|
||||
height = this.element.height(),
|
||||
result = this.element.children(".ui-menu-item").filter(function() {
|
||||
var close = $(this).offset().top - base - height + $(this).height();
|
||||
// TODO improve approximation
|
||||
return close < 10 && close > -10;
|
||||
});
|
||||
|
||||
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
||||
if (!result.length) {
|
||||
result = this.element.children(".ui-menu-item:last");
|
||||
}
|
||||
this.activate(event, result);
|
||||
} else {
|
||||
this.activate(event, this.element.children(".ui-menu-item")
|
||||
.filter(!this.active || this.last() ? ":first" : ":last"));
|
||||
}
|
||||
},
|
||||
|
||||
// TODO merge with nextPage
|
||||
previousPage: function(event) {
|
||||
if (this.hasScroll()) {
|
||||
// TODO merge with no-scroll-else
|
||||
if (!this.active || this.first()) {
|
||||
this.activate(event, this.element.children(".ui-menu-item:last"));
|
||||
return;
|
||||
}
|
||||
|
||||
var base = this.active.offset().top,
|
||||
height = this.element.height();
|
||||
result = this.element.children(".ui-menu-item").filter(function() {
|
||||
var close = $(this).offset().top - base + height - $(this).height();
|
||||
// TODO improve approximation
|
||||
return close < 10 && close > -10;
|
||||
});
|
||||
|
||||
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
||||
if (!result.length) {
|
||||
result = this.element.children(".ui-menu-item:first");
|
||||
}
|
||||
this.activate(event, result);
|
||||
} else {
|
||||
this.activate(event, this.element.children(".ui-menu-item")
|
||||
.filter(!this.active || this.first() ? ":last" : ":first"));
|
||||
}
|
||||
},
|
||||
|
||||
hasScroll: function() {
|
||||
return this.element.height() < this.element.attr("scrollHeight");
|
||||
},
|
||||
|
||||
select: function( event ) {
|
||||
this._trigger("selected", event, { item: this.active });
|
||||
}
|
||||
});
|
||||
|
||||
}(jQuery));
|
32
www/js/jquery-ui-1.8.11/jquery.ui.autocomplete.min.js
vendored
Normal file
32
www/js/jquery-ui-1.8.11/jquery.ui.autocomplete.min.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* jQuery UI Autocomplete 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Autocomplete
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.position.js
|
||||
*/
|
||||
(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g=
|
||||
false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=
|
||||
a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};
|
||||
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&&
|
||||
a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
|
||||
d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&
|
||||
b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source=
|
||||
this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();
|
||||
this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||
|
||||
b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var g=this;
|
||||
d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
|
||||
"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery);
|
||||
(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
|
||||
-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.attr("scrollTop"),c=this.element.height();if(b<0)this.element.attr("scrollTop",g+b);else b>=c&&this.element.attr("scrollTop",g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},
|
||||
deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);
|
||||
e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,
|
||||
g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));
|
||||
this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery);
|
308
www/js/jquery-ui-1.8.11/jquery.ui.core.js
vendored
Normal file
308
www/js/jquery-ui-1.8.11/jquery.ui.core.js
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
/*!
|
||||
* jQuery UI 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
// prevent duplicate loading
|
||||
// this is only a problem because we proxy existing functions
|
||||
// and we don't want to double proxy them
|
||||
$.ui = $.ui || {};
|
||||
if ( $.ui.version ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.extend( $.ui, {
|
||||
version: "1.8.11",
|
||||
|
||||
keyCode: {
|
||||
ALT: 18,
|
||||
BACKSPACE: 8,
|
||||
CAPS_LOCK: 20,
|
||||
COMMA: 188,
|
||||
COMMAND: 91,
|
||||
COMMAND_LEFT: 91, // COMMAND
|
||||
COMMAND_RIGHT: 93,
|
||||
CONTROL: 17,
|
||||
DELETE: 46,
|
||||
DOWN: 40,
|
||||
END: 35,
|
||||
ENTER: 13,
|
||||
ESCAPE: 27,
|
||||
HOME: 36,
|
||||
INSERT: 45,
|
||||
LEFT: 37,
|
||||
MENU: 93, // COMMAND_RIGHT
|
||||
NUMPAD_ADD: 107,
|
||||
NUMPAD_DECIMAL: 110,
|
||||
NUMPAD_DIVIDE: 111,
|
||||
NUMPAD_ENTER: 108,
|
||||
NUMPAD_MULTIPLY: 106,
|
||||
NUMPAD_SUBTRACT: 109,
|
||||
PAGE_DOWN: 34,
|
||||
PAGE_UP: 33,
|
||||
PERIOD: 190,
|
||||
RIGHT: 39,
|
||||
SHIFT: 16,
|
||||
SPACE: 32,
|
||||
TAB: 9,
|
||||
UP: 38,
|
||||
WINDOWS: 91 // COMMAND
|
||||
}
|
||||
});
|
||||
|
||||
// plugins
|
||||
$.fn.extend({
|
||||
_focus: $.fn.focus,
|
||||
focus: function( delay, fn ) {
|
||||
return typeof delay === "number" ?
|
||||
this.each(function() {
|
||||
var elem = this;
|
||||
setTimeout(function() {
|
||||
$( elem ).focus();
|
||||
if ( fn ) {
|
||||
fn.call( elem );
|
||||
}
|
||||
}, delay );
|
||||
}) :
|
||||
this._focus.apply( this, arguments );
|
||||
},
|
||||
|
||||
scrollParent: function() {
|
||||
var scrollParent;
|
||||
if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
|
||||
scrollParent = this.parents().filter(function() {
|
||||
return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
||||
}).eq(0);
|
||||
} else {
|
||||
scrollParent = this.parents().filter(function() {
|
||||
return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
||||
}).eq(0);
|
||||
}
|
||||
|
||||
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
|
||||
},
|
||||
|
||||
zIndex: function( zIndex ) {
|
||||
if ( zIndex !== undefined ) {
|
||||
return this.css( "zIndex", zIndex );
|
||||
}
|
||||
|
||||
if ( this.length ) {
|
||||
var elem = $( this[ 0 ] ), position, value;
|
||||
while ( elem.length && elem[ 0 ] !== document ) {
|
||||
// Ignore z-index if position is set to a value where z-index is ignored by the browser
|
||||
// This makes behavior of this function consistent across browsers
|
||||
// WebKit always returns auto if the element is positioned
|
||||
position = elem.css( "position" );
|
||||
if ( position === "absolute" || position === "relative" || position === "fixed" ) {
|
||||
// IE returns 0 when zIndex is not specified
|
||||
// other browsers return a string
|
||||
// we ignore the case of nested elements with an explicit value of 0
|
||||
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
|
||||
value = parseInt( elem.css( "zIndex" ), 10 );
|
||||
if ( !isNaN( value ) && value !== 0 ) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
elem = elem.parent();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
disableSelection: function() {
|
||||
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
|
||||
".ui-disableSelection", function( event ) {
|
||||
event.preventDefault();
|
||||
});
|
||||
},
|
||||
|
||||
enableSelection: function() {
|
||||
return this.unbind( ".ui-disableSelection" );
|
||||
}
|
||||
});
|
||||
|
||||
$.each( [ "Width", "Height" ], function( i, name ) {
|
||||
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
|
||||
type = name.toLowerCase(),
|
||||
orig = {
|
||||
innerWidth: $.fn.innerWidth,
|
||||
innerHeight: $.fn.innerHeight,
|
||||
outerWidth: $.fn.outerWidth,
|
||||
outerHeight: $.fn.outerHeight
|
||||
};
|
||||
|
||||
function reduce( elem, size, border, margin ) {
|
||||
$.each( side, function() {
|
||||
size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
|
||||
if ( border ) {
|
||||
size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
|
||||
}
|
||||
if ( margin ) {
|
||||
size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
|
||||
}
|
||||
});
|
||||
return size;
|
||||
}
|
||||
|
||||
$.fn[ "inner" + name ] = function( size ) {
|
||||
if ( size === undefined ) {
|
||||
return orig[ "inner" + name ].call( this );
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
$( this ).css( type, reduce( this, size ) + "px" );
|
||||
});
|
||||
};
|
||||
|
||||
$.fn[ "outer" + name] = function( size, margin ) {
|
||||
if ( typeof size !== "number" ) {
|
||||
return orig[ "outer" + name ].call( this, size );
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
$( this).css( type, reduce( this, size, true, margin ) + "px" );
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// selectors
|
||||
function visible( element ) {
|
||||
return !$( element ).parents().andSelf().filter(function() {
|
||||
return $.curCSS( this, "visibility" ) === "hidden" ||
|
||||
$.expr.filters.hidden( this );
|
||||
}).length;
|
||||
}
|
||||
|
||||
$.extend( $.expr[ ":" ], {
|
||||
data: function( elem, i, match ) {
|
||||
return !!$.data( elem, match[ 3 ] );
|
||||
},
|
||||
|
||||
focusable: function( element ) {
|
||||
var nodeName = element.nodeName.toLowerCase(),
|
||||
tabIndex = $.attr( element, "tabindex" );
|
||||
if ( "area" === nodeName ) {
|
||||
var map = element.parentNode,
|
||||
mapName = map.name,
|
||||
img;
|
||||
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
|
||||
return false;
|
||||
}
|
||||
img = $( "img[usemap=#" + mapName + "]" )[0];
|
||||
return !!img && visible( img );
|
||||
}
|
||||
return ( /input|select|textarea|button|object/.test( nodeName )
|
||||
? !element.disabled
|
||||
: "a" == nodeName
|
||||
? element.href || !isNaN( tabIndex )
|
||||
: !isNaN( tabIndex ))
|
||||
// the element and all of its ancestors must be visible
|
||||
&& visible( element );
|
||||
},
|
||||
|
||||
tabbable: function( element ) {
|
||||
var tabIndex = $.attr( element, "tabindex" );
|
||||
return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
|
||||
}
|
||||
});
|
||||
|
||||
// support
|
||||
$(function() {
|
||||
var body = document.body,
|
||||
div = body.appendChild( div = document.createElement( "div" ) );
|
||||
|
||||
$.extend( div.style, {
|
||||
minHeight: "100px",
|
||||
height: "auto",
|
||||
padding: 0,
|
||||
borderWidth: 0
|
||||
});
|
||||
|
||||
$.support.minHeight = div.offsetHeight === 100;
|
||||
$.support.selectstart = "onselectstart" in div;
|
||||
|
||||
// set display to none to avoid a layout bug in IE
|
||||
// http://dev.jquery.com/ticket/4014
|
||||
body.removeChild( div ).style.display = "none";
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// deprecated
|
||||
$.extend( $.ui, {
|
||||
// $.ui.plugin is deprecated. Use the proxy pattern instead.
|
||||
plugin: {
|
||||
add: function( module, option, set ) {
|
||||
var proto = $.ui[ module ].prototype;
|
||||
for ( var i in set ) {
|
||||
proto.plugins[ i ] = proto.plugins[ i ] || [];
|
||||
proto.plugins[ i ].push( [ option, set[ i ] ] );
|
||||
}
|
||||
},
|
||||
call: function( instance, name, args ) {
|
||||
var set = instance.plugins[ name ];
|
||||
if ( !set || !instance.element[ 0 ].parentNode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( var i = 0; i < set.length; i++ ) {
|
||||
if ( instance.options[ set[ i ][ 0 ] ] ) {
|
||||
set[ i ][ 1 ].apply( instance.element, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
|
||||
contains: function( a, b ) {
|
||||
return document.compareDocumentPosition ?
|
||||
a.compareDocumentPosition( b ) & 16 :
|
||||
a !== b && a.contains( b );
|
||||
},
|
||||
|
||||
// only used by resizable
|
||||
hasScroll: function( el, a ) {
|
||||
|
||||
//If overflow is hidden, the element might have extra content, but the user wants to hide it
|
||||
if ( $( el ).css( "overflow" ) === "hidden") {
|
||||
return false;
|
||||
}
|
||||
|
||||
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
||||
has = false;
|
||||
|
||||
if ( el[ scroll ] > 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: determine which cases actually cause this to happen
|
||||
// if the element doesn't have the scroll set, see if it's possible to
|
||||
// set the scroll
|
||||
el[ scroll ] = 1;
|
||||
has = ( el[ scroll ] > 0 );
|
||||
el[ scroll ] = 0;
|
||||
return has;
|
||||
},
|
||||
|
||||
// these are odd functions, fix the API or move into individual plugins
|
||||
isOverAxis: function( x, reference, size ) {
|
||||
//Determines when x coordinate is over "b" element axis
|
||||
return ( x > reference ) && ( x < ( reference + size ) );
|
||||
},
|
||||
isOver: function( y, x, top, left, height, width ) {
|
||||
//Determines when x, y coordinates is over "b" element
|
||||
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
17
www/js/jquery-ui-1.8.11/jquery.ui.core.min.js
vendored
Normal file
17
www/js/jquery-ui-1.8.11/jquery.ui.core.min.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/*!
|
||||
* jQuery UI 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI
|
||||
*/
|
||||
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.11",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
|
||||
NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
|
||||
"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
|
||||
if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
|
||||
"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,
|
||||
d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
|
||||
c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
|
||||
b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
|
252
www/js/jquery-ui-1.8.11/jquery.ui.position.js
vendored
Normal file
252
www/js/jquery-ui-1.8.11/jquery.ui.position.js
vendored
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* jQuery UI Position 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Position
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
$.ui = $.ui || {};
|
||||
|
||||
var horizontalPositions = /left|center|right/,
|
||||
verticalPositions = /top|center|bottom/,
|
||||
center = "center",
|
||||
_position = $.fn.position,
|
||||
_offset = $.fn.offset;
|
||||
|
||||
$.fn.position = function( options ) {
|
||||
if ( !options || !options.of ) {
|
||||
return _position.apply( this, arguments );
|
||||
}
|
||||
|
||||
// make a copy, we don't want to modify arguments
|
||||
options = $.extend( {}, options );
|
||||
|
||||
var target = $( options.of ),
|
||||
targetElem = target[0],
|
||||
collision = ( options.collision || "flip" ).split( " " ),
|
||||
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
|
||||
targetWidth,
|
||||
targetHeight,
|
||||
basePosition;
|
||||
|
||||
if ( targetElem.nodeType === 9 ) {
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
basePosition = { top: 0, left: 0 };
|
||||
// TODO: use $.isWindow() in 1.9
|
||||
} else if ( targetElem.setTimeout ) {
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
|
||||
} else if ( targetElem.preventDefault ) {
|
||||
// force left top to allow flipping
|
||||
options.at = "left top";
|
||||
targetWidth = targetHeight = 0;
|
||||
basePosition = { top: options.of.pageY, left: options.of.pageX };
|
||||
} else {
|
||||
targetWidth = target.outerWidth();
|
||||
targetHeight = target.outerHeight();
|
||||
basePosition = target.offset();
|
||||
}
|
||||
|
||||
// force my and at to have valid horizontal and veritcal positions
|
||||
// if a value is missing or invalid, it will be converted to center
|
||||
$.each( [ "my", "at" ], function() {
|
||||
var pos = ( options[this] || "" ).split( " " );
|
||||
if ( pos.length === 1) {
|
||||
pos = horizontalPositions.test( pos[0] ) ?
|
||||
pos.concat( [center] ) :
|
||||
verticalPositions.test( pos[0] ) ?
|
||||
[ center ].concat( pos ) :
|
||||
[ center, center ];
|
||||
}
|
||||
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
|
||||
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
|
||||
options[ this ] = pos;
|
||||
});
|
||||
|
||||
// normalize collision option
|
||||
if ( collision.length === 1 ) {
|
||||
collision[ 1 ] = collision[ 0 ];
|
||||
}
|
||||
|
||||
// normalize offset option
|
||||
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
|
||||
if ( offset.length === 1 ) {
|
||||
offset[ 1 ] = offset[ 0 ];
|
||||
}
|
||||
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
|
||||
|
||||
if ( options.at[0] === "right" ) {
|
||||
basePosition.left += targetWidth;
|
||||
} else if ( options.at[0] === center ) {
|
||||
basePosition.left += targetWidth / 2;
|
||||
}
|
||||
|
||||
if ( options.at[1] === "bottom" ) {
|
||||
basePosition.top += targetHeight;
|
||||
} else if ( options.at[1] === center ) {
|
||||
basePosition.top += targetHeight / 2;
|
||||
}
|
||||
|
||||
basePosition.left += offset[ 0 ];
|
||||
basePosition.top += offset[ 1 ];
|
||||
|
||||
return this.each(function() {
|
||||
var elem = $( this ),
|
||||
elemWidth = elem.outerWidth(),
|
||||
elemHeight = elem.outerHeight(),
|
||||
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
|
||||
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
|
||||
collisionWidth = elemWidth + marginLeft +
|
||||
( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
|
||||
collisionHeight = elemHeight + marginTop +
|
||||
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
|
||||
position = $.extend( {}, basePosition ),
|
||||
collisionPosition;
|
||||
|
||||
if ( options.my[0] === "right" ) {
|
||||
position.left -= elemWidth;
|
||||
} else if ( options.my[0] === center ) {
|
||||
position.left -= elemWidth / 2;
|
||||
}
|
||||
|
||||
if ( options.my[1] === "bottom" ) {
|
||||
position.top -= elemHeight;
|
||||
} else if ( options.my[1] === center ) {
|
||||
position.top -= elemHeight / 2;
|
||||
}
|
||||
|
||||
// prevent fractions (see #5280)
|
||||
position.left = Math.round( position.left );
|
||||
position.top = Math.round( position.top );
|
||||
|
||||
collisionPosition = {
|
||||
left: position.left - marginLeft,
|
||||
top: position.top - marginTop
|
||||
};
|
||||
|
||||
$.each( [ "left", "top" ], function( i, dir ) {
|
||||
if ( $.ui.position[ collision[i] ] ) {
|
||||
$.ui.position[ collision[i] ][ dir ]( position, {
|
||||
targetWidth: targetWidth,
|
||||
targetHeight: targetHeight,
|
||||
elemWidth: elemWidth,
|
||||
elemHeight: elemHeight,
|
||||
collisionPosition: collisionPosition,
|
||||
collisionWidth: collisionWidth,
|
||||
collisionHeight: collisionHeight,
|
||||
offset: offset,
|
||||
my: options.my,
|
||||
at: options.at
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if ( $.fn.bgiframe ) {
|
||||
elem.bgiframe();
|
||||
}
|
||||
elem.offset( $.extend( position, { using: options.using } ) );
|
||||
});
|
||||
};
|
||||
|
||||
$.ui.position = {
|
||||
fit: {
|
||||
left: function( position, data ) {
|
||||
var win = $( window ),
|
||||
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
|
||||
position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
|
||||
},
|
||||
top: function( position, data ) {
|
||||
var win = $( window ),
|
||||
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
|
||||
position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
|
||||
}
|
||||
},
|
||||
|
||||
flip: {
|
||||
left: function( position, data ) {
|
||||
if ( data.at[0] === center ) {
|
||||
return;
|
||||
}
|
||||
var win = $( window ),
|
||||
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
|
||||
myOffset = data.my[ 0 ] === "left" ?
|
||||
-data.elemWidth :
|
||||
data.my[ 0 ] === "right" ?
|
||||
data.elemWidth :
|
||||
0,
|
||||
atOffset = data.at[ 0 ] === "left" ?
|
||||
data.targetWidth :
|
||||
-data.targetWidth,
|
||||
offset = -2 * data.offset[ 0 ];
|
||||
position.left += data.collisionPosition.left < 0 ?
|
||||
myOffset + atOffset + offset :
|
||||
over > 0 ?
|
||||
myOffset + atOffset + offset :
|
||||
0;
|
||||
},
|
||||
top: function( position, data ) {
|
||||
if ( data.at[1] === center ) {
|
||||
return;
|
||||
}
|
||||
var win = $( window ),
|
||||
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
|
||||
myOffset = data.my[ 1 ] === "top" ?
|
||||
-data.elemHeight :
|
||||
data.my[ 1 ] === "bottom" ?
|
||||
data.elemHeight :
|
||||
0,
|
||||
atOffset = data.at[ 1 ] === "top" ?
|
||||
data.targetHeight :
|
||||
-data.targetHeight,
|
||||
offset = -2 * data.offset[ 1 ];
|
||||
position.top += data.collisionPosition.top < 0 ?
|
||||
myOffset + atOffset + offset :
|
||||
over > 0 ?
|
||||
myOffset + atOffset + offset :
|
||||
0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// offset setter from jQuery 1.4
|
||||
if ( !$.offset.setOffset ) {
|
||||
$.offset.setOffset = function( elem, options ) {
|
||||
// set position first, in-case top/left are set even on static elem
|
||||
if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
|
||||
elem.style.position = "relative";
|
||||
}
|
||||
var curElem = $( elem ),
|
||||
curOffset = curElem.offset(),
|
||||
curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
|
||||
curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
|
||||
props = {
|
||||
top: (options.top - curOffset.top) + curTop,
|
||||
left: (options.left - curOffset.left) + curLeft
|
||||
};
|
||||
|
||||
if ( 'using' in options ) {
|
||||
options.using.call( elem, props );
|
||||
} else {
|
||||
curElem.css( props );
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.offset = function( options ) {
|
||||
var elem = this[ 0 ];
|
||||
if ( !elem || !elem.ownerDocument ) { return null; }
|
||||
if ( options ) {
|
||||
return this.each(function() {
|
||||
$.offset.setOffset( this, options );
|
||||
});
|
||||
}
|
||||
return _offset.call( this );
|
||||
};
|
||||
}
|
||||
|
||||
}( jQuery ));
|
16
www/js/jquery-ui-1.8.11/jquery.ui.position.min.js
vendored
Normal file
16
www/js/jquery-ui-1.8.11/jquery.ui.position.min.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* jQuery UI Position 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Position
|
||||
*/
|
||||
(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
|
||||
left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
|
||||
k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
|
||||
m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
|
||||
d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
|
||||
a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
|
||||
g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
|
262
www/js/jquery-ui-1.8.11/jquery.ui.widget.js
vendored
Normal file
262
www/js/jquery-ui-1.8.11/jquery.ui.widget.js
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
/*!
|
||||
* jQuery UI Widget 1.8.11
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Widget
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
// jQuery 1.4+
|
||||
if ( $.cleanData ) {
|
||||
var _cleanData = $.cleanData;
|
||||
$.cleanData = function( elems ) {
|
||||
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
|
||||
$( elem ).triggerHandler( "remove" );
|
||||
}
|
||||
_cleanData( elems );
|
||||
};
|
||||
} else {
|
||||
var _remove = $.fn.remove;
|
||||
$.fn.remove = function( selector, keepData ) {
|
||||
return this.each(function() {
|
||||
if ( !keepData ) {
|
||||
if ( !selector || $.filter( selector, [ this ] ).length ) {
|
||||
$( "*", this ).add( [ this ] ).each(function() {
|
||||
$( this ).triggerHandler( "remove" );
|
||||
});
|
||||
}
|
||||
}
|
||||
return _remove.call( $(this), selector, keepData );
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$.widget = function( name, base, prototype ) {
|
||||
var namespace = name.split( "." )[ 0 ],
|
||||
fullName;
|
||||
name = name.split( "." )[ 1 ];
|
||||
fullName = namespace + "-" + name;
|
||||
|
||||
if ( !prototype ) {
|
||||
prototype = base;
|
||||
base = $.Widget;
|
||||
}
|
||||
|
||||
// create selector for plugin
|
||||
$.expr[ ":" ][ fullName ] = function( elem ) {
|
||||
return !!$.data( elem, name );
|
||||
};
|
||||
|
||||
$[ namespace ] = $[ namespace ] || {};
|
||||
$[ namespace ][ name ] = function( options, element ) {
|
||||
// allow instantiation without initializing for simple inheritance
|
||||
if ( arguments.length ) {
|
||||
this._createWidget( options, element );
|
||||
}
|
||||
};
|
||||
|
||||
var basePrototype = new base();
|
||||
// we need to make the options hash a property directly on the new instance
|
||||
// otherwise we'll modify the options hash on the prototype that we're
|
||||
// inheriting from
|
||||
// $.each( basePrototype, function( key, val ) {
|
||||
// if ( $.isPlainObject(val) ) {
|
||||
// basePrototype[ key ] = $.extend( {}, val );
|
||||
// }
|
||||
// });
|
||||
basePrototype.options = $.extend( true, {}, basePrototype.options );
|
||||
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
|
||||
namespace: namespace,
|
||||
widgetName: name,
|
||||
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
|
||||
widgetBaseClass: fullName
|
||||
}, prototype );
|
||||
|
||||
$.widget.bridge( name, $[ namespace ][ name ] );
|
||||
};
|
||||
|
||||
$.widget.bridge = function( name, object ) {
|
||||
$.fn[ name ] = function( options ) {
|
||||
var isMethodCall = typeof options === "string",
|
||||
args = Array.prototype.slice.call( arguments, 1 ),
|
||||
returnValue = this;
|
||||
|
||||
// allow multiple hashes to be passed on init
|
||||
options = !isMethodCall && args.length ?
|
||||
$.extend.apply( null, [ true, options ].concat(args) ) :
|
||||
options;
|
||||
|
||||
// prevent calls to internal methods
|
||||
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
if ( isMethodCall ) {
|
||||
this.each(function() {
|
||||
var instance = $.data( this, name ),
|
||||
methodValue = instance && $.isFunction( instance[options] ) ?
|
||||
instance[ options ].apply( instance, args ) :
|
||||
instance;
|
||||
// TODO: add this back in 1.9 and use $.error() (see #5972)
|
||||
// if ( !instance ) {
|
||||
// throw "cannot call methods on " + name + " prior to initialization; " +
|
||||
// "attempted to call method '" + options + "'";
|
||||
// }
|
||||
// if ( !$.isFunction( instance[options] ) ) {
|
||||
// throw "no such method '" + options + "' for " + name + " widget instance";
|
||||
// }
|
||||
// var methodValue = instance[ options ].apply( instance, args );
|
||||
if ( methodValue !== instance && methodValue !== undefined ) {
|
||||
returnValue = methodValue;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.each(function() {
|
||||
var instance = $.data( this, name );
|
||||
if ( instance ) {
|
||||
instance.option( options || {} )._init();
|
||||
} else {
|
||||
$.data( this, name, new object( options, this ) );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
};
|
||||
|
||||
$.Widget = function( options, element ) {
|
||||
// allow instantiation without initializing for simple inheritance
|
||||
if ( arguments.length ) {
|
||||
this._createWidget( options, element );
|
||||
}
|
||||
};
|
||||
|
||||
$.Widget.prototype = {
|
||||
widgetName: "widget",
|
||||
widgetEventPrefix: "",
|
||||
options: {
|
||||
disabled: false
|
||||
},
|
||||
_createWidget: function( options, element ) {
|
||||
// $.widget.bridge stores the plugin instance, but we do it anyway
|
||||
// so that it's stored even before the _create function runs
|
||||
$.data( element, this.widgetName, this );
|
||||
this.element = $( element );
|
||||
this.options = $.extend( true, {},
|
||||
this.options,
|
||||
this._getCreateOptions(),
|
||||
options );
|
||||
|
||||
var self = this;
|
||||
this.element.bind( "remove." + this.widgetName, function() {
|
||||
self.destroy();
|
||||
});
|
||||
|
||||
this._create();
|
||||
this._trigger( "create" );
|
||||
this._init();
|
||||
},
|
||||
_getCreateOptions: function() {
|
||||
return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
|
||||
},
|
||||
_create: function() {},
|
||||
_init: function() {},
|
||||
|
||||
destroy: function() {
|
||||
this.element
|
||||
.unbind( "." + this.widgetName )
|
||||
.removeData( this.widgetName );
|
||||
this.widget()
|
||||
.unbind( "." + this.widgetName )
|
||||
.removeAttr( "aria-disabled" )
|
||||
.removeClass(
|
||||
this.widgetBaseClass + "-disabled " +
|
||||
"ui-state-disabled" );
|
||||
},
|
||||
|
||||
widget: function() {
|
||||
return this.element;
|
||||
},
|
||||
|
||||
option: function( key, value ) {
|
||||
var options = key;
|
||||
|
||||
if ( arguments.length === 0 ) {
|
||||
// don't return a reference to the internal hash
|
||||
return $.extend( {}, this.options );
|
||||
}
|
||||
|
||||
if (typeof key === "string" ) {
|
||||
if ( value === undefined ) {
|
||||
return this.options[ key ];
|
||||
}
|
||||
options = {};
|
||||
options[ key ] = value;
|
||||
}
|
||||
|
||||
this._setOptions( options );
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOptions: function( options ) {
|
||||
var self = this;
|
||||
$.each( options, function( key, value ) {
|
||||
self._setOption( key, value );
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOption: function( key, value ) {
|
||||
this.options[ key ] = value;
|
||||
|
||||
if ( key === "disabled" ) {
|
||||
this.widget()
|
||||
[ value ? "addClass" : "removeClass"](
|
||||
this.widgetBaseClass + "-disabled" + " " +
|
||||
"ui-state-disabled" )
|
||||
.attr( "aria-disabled", value );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
return this._setOption( "disabled", false );
|
||||
},
|
||||
disable: function() {
|
||||
return this._setOption( "disabled", true );
|
||||
},
|
||||
|
||||
_trigger: function( type, event, data ) {
|
||||
var callback = this.options[ type ];
|
||||
|
||||
event = $.Event( event );
|
||||
event.type = ( type === this.widgetEventPrefix ?
|
||||
type :
|
||||
this.widgetEventPrefix + type ).toLowerCase();
|
||||
data = data || {};
|
||||
|
||||
// copy original event properties over to the new event
|
||||
// this would happen if we could call $.event.fix instead of $.Event
|
||||
// but we don't have a way to force an event to be fixed multiple times
|
||||
if ( event.originalEvent ) {
|
||||
for ( var i = $.event.props.length, prop; i; ) {
|
||||
prop = $.event.props[ --i ];
|
||||
event[ prop ] = event.originalEvent[ prop ];
|
||||
}
|
||||
}
|
||||
|
||||
this.element.trigger( event, data );
|
||||
|
||||
return !( $.isFunction(callback) &&
|
||||
callback.call( this.element[0], event, data ) === false ||
|
||||
event.isDefaultPrevented() );
|
||||
}
|
||||
};
|
||||
|
||||
})( jQuery );
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user