diff --git a/AUTHORS.md b/AUTHORS.md
index 37f9464..46ead1b 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -8,3 +8,5 @@
* Chris https://github.com/ch0wnag3 (favicon URL improvement)
* Gabriel Wanzek https://github.com/GabrielWanzek (gabdark & gabdark3 themes)
* Luc https://github.com/ltribolet (Bootstrap theme)
+* Stephan Bergemann https://github.com/oberling (German translation, Bootstrap multilang support + making bootstrap theme HTML5 valid)
+* linuxman https://github.com/linuxman (Spanish translation)
diff --git a/CC0 b/CC0
new file mode 100644
index 0000000..bdfff7a
--- /dev/null
+++ b/CC0
@@ -0,0 +1,118 @@
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT
+ PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT
+ CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES
+ THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO
+ WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION
+ OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES
+ RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR
+ WORKS PROVIDED HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically
+confer exclusive Copyright and Related Rights (defined below) upon the
+creator and subsequent owner(s) (each and all, an "owner") of an
+original work of authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work
+for the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without
+fear of later claims of infringement build upon, modify, incorporate
+in other works, reuse and redistribute as freely as possible in any
+form whatsoever and for any purposes, including without limitation
+commercial purposes. These owners may contribute to the Commons to
+promote the ideal of a free culture and the further production of
+creative, cultural and scientific works, or to gain reputation or
+greater distribution for their Work in part through the use and
+efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or
+she is an owner of Copyright and Related Rights in the Work,
+voluntarily elects to apply CC0 to the Work and publicly distribute
+the Work under its terms, with knowledge of his or her Copyright and
+Related Rights in the Work and the meaning and intended legal effect
+of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may
+be protected by copyright and related or neighboring rights
+("Copyright and Related Rights"). Copyright and Related Rights
+include, but are not limited to, the following:
+
+ the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work; moral rights retained by the
+ original author(s) and/or performer(s); publicity and privacy
+ rights pertaining to a person's image or likeness depicted in a
+ Work; rights protecting against unfair competition in regards to a
+ Work, subject to the limitations in paragraph 4(a), below; rights
+ protecting the extraction, dissemination, use and reuse of data in
+ a Work; database rights (such as those arising under Directive
+ 96/9/EC of the European Parliament and of the Council of 11 March
+ 1996 on the legal protection of databases, and under any national
+ implementation thereof, including any amended or successor version
+ of such directive); and other similar, equivalent or corresponding
+ rights throughout the world based on applicable law or treaty, and
+ any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in
+contravention of, applicable law, Affirmer hereby overtly, fully,
+permanently, irrevocably and unconditionally waives, abandons, and
+surrenders all of Affirmer's Copyright and Related Rights and
+associated claims and causes of action, whether now known or unknown
+(including existing as well as future claims and causes of action), in
+the Work (i) in all territories worldwide, (ii) for the maximum
+duration provided by applicable law or treaty (including future time
+extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"Waiver"). Affirmer makes the Waiver for the benefit of each member of
+the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal
+or equitable action to disrupt the quiet enjoyment of the Work by the
+public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any
+reason be judged legally invalid or ineffective under applicable law,
+then the Waiver shall be preserved to the maximum extent permitted
+taking into account Affirmer's express Statement of Purpose. In
+addition, to the extent the Waiver is so judged Affirmer hereby grants
+to each affected person a royalty-free, non transferable, non
+sublicensable, non exclusive, irrevocable and unconditional license to
+exercise Affirmer's Copyright and Related Rights in the Work (i) in
+all territories worldwide, (ii) for the maximum duration provided by
+applicable law or treaty (including future time extensions), (iii) in
+any current or future medium and for any number of copies, and (iv)
+for any purpose whatsoever, including without limitation commercial,
+advertising or promotional purposes (the "License"). The License shall
+be deemed effective as of the date CC0 was applied by Affirmer to the
+Work. Should any part of the License for any reason be judged legally
+invalid or ineffective under applicable law, such partial invalidity
+or ineffectiveness shall not invalidate the remainder of the License,
+and in such case Affirmer hereby affirms that he or she will not (i)
+exercise any of his or her remaining Copyright and Related Rights in
+the Work or (ii) assert any associated claims and causes of action
+with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ No trademark or patent rights held by Affirmer are waived,
+ abandoned, surrendered, licensed or otherwise affected by this
+ document. Affirmer offers the Work as-is and makes no
+ representations or warranties of any kind concerning the Work,
+ express, implied, statutory or otherwise, including without
+ limitation warranties of title, merchantability, fitness for a
+ particular purpose, non infringement, or the absence of latent or
+ other defects, accuracy, or the present or absence of errors,
+ whether or not discoverable, all to the greatest extent
+ permissible under applicable law. Affirmer disclaims
+ responsibility for clearing rights of other persons that may apply
+ to the Work or any use thereof, including without limitation any
+ person's Copyright and Related Rights in the Work. Further,
+ Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work. Affirmer understands and acknowledges that Creative Commons
+ is not a party to this document and has no duty or obligation with
+ respect to this CC0 or use of the Work.
diff --git a/README.md b/README.md
index 49ab739..0fa0aec 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,34 @@
Stikked is an Open-Source PHP Pastebin, with the aim of keeping a simple and easy to use user interface.
-Stikked allows you to easily share code with anyone you wish. Stikked was created for the following reasons:
+Stikked allows you to easily share code with anyone you wish. Based on the [original Stikked](http://code.google.com/p/stikked/) with lots of bugfixes and improvements.
-* IRC and Private Chats were spammed.
-* Pastebins were ugly.
-* Pastebins were confusing.
-* Pastebins were messy and not thought through.
-* Stikked rethought code collaboration, by making it easy to paste code.
+Here are some features:
-Based on the original Stikked (http://code.google.com/p/stikked/) with lots of bugfixes and improvements.
-
-Thanks to Rebecca Chapnik for this great review: http://maketecheasier.com/run-your-own-pastebin-with-stikked/2013/01/11
+* Easy setup
+* Syntaxhighlighting for many languages, including live syntaxhighlighting with CodeMirror
+* Paste replies
+* Diff view between the original paste and the reply
+* An API
+* Trending pastes
+* Anti-Spam features
+* Themes support
+* Multilanguage support
+* And many more. View [this review](http://maketecheasier.com/run-your-own-pastebin-with-stikked/2013/01/11)
Try it out
----------
+
http://paste.scratchbook.ch/
Installation
------------
-1. Download stikked from https://github.com/claudehohl/Stikked/tags
-2. Create a user and database for Stikked
-3. Edit configuration settings in application/config/stikked.php - everything is described there
-4. You're done!
+1. Download stikked from https://github.com/claudehohl/Stikked/tags
+2. Create a user and database for Stikked
+3. Edit configuration settings in application/config/stikked.php - everything is described there
+4. You're done!
* The database structure will be created automatically if it doesn't exist.
* No special file permissions are needed by default. Optional: If you want to have the JavaScript- and CSS-files minified, the static/asset/ folder has to be writable.
@@ -32,22 +36,64 @@ Installation
* */5 * * * * curl --silent http://yoursite.com/cron/[key]
+Documentation
+-------------
+
+In the folder doc/, you will find:
+
+* Webserver example configurations for Apache, Nginx, Lighttpd, Cherokee
+* A troubleshooting guide
+* How to create your own theme
+* How to translate Stikked into your language
+* How to contribute and improve Stikked
+
+
Changelog
---------
### Version 0.8.5:
* Themes! Configure a different theme in config/stikked.php - or create your own
+* Multilanguage support. Configure a different language in config/stikked.php
+* Diff view for paste replies! View differences between the original paste and its reply
+ * see it in action: http://paste.scratchbook.ch/view/de81a093/diff
+* Possibility to set default expiration time
+* Updated GeSHi to version 1.0.8.11
+* Updated CodeMirror to version 3.11
+* Lots of minor fixes and improvements
+* Added guides for troubleshooting, development, translation and creating themes
+* Added webserver example configurations
+* Added reCaptcha integration for better antispam
#### Upgrade instructions
-The following line must be present config/stikked.php
+The following lines must be present config/stikked.php
```php
$config['theme'] = 'default';
```
-You can choose between default, bootstrap, gabdark and gabdark3.
+You can choose between default, bootstrap, gabdark, gabdark3 and a fancy geocities theme ;)
+
+Create you own theme. See doc/CREATING_THEMES.md
+
+```php
+$config['language'] = 'english';
+```
+
+You can choose between english, german and swissgerman ;)
+
+Help translating Stikked into your language! See doc/TRANSLATING_STIKKED.md
+
+##### reCaptcha
+
+```php
+$config['recaptcha_publickey'] = '';
+$config['recaptcha_privatekey'] = '';
+```
+
+If these lines are filled, reCaptcha will be used.
+Get a key from https://www.google.com/recaptcha/admin/create
### Version 0.8.4:
@@ -123,4 +169,3 @@ You can choose between default, bootstrap, gabdark and gabdark3.
* Fully standards compliant css and xhtml.
* Random generating names for anonymous users
* Paste downloading
-
diff --git a/CREATING_THEMES.md b/doc/CREATING_THEMES.md
similarity index 100%
rename from CREATING_THEMES.md
rename to doc/CREATING_THEMES.md
diff --git a/doc/DEVELOPMENT.md b/doc/DEVELOPMENT.md
new file mode 100644
index 0000000..91c5333
--- /dev/null
+++ b/doc/DEVELOPMENT.md
@@ -0,0 +1,9 @@
+You want to improve Stikked? Always welcome! Send us your pull request and you will be honoured in AUTHORS.md.
+
+Some guidelines:
+
+* For PHP only files (not views/themes), please run the PHP Beautifier (http://pear.php.net/package/PHP_Beautifier) with the following parameters:
+```
+php_beautifier --indent_tabs -l "IndentStyles(style=bsd) ArrayNested() NewLines(before=function:T_CLASS:if,after=T_COMMENT) ListClassFunction()"
+```
+* Other people may modify your contribution. Don't take that personal; we all want to improve Stikked. Your input is always welcome!
diff --git a/doc/TRANSLATING_STIKKED.md b/doc/TRANSLATING_STIKKED.md
new file mode 100644
index 0000000..43474fc
--- /dev/null
+++ b/doc/TRANSLATING_STIKKED.md
@@ -0,0 +1,7 @@
+How to translate Stikked into your own language
+-----------------------------------------------
+
+1. Make a copy of the folder htdocs/application/language/swissgerman, and name it as you like.
+2. Start placing in your texts!
+
+The date_lang.php and form_validation_lang.php are optional; they lay in the system folder for english fallback. stikked_lang.php is required. If you miss a translation, it will be shown as [tanslation_index] in Stikked.
diff --git a/doc/TROUBLESHOOTING_GUIDE.md b/doc/TROUBLESHOOTING_GUIDE.md
new file mode 100644
index 0000000..37be3ea
--- /dev/null
+++ b/doc/TROUBLESHOOTING_GUIDE.md
@@ -0,0 +1,43 @@
+Stikked troubleshooting guide
+-----------------------------
+
+### Apache
+
+#### 404 Not Found after creating a Paste
+
+Rewrite rules must be enabled in httpd.conf.
+
+### Nginx
+
+#### 502 Bad Gateway
+
+PHP FastCGI must be running. Here's my /etc/init.d/php-fcgi config:
+
+```bash
+#!/bin/bash
+
+FASTCGI_USER=www-data
+FASTCGI_GROUP=www-data
+ADDRESS=127.0.0.1
+PORT=9000
+PIDFILE=/var/run/php-fastcgi.pid
+CHILDREN=6
+PHP5=/usr/bin/php5-cgi
+
+/usr/bin/spawn-fcgi -a $ADDRESS -p $PORT -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5
+```
+
+You can adapt that to your system.
+
+### Lighttpd
+
+#### 503 - Service Not Available
+
+PHP FastCGI must be running. See the php-fcgi section under Nginx.
+
+### Cherokee
+
+Still have a problem?
+---------------------
+
+Report an issue at GitHub, and we will add your problem to this guide.
diff --git a/doc/webserver_sampleconfigs/apache-site.conf b/doc/webserver_sampleconfigs/apache-site.conf
new file mode 100644
index 0000000..2da6137
--- /dev/null
+++ b/doc/webserver_sampleconfigs/apache-site.conf
@@ -0,0 +1,12 @@
+
+ ServerName stikked
+ DocumentRoot /var/www/stikked/htdocs
+ ErrorLog ${APACHE_LOG_DIR}/stikked-error_log
+ CustomLog ${APACHE_LOG_DIR}/stikked-access_log common
+
+ Options +FollowSymLinks
+ AllowOverride All
+ Order allow,deny
+ Allow from all
+
+
diff --git a/doc/webserver_sampleconfigs/cherokee.conf b/doc/webserver_sampleconfigs/cherokee.conf
new file mode 100644
index 0000000..3244aa4
--- /dev/null
+++ b/doc/webserver_sampleconfigs/cherokee.conf
@@ -0,0 +1,325 @@
+config!version = 001002101
+server!bind!1!port = 80
+server!keepalive = 1
+server!keepalive_max_requests = 500
+server!panic_action = /opt/cherokee/bin/cherokee-panic
+server!pid_file = /opt/cherokee/var/run/cherokee.pid
+server!server_tokens = full
+server!timeout = 15
+vserver!1!directory_index = index.html
+vserver!1!document_root = /opt/cherokee/var/www
+vserver!1!error_writer!filename = /opt/cherokee/var/log/cherokee.error
+vserver!1!error_writer!type = file
+vserver!1!logger = combined
+vserver!1!logger!access!buffsize = 16384
+vserver!1!logger!access!filename = /opt/cherokee/var/log/cherokee.access
+vserver!1!logger!access!type = file
+vserver!1!nick = default
+vserver!1!rule!5!encoder!gzip = allow
+vserver!1!rule!5!handler = server_info
+vserver!1!rule!5!handler!type = just_about
+vserver!1!rule!5!match = directory
+vserver!1!rule!5!match!directory = /about
+vserver!1!rule!4!document_root = /opt/cherokee/lib/cgi-bin
+vserver!1!rule!4!handler = cgi
+vserver!1!rule!4!match = directory
+vserver!1!rule!4!match!directory = /cgi-bin
+vserver!1!rule!3!document_root = /opt/cherokee/share/cherokee/themes
+vserver!1!rule!3!handler = file
+vserver!1!rule!3!match = directory
+vserver!1!rule!3!match!directory = /cherokee_themes
+vserver!1!rule!2!document_root = /opt/cherokee/share/cherokee/icons
+vserver!1!rule!2!handler = file
+vserver!1!rule!2!match = directory
+vserver!1!rule!2!match!directory = /icons
+vserver!1!rule!1!handler = common
+vserver!1!rule!1!handler!iocache = 1
+vserver!1!rule!1!match = default
+vserver!2!directory_index = index.php,index.html
+vserver!2!document_root = /opt/cherokee/var/www/stikked
+vserver!2!error_writer!filename = /opt/cherokee/var/log/cherokee.error
+vserver!2!error_writer!type = file
+vserver!2!logger = combined
+vserver!2!logger!access!buffsize = 16384
+vserver!2!logger!access!filename = /opt/cherokee/var/log/cherokee.access
+vserver!2!logger!access!type = file
+vserver!2!nick = stikked
+vserver!2!rule!110!document_root = /opt/cherokee/var/www/stikked/static
+vserver!2!rule!110!handler = file
+vserver!2!rule!110!handler!iocache = 0
+vserver!2!rule!110!match = directory
+vserver!2!rule!110!match!directory = /static
+vserver!2!rule!110!match!final = 1
+vserver!2!rule!10!handler = fcgi
+vserver!2!rule!10!handler!balancer = round_robin
+vserver!2!rule!10!handler!balancer!source!10 = 1
+vserver!2!rule!10!handler!check_file = 1
+vserver!2!rule!10!handler!error_handler = 1
+vserver!2!rule!10!handler!pass_req_headers = 1
+vserver!2!rule!10!handler!script_alias = /opt/cherokee/var/www/stikked/index.php
+vserver!2!rule!10!handler!x_real_ip_enabled = 0
+vserver!2!rule!10!handler!xsendfile = 0
+vserver!2!rule!10!match = default
+source!1!env!PHP_FCGI_CHILDREN = 5
+source!1!env!PHP_FCGI_MAX_REQUESTS = 490
+source!1!env_inherited = 0
+source!1!host = 127.0.0.1:47990
+source!1!interpreter = /usr/bin/php-cgi -b 127.0.0.1:47990
+source!1!nick = PHP Interpreter
+source!1!type = interpreter
+icons!default = page_white.png
+icons!directory = folder.png
+icons!file!bomb.png = core
+icons!file!page_white_go.png = *README*
+icons!parent_directory = arrow_turn_left.png
+icons!suffix!camera.png = jpg,jpeg,jpe
+icons!suffix!cd.png = iso,ngr,cue
+icons!suffix!color_wheel.png = png,gif,xcf,bmp,pcx,tiff,tif,cdr,psd,xpm,xbm
+icons!suffix!control_play.png = bin,exe,com,msi,out
+icons!suffix!css.png = css
+icons!suffix!cup.png = java,class,jar
+icons!suffix!email.png = eml,mbox,box,email,mbx
+icons!suffix!film.png = avi,mpeg,mpe,mpg,mpeg3,dl,fli,qt,mov,movie,flv,webm
+icons!suffix!font.png = ttf
+icons!suffix!html.png = html,htm
+icons!suffix!music.png = au,snd,mid,midi,kar,mpga,mpega,mp2,mp3,sid,wav,aif,aiff,aifc,gsm,m3u,wma,wax,ra,rm,ram,pls,sd2,ogg
+icons!suffix!package.png = tar,gz,bz2,zip,rar,ace,lha,7z,dmg,cpk
+icons!suffix!page_white_acrobat.png = pdf
+icons!suffix!page_white_c.png = c,h,cpp
+icons!suffix!page_white_office.png = doc,ppt,xls
+icons!suffix!page_white_php.png = php
+icons!suffix!page_white_text.png = txt,text,rtf,sdw
+icons!suffix!printer.png = ps,eps
+icons!suffix!ruby.png = rb
+icons!suffix!script.png = sh,csh,ksh,tcl,tk,py,pl
+mime!application/bzip2!extensions = bz2
+mime!application/gzip!extensions = gz
+mime!application/hta!extensions = hta
+mime!application/java-archive!extensions = jar
+mime!application/java-serialized-object!extensions = ser
+mime!application/java-vm!extensions = class
+mime!application/json!extensions = json
+mime!application/mac-binhex40!extensions = hqx
+mime!application/msaccess!extensions = mdb
+mime!application/msword!extensions = doc,dot
+mime!application/octet-stream!extensions = bin
+mime!application/octetstream!extensions = ace
+mime!application/oda!extensions = oda
+mime!application/ogg!extensions = ogx
+mime!application/pdf!extensions = pdf
+mime!application/pgp-keys!extensions = key
+mime!application/pgp-signature!extensions = pgp
+mime!application/pics-rules!extensions = prf
+mime!application/postscript!extensions = ps,ai,eps
+mime!application/rar!extensions = rar
+mime!application/rdf+xml!extensions = rdf
+mime!application/rss+xml!extensions = rss
+mime!application/smil!extensions = smi,smil
+mime!application/vnd.mozilla.xul+xml!extensions = xul
+mime!application/vnd.ms-excel!extensions = xls,xlb,xlt
+mime!application/vnd.ms-pki.seccat!extensions = cat
+mime!application/vnd.ms-pki.stl!extensions = stl
+mime!application/vnd.ms-powerpoint!extensions = ppt,pps
+mime!application/vnd.oasis.opendocument.chart!extensions = odc
+mime!application/vnd.oasis.opendocument.database!extensions = odb
+mime!application/vnd.oasis.opendocument.formula!extensions = odf
+mime!application/vnd.oasis.opendocument.graphics!extensions = odg
+mime!application/vnd.oasis.opendocument.image!extensions = odi
+mime!application/vnd.oasis.opendocument.presentation!extensions = odp
+mime!application/vnd.oasis.opendocument.spreadsheet!extensions = ods
+mime!application/vnd.oasis.opendocument.text!extensions = odt
+mime!application/vnd.oasis.opendocument.text-master!extensions = odm
+mime!application/vnd.oasis.opendocument.text-web!extensions = oth
+mime!application/vnd.pkg5.info!extensions = p5i
+mime!application/vnd.visio!extensions = vsd
+mime!application/vnd.wap.wbxml!extensions = wbxml
+mime!application/vnd.wap.wmlc!extensions = wmlc
+mime!application/vnd.wap.wmlscriptc!extensions = wmlsc
+mime!application/x-7z-compressed!extensions = 7z
+mime!application/x-abiword!extensions = abw
+mime!application/x-apple-diskimage!extensions = dmg
+mime!application/x-bcpio!extensions = bcpio
+mime!application/x-bittorrent!extensions = torrent
+mime!application/x-cdf!extensions = cdf
+mime!application/x-cpio!extensions = cpio
+mime!application/x-csh!extensions = csh
+mime!application/x-debian-package!extensions = deb,udeb
+mime!application/x-director!extensions = dcr,dir,dxr
+mime!application/x-dvi!extensions = dvi
+mime!application/x-flac!extensions = flac
+mime!application/x-font!extensions = pfa,pfb,gsf,pcf,pcf.Z
+mime!application/x-freemind!extensions = mm
+mime!application/x-gnumeric!extensions = gnumeric
+mime!application/x-gtar!extensions = gtar,tgz,taz
+mime!application/x-gzip!extensions = gz,tgz
+mime!application/x-httpd-php!extensions = phtml,pht,php
+mime!application/x-httpd-php-source!extensions = phps
+mime!application/x-httpd-php3!extensions = php3
+mime!application/x-httpd-php3-preprocessed!extensions = php3p
+mime!application/x-httpd-php4!extensions = php4
+mime!application/x-internet-signup!extensions = ins,isp
+mime!application/x-iphone!extensions = iii
+mime!application/x-iso9660-image!extensions = iso
+mime!application/x-java-jnlp-file!extensions = jnlp
+mime!application/x-javascript!extensions = js
+mime!application/x-kchart!extensions = chrt
+mime!application/x-killustrator!extensions = kil
+mime!application/x-koan!extensions = skp,skd,skt,skm
+mime!application/x-kpresenter!extensions = kpr,kpt
+mime!application/x-kspread!extensions = ksp
+mime!application/x-kword!extensions = kwd,kwt
+mime!application/x-latex!extensions = latex
+mime!application/x-lha!extensions = lha
+mime!application/x-lzh!extensions = lzh
+mime!application/x-lzx!extensions = lzx
+mime!application/x-ms-wmd!extensions = wmd
+mime!application/x-ms-wmz!extensions = wmz
+mime!application/x-msdos-program!extensions = com,exe,bat,dll
+mime!application/x-msi!extensions = msi
+mime!application/x-netcdf!extensions = nc
+mime!application/x-ns-proxy-autoconfig!extensions = pac
+mime!application/x-nwc!extensions = nwc
+mime!application/x-object!extensions = o
+mime!application/x-oz-application!extensions = oza
+mime!application/x-pkcs7-certreqresp!extensions = p7r
+mime!application/x-pkcs7-crl!extensions = crl
+mime!application/x-python-code!extensions = pyc,pyo
+mime!application/x-quicktimeplayer!extensions = qtl
+mime!application/x-redhat-package-manager!extensions = rpm
+mime!application/x-sh!extensions = sh
+mime!application/x-shar!extensions = shar
+mime!application/x-shockwave-flash!extensions = swf,swfl
+mime!application/x-stuffit!extensions = sit,sea
+mime!application/x-sv4cpio!extensions = sv4cpio
+mime!application/x-sv4crc!extensions = sv4crc
+mime!application/x-tar!extensions = tar
+mime!application/x-tcl!extensions = tcl
+mime!application/x-tex-pk!extensions = pk
+mime!application/x-texinfo!extensions = texinfo,texi
+mime!application/x-trash!extensions = ~,bak,old,sik
+mime!application/x-troff!extensions = t,tr,roff
+mime!application/x-troff-man!extensions = man
+mime!application/x-troff-me!extensions = me
+mime!application/x-troff-ms!extensions = ms
+mime!application/x-ustar!extensions = ustar
+mime!application/x-x509-ca-cert!extensions = crt
+mime!application/x-xcf!extensions = xcf
+mime!application/x-xfig!extensions = fig
+mime!application/x-xpinstall!extensions = xpi
+mime!application/xhtml+xml!extensions = xhtml,xht
+mime!application/xml!extensions = xml,xsl
+mime!application/zip!extensions = zip
+mime!audio/basic!extensions = au,snd
+mime!audio/midi!extensions = mid,midi,kar
+mime!audio/mpeg!extensions = mpga,mpega,mp2,mp3,m4a
+mime!audio/ogg!extensions = ogg,oga
+mime!audio/prs.sid!extensions = sid
+mime!audio/x-aiff!extensions = aif,aiff,aifc
+mime!audio/x-gsm!extensions = gsm
+mime!audio/x-mpegurl!extensions = m3u
+mime!audio/x-ms-wax!extensions = wax
+mime!audio/x-ms-wma!extensions = wma
+mime!audio/x-pn-realaudio!extensions = ra,rm,ram
+mime!audio/x-realaudio!extensions = ra
+mime!audio/x-scpls!extensions = pls
+mime!audio/x-sd2!extensions = sd2
+mime!audio/x-wav!extensions = wav
+mime!chemical/x-cache!extensions = cac,cache
+mime!chemical/x-cache-csf!extensions = csf
+mime!chemical/x-cdx!extensions = cdx
+mime!chemical/x-cif!extensions = cif
+mime!chemical/x-cmdf!extensions = cmdf
+mime!chemical/x-cml!extensions = cml
+mime!chemical/x-compass!extensions = cpa
+mime!chemical/x-crossfire!extensions = bsd
+mime!chemical/x-csml!extensions = csml,csm
+mime!chemical/x-ctx!extensions = ctx
+mime!chemical/x-cxf!extensions = cxf,cef
+mime!chemical/x-isostar!extensions = istr,ist
+mime!chemical/x-jcamp-dx!extensions = jdx,dx
+mime!chemical/x-kinemage!extensions = kin
+mime!chemical/x-pdb!extensions = pdb,ent
+mime!chemical/x-swissprot!extensions = sw
+mime!chemical/x-vamas-iso14976!extensions = vms
+mime!chemical/x-vmd!extensions = vmd
+mime!chemical/x-xtel!extensions = xtel
+mime!chemical/x-xyz!extensions = xyz
+mime!image/gif!extensions = gif
+mime!image/jpeg!extensions = jpeg,jpg,jpe
+mime!image/pcx!extensions = pcx
+mime!image/png!extensions = png
+mime!image/svg+xml!extensions = svg,svgz
+mime!image/tiff!extensions = tiff,tif
+mime!image/vnd.djvu!extensions = djvu,djv
+mime!image/vnd.wap.wbmp!extensions = wbmp
+mime!image/x-icon!extensions = ico
+mime!image/x-ms-bmp!extensions = bmp
+mime!image/x-photoshop!extensions = psd
+mime!image/x-portable-anymap!extensions = pnm
+mime!image/x-portable-bitmap!extensions = pbm
+mime!image/x-portable-graymap!extensions = pgm
+mime!image/x-portable-pixmap!extensions = ppm
+mime!image/x-xbitmap!extensions = xbm
+mime!image/x-xpixmap!extensions = xpm
+mime!image/x-xwindowdump!extensions = xwd
+mime!model/iges!extensions = igs,iges
+mime!model/mesh!extensions = msh,mesh,silo
+mime!model/vrml!extensions = wrl,vrml
+mime!text/calendar!extensions = ics,icz
+mime!text/comma-separated-values!extensions = csv
+mime!text/css!extensions = css
+mime!text/h323!extensions = 323
+mime!text/html!extensions = html,htm,shtml
+mime!text/iuls!extensions = uls
+mime!text/mathml!extensions = mml
+mime!text/plain!extensions = asc,txt,text,diff,pot
+mime!text/richtext!extensions = rtx
+mime!text/rtf!extensions = rtf
+mime!text/scriptlet!extensions = sct,wsc
+mime!text/tab-separated-values!extensions = tsv
+mime!text/vnd.sun.j2me.app-descriptor!extensions = jad
+mime!text/vnd.wap.wml!extensions = wml
+mime!text/vnd.wap.wmlscript!extensions = wmls
+mime!text/x-boo!extensions = boo
+mime!text/x-c++hdr!extensions = h++,hpp,hxx,hh
+mime!text/x-c++src!extensions = c++,cpp,cxx,cc
+mime!text/x-chdr!extensions = h
+mime!text/x-csh!extensions = csh
+mime!text/x-csrc!extensions = c
+mime!text/x-dsrc!extensions = d
+mime!text/x-haskell!extensions = hs
+mime!text/x-java!extensions = java
+mime!text/x-literate-haskell!extensions = lhs
+mime!text/x-moc!extensions = moc
+mime!text/x-pascal!extensions = p,pas
+mime!text/x-pcs-gcd!extensions = gcd
+mime!text/x-perl!extensions = pl,pm
+mime!text/x-python!extensions = py
+mime!text/x-setext!extensions = etx
+mime!text/x-sh!extensions = sh
+mime!text/x-tcl!extensions = tcl,tk
+mime!text/x-tex!extensions = tex,ltx,sty,cls
+mime!text/x-vcalendar!extensions = vcs
+mime!text/x-vcard!extensions = vcf
+mime!video/dl!extensions = dl
+mime!video/dv!extensions = dif,dv
+mime!video/fli!extensions = fli
+mime!video/gl!extensions = gl
+mime!video/mp4!extensions = mp4
+mime!video/mpeg!extensions = mpeg,mpg,mpe
+mime!video/ogg!extensions = ogv
+mime!video/quicktime!extensions = qt,mov
+mime!video/vnd.mpegurl!extensions = mxu
+mime!video/webm!extensions = webm
+mime!video/x-flv!extensions = flv
+mime!video/x-la-asf!extensions = lsf,lsx
+mime!video/x-mng!extensions = mng
+mime!video/x-ms-asf!extensions = asf,asx
+mime!video/x-ms-wm!extensions = wm
+mime!video/x-ms-wmv!extensions = wmv
+mime!video/x-ms-wmx!extensions = wmx
+mime!video/x-ms-wvx!extensions = wvx
+mime!video/x-msvideo!extensions = avi
+mime!video/x-sgi-movie!extensions = movie
+mime!x-conference/x-cooltalk!extensions = ice
+mime!x-world/x-vrml!extensions = vrm,vrml,wrl
\ No newline at end of file
diff --git a/doc/webserver_sampleconfigs/lighttpd-site.conf b/doc/webserver_sampleconfigs/lighttpd-site.conf
new file mode 100644
index 0000000..677bf78
--- /dev/null
+++ b/doc/webserver_sampleconfigs/lighttpd-site.conf
@@ -0,0 +1,23 @@
+server.modules += ( "mod_fastcgi" )
+server.modules += ( "mod_rewrite" )
+
+fastcgi.server += ( ".php" =>
+ ((
+ "host" => "127.0.0.1",
+ "port" => "9000",
+ "broken-scriptfilename" => "enable"
+ ))
+)
+
+$HTTP["host"] == "stikked" {
+ url.rewrite-once = (
+ "^/static/(.*)$" => "/static/$1",
+ "^/favicon\.ico$" => "/favicon.ico",
+ "^/robots\.txt$" => "/robots.txt",
+ "^/(.*)$" => "/index.php$2",
+ )
+
+ server.document-root = "/var/www/stikked/htdocs"
+
+ #accesslog.filename = "/var/log/lighttpd/stikked.access.log"
+}
diff --git a/doc/webserver_sampleconfigs/nginx-site.conf b/doc/webserver_sampleconfigs/nginx-site.conf
new file mode 100644
index 0000000..b31acfd
--- /dev/null
+++ b/doc/webserver_sampleconfigs/nginx-site.conf
@@ -0,0 +1,23 @@
+server {
+ listen 80;
+ server_name stikked;
+ root /var/www/stikked/htdocs;
+ index index.php;
+
+# access_log /var/log/nginx/localhost.access_log combined;
+# error_log /var/log/nginx/localhost.error_log info;
+
+ if ($request_uri !~* ^/(static|favicon\.ico|robots\.txt))
+ {
+ rewrite ^/(.*)$ /index.php?/$1 last;
+ break;
+ }
+
+ location ~* \.php$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_index index.php;
+ fastcgi_split_path_info ^(.+\.php)(.*)$;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ }
+}
diff --git a/htdocs/application/config/autoload.php b/htdocs/application/config/autoload.php
index b602db2..7431c5d 100644
--- a/htdocs/application/config/autoload.php
+++ b/htdocs/application/config/autoload.php
@@ -64,7 +64,7 @@ $autoload['libraries'] = array('database', 'db_session', 'carabiner');
| $autoload['helper'] = array('url', 'file');
*/
-$autoload['helper'] = array('url', 'date');
+$autoload['helper'] = array('url', 'date', 'language');
/*
@@ -96,7 +96,7 @@ $autoload['config'] = array('stikked');
|
*/
-$autoload['language'] = array();
+$autoload['language'] = array('stikked');
/*
diff --git a/htdocs/application/config/codemirror_languages.php b/htdocs/application/config/codemirror_languages.php
index 40d24c3..ea80c18 100644
--- a/htdocs/application/config/codemirror_languages.php
+++ b/htdocs/application/config/codemirror_languages.php
@@ -135,10 +135,10 @@ $config['codemirror_languages'] = array(
) ,
) ,
'sql' => array(
- 'mode' => 'mysql',
+ 'mode' => 'sql',
'js' => array(
array(
- 'codemirror/mode/mysql/mysql.js'
+ 'codemirror/mode/sql/sql.js'
) ,
) ,
) ,
@@ -157,6 +157,22 @@ $config['codemirror_languages'] = array(
'6502tasm' => 'MOS 6502 TASM/64TASS',
'68000devpac' => 'Motorola 68000 Devpac Assembler',
'abap' => 'ABAP',
+ 'apl' => array(
+ 'mode' => 'apl',
+ 'js' => array(
+ array(
+ 'codemirror/mode/apl/apl.js'
+ ) ,
+ ) ,
+ ) ,
+ 'asterisk' => array(
+ 'mode' => 'asterisk',
+ 'js' => array(
+ array(
+ 'codemirror/mode/asterisk/asterisk.js'
+ ) ,
+ ) ,
+ ) ,
'actionscript' => 'Actionscript',
'actionscript3' => 'ActionScript3',
'ada' => 'Ada',
@@ -221,7 +237,14 @@ $config['codemirror_languages'] = array(
) ,
) ,
'cuesheet' => 'Cuesheet',
- 'd' => 'D',
+ 'd' => array(
+ 'mode' => 'd',
+ 'js' => array(
+ array(
+ 'codemirror/mode/d/d.js'
+ ) ,
+ ) ,
+ ) ,
'dcs' => 'DCS',
'delphi' => 'Delphi (Object Pascal)',
'div' => 'DIV',
@@ -239,6 +262,14 @@ $config['codemirror_languages'] = array(
'eiffel' => 'Eiffel',
'email' => 'Email (mbox/eml/RFC format)',
'epc' => 'Enerscript',
+ 'erlang' => array(
+ 'mode' => 'erlang',
+ 'js' => array(
+ array(
+ 'codemirror/mode/erlang/erlang.js'
+ ) ,
+ ) ,
+ ) ,
'euphoria' => 'Euphoria',
'f1' => 'Formula One',
'falcon' => 'Falcon',
@@ -254,6 +285,14 @@ $config['codemirror_languages'] = array(
'glsl' => 'glSlang',
'gml' => 'GML',
'gnuplot' => 'Gnuplot script',
+ 'go' => array(
+ 'mode' => 'go',
+ 'js' => array(
+ array(
+ 'codemirror/mode/go/go.js'
+ ) ,
+ ) ,
+ ) ,
'groovy' => array(
'mode' => 'text/x-groovy',
'js' => array(
@@ -271,6 +310,14 @@ $config['codemirror_languages'] = array(
) ,
) ,
) ,
+ 'haxe' => array(
+ 'mode' => 'text/x-haxe',
+ 'js' => array(
+ array(
+ 'codemirror/mode/haxe/haxe.js'
+ ) ,
+ ) ,
+ ) ,
'hicest' => 'HicEst',
'hq9plus' => 'HQ9+',
'html4strict' => array(
@@ -340,17 +387,24 @@ $config['codemirror_languages'] = array(
'make' => 'Make',
'mapbasic' => 'MapBasic',
'matlab' => 'Matlab M-file',
- 'mirc' => 'mIRC Scripting',
+ 'mirc' => array(
+ 'mode' => 'mirc',
+ 'js' => array(
+ array(
+ 'codemirror/mode/mirc/mirc.js'
+ ) ,
+ ) ,
+ ) ,
'mmix' => 'MMIX Assembler',
'modula2' => 'Modula-2',
'modula3' => 'Modula-3',
'mpasm' => 'Microchip Assembler',
'mxml' => 'MXML',
'mysql' => array(
- 'mode' => 'mysql',
+ 'mode' => 'sql',
'js' => array(
array(
- 'codemirror/mode/mysql/mysql.js'
+ 'codemirror/mode/sql/sql.js'
) ,
) ,
) ,
@@ -360,6 +414,14 @@ $config['codemirror_languages'] = array(
'objc' => 'Objective-C',
'objeck' => 'Objeck Programming Language',
'ocaml' => 'OCaml (Objective Caml)',
+ 'ocaml' => array(
+ 'mode' => 'text/x-ocaml',
+ 'js' => array(
+ array(
+ 'codemirror/mode/ocaml/ocaml.js'
+ ) ,
+ ) ,
+ ) ,
'oobas' => 'OpenOffice.org Basic',
'oracle11' => 'Oracle 11i',
'oracle8' => 'Oracle 8',
@@ -397,10 +459,10 @@ $config['codemirror_languages'] = array(
'pixelbender' => 'Pixel Bender 1.0',
'pli' => 'PL/I',
'plsql' => array(
- 'mode' => 'plsql',
+ 'mode' => 'sql',
'js' => array(
array(
- 'codemirror/mode/plsql/plsql.js'
+ 'codemirror/mode/sql/sql.js'
) ,
) ,
) ,
@@ -421,7 +483,14 @@ $config['codemirror_languages'] = array(
) ,
'providex' => 'ProvideX',
'purebasic' => 'PureBasic',
- 'q' => 'q/kdb+',
+ 'q' => array(
+ 'mode' => 'text/x-q',
+ 'js' => array(
+ array(
+ 'codemirror/mode/q/q.js'
+ ) ,
+ ) ,
+ ) ,
'qbasic' => 'QBasic/QuickBASIC',
'rails' => 'Ruby (with Ruby on Rails Framework)',
'rebol' => 'Rebol',
@@ -430,7 +499,14 @@ $config['codemirror_languages'] = array(
'rpmspec' => 'RPM Spec',
'rsplus' => 'R',
'sas' => 'SAS',
- 'scala' => 'Scala',
+ 'scala' => array(
+ 'mode' => 'scala',
+ 'js' => array(
+ array(
+ 'codemirror/mode/clike/clike.js'
+ ) ,
+ ) ,
+ ) ,
'scheme' => array(
'mode' => 'text/x-scheme',
'js' => array(
@@ -444,7 +520,14 @@ $config['codemirror_languages'] = array(
'smalltalk' => 'Smalltalk',
'smarty' => 'Smarty template',
'systemverilog' => 'SystemVerilog IEEE 1800-2009(draft8)',
- 'tcl' => 'TCL/iTCL',
+ 'tcl' => array(
+ 'mode' => 'text/x-tcl',
+ 'js' => array(
+ array(
+ 'codemirror/mode/tcl/tcl.js'
+ ) ,
+ ) ,
+ ) ,
'teraterm' => 'Tera Term Macro',
'thinbasic' => 'thinBasic',
'tsql' => 'T-SQL',
@@ -453,18 +536,10 @@ $config['codemirror_languages'] = array(
'uscript' => 'UnrealScript',
'vala' => 'Vala',
'vb' => array(
- 'mode' => 'text/vbscript',
+ 'mode' => 'text/x-vb',
'js' => array(
array(
- 'codemirror/mode/vbscript/vbscript.js'
- ) ,
- ) ,
- ) ,
- 'vbnet' => array(
- 'mode' => 'text/vbscript',
- 'js' => array(
- array(
- 'codemirror/mode/vbscript/vbscript.js'
+ 'codemirror/mode/vb/vb.js'
) ,
) ,
) ,
@@ -494,6 +569,13 @@ $config['codemirror_languages'] = array(
) ,
) ,
) ,
- 'z80' => 'ZiLOG Z80 Assembler',
+ 'z80' => array(
+ 'mode' => 'text/x-z80',
+ 'js' => array(
+ array(
+ 'codemirror/mode/z80/z80.js'
+ ) ,
+ ) ,
+ ) ,
'zxbasic' => 'ZXBasic',
);
diff --git a/htdocs/application/config/config.php b/htdocs/application/config/config.php
index 3ec5aca..3c92c9d 100644
--- a/htdocs/application/config/config.php
+++ b/htdocs/application/config/config.php
@@ -16,6 +16,16 @@
*/
$config['base_url'] = '';
+/*
+|--------------------------------------------------------------------------
+| Stikked version
+|--------------------------------------------------------------------------
+|
+| So that we can track your version.
+|
+*/
+$config['stikked_version'] = '0.8.5';
+
/*
|--------------------------------------------------------------------------
| Index File
@@ -69,7 +79,7 @@ $config['url_suffix'] = '';
| than english.
|
*/
-$config['language'] = 'english';
+#$config['language'] = 'english'; #this is configured in config/stikked.php
/*
|--------------------------------------------------------------------------
diff --git a/htdocs/application/config/geshi_languages.php b/htdocs/application/config/geshi_languages.php
index c39c58d..f98b42d 100644
--- a/htdocs/application/config/geshi_languages.php
+++ b/htdocs/application/config/geshi_languages.php
@@ -39,7 +39,9 @@ $config['geshi_languages'] = array(
'apache' => 'Apache',
'applescript' => 'AppleScript',
'apt_sources' => 'Apt sources.list',
+ 'arm' => 'ARM Assembler',
'asm' => 'x86 Assembler',
+ 'asymptote' => 'asymptote',
'asp' => 'ASP',
'autoconf' => 'autoconf',
'autohotkey' => 'Autohotkey',
@@ -69,6 +71,8 @@ $config['geshi_languages'] = array(
'cuesheet' => 'Cuesheet',
'd' => 'D',
'dcs' => 'DCS',
+ 'dcl' => 'DCL',
+ 'dcpu16' => 'DCPU/16 Assembly',
'delphi' => 'Delphi (Object Pascal)',
'div' => 'DIV',
'dos' => 'DOS',
@@ -84,6 +88,7 @@ $config['geshi_languages'] = array(
'fo' => 'fo',
'fortran' => 'Fortran',
'freebasic' => 'FreeBasic',
+ 'freeswitch' => 'FreeSWITCH',
'fsharp' => 'F#',
'gambas' => 'GAMBAS',
'gdb' => 'GDB',
@@ -96,6 +101,7 @@ $config['geshi_languages'] = array(
'groovy' => 'Groovy',
'gwbasic' => 'GwBasic',
'haskell' => 'Haskell',
+ 'haxe' => 'Haxe',
'hicest' => 'HicEst',
'hq9plus' => 'HQ9+',
'html4strict' => 'HTML 4.01 strict',
@@ -114,6 +120,7 @@ $config['geshi_languages'] = array(
'klonec' => 'KLone with C',
'klonecpp' => 'KLone with C++',
'lb' => 'Liberty BASIC',
+ 'ldif' => 'LDIF',
'lisp' => 'Generic Lisp',
'llvm' => 'LLVM',
'locobasic' => 'Locomotive Basic (Amstrad CPC series)',
@@ -135,17 +142,23 @@ $config['geshi_languages'] = array(
'mpasm' => 'Microchip Assembler',
'mxml' => 'MXML',
'mysql' => 'MySQL',
+ 'nagios' => 'Nagios',
+ 'netrexx' => 'NetRexx',
'newlisp' => 'newLISP',
'nsis' => 'Nullsoft Scriptable Install System',
'oberon2' => 'Oberon-2',
'objc' => 'Objective-C',
'objeck' => 'Objeck Programming Language',
'ocaml' => 'OCaml (Objective Caml)',
+ 'octave' => 'GNU Octave M-file',
'oobas' => 'OpenOffice.org Basic',
+ 'oorexx' => 'ooRexx',
'oracle11' => 'Oracle 11i',
'oracle8' => 'Oracle 8',
'oxygene' => 'Delphi Prism (Oxygene)',
'oz' => 'Oz',
+ 'parasail' => 'ParaSail',
+ 'parigp' => 'PARI/GP',
'pascal' => 'Pascal',
'pcre' => 'PCRE',
'per' => 'Per (forms)',
@@ -167,11 +180,13 @@ $config['geshi_languages'] = array(
'properties' => 'Property',
'providex' => 'ProvideX',
'purebasic' => 'PureBasic',
+ 'pys60' => 'Python for S60',
'q' => 'q/kdb+',
'qbasic' => 'QBasic/QuickBASIC',
'rails' => 'Ruby (with Ruby on Rails Framework)',
'rebol' => 'Rebol',
'reg' => 'Microsoft Registry Editor',
+ 'rexx' => 'Rexx',
'robots' => 'robots.txt',
'rpmspec' => 'RPM Spec',
'rsplus' => 'R',
@@ -182,6 +197,9 @@ $config['geshi_languages'] = array(
'sdlbasic' => 'sdlBasic',
'smalltalk' => 'Smalltalk',
'smarty' => 'Smarty template',
+ 'spark' => 'SPARK',
+ 'sparql' => 'SPARQL',
+ 'stonescript' => 'StoneScript',
'systemverilog' => 'SystemVerilog IEEE 1800-2009(draft8)',
'tcl' => 'TCL/iTCL',
'teraterm' => 'Tera Term Macro',
@@ -190,9 +208,12 @@ $config['geshi_languages'] = array(
'typoscript' => 'TypoScript',
'unicon' => 'Unicon',
'uscript' => 'UnrealScript',
+ 'upc' => 'UPC',
+ 'urbi' => 'Urbi',
'vala' => 'Vala',
'vb' => 'Visual Basic',
'vbnet' => 'VB.NET',
+ 'vedit' => 'Vedit macro language',
'verilog' => 'Verilog',
'vhdl' => 'VHDL',
'vim' => 'Vim scripting',
diff --git a/htdocs/application/config/routes.php b/htdocs/application/config/routes.php
index eafc508..910b96a 100644
--- a/htdocs/application/config/routes.php
+++ b/htdocs/application/config/routes.php
@@ -55,6 +55,8 @@ $route['lists/:num'] = 'main/lists/$1';
$route['trends'] = 'main/trends';
$route['trends/:any'] = 'main/trends/$1';
$route['spamadmin/:num'] = 'spamadmin/index';
+$route['spamadmin/blacklist'] = 'spamadmin/blacklist';
+$route['spamadmin/blacklist/(:num)'] = 'spamadmin/blacklist';
$route['spamadmin/blacklist/unblock/(:any)'] = 'spamadmin/unblock_ip';
$route['spamadmin/:any'] = 'spamadmin/spam_detail';
$route['about'] = 'main/about';
@@ -66,6 +68,7 @@ $route['404_override'] = 'main/error_404';
$route['themes/:any/css/:any'] = 'theme_assets/css';
$route['themes/:any/images/:any'] = 'theme_assets/images';
+$route['themes/:any/img/:any'] = 'theme_assets/images';
$route['themes/:any/js/:any'] = 'theme_assets/js';
/* End of file routes.php */
diff --git a/htdocs/application/config/stikked.php b/htdocs/application/config/stikked.php
index 082337a..c0a8c0c 100644
--- a/htdocs/application/config/stikked.php
+++ b/htdocs/application/config/stikked.php
@@ -25,10 +25,21 @@ $config['db_password'] = 'stikked';
*
* Which theme to use
* Folder name in htdocs/themes/
+ * Currently: default, bootstrap, gabdark, gabdark3, geocities
*
*/
$config['theme'] = 'default';
+/**
+ * Language
+ *
+ * Which language to use
+ * Translate Stikked to your own language, see htdocs/application/language files
+ * Currently: english, german, swissgerman, spanish
+ *
+*/
+$config['language'] = 'english';
+
/**
* Combine JS & CSS files (recommended)
*
@@ -77,11 +88,16 @@ $config['per_page'] = 15;
*
* private_only: No recent pastes will be displayed.
* enable_captcha: Users must enter a captcha to post.
+ * recaptcha_publickey & recaptcha_privatekey: If filled, reCaptcha will be used (get a key from https://www.google.com/recaptcha/admin/create)
* blocked_words: Comma separated list, e.g. '.es.tl, mycraft.com, yourbadword'
+ * disable_api: Don't allow pasting via API (because we can't use a captcha there...)
*
**/
$config['private_only'] = false;
$config['enable_captcha'] = false;
+$config['recaptcha_publickey'] = '';
+$config['recaptcha_privatekey'] = '';
+$config['disable_api'] = false;
$config['blocked_words'] = '';
//spamadmin: accessible via /spamadmin (only active when user + pass is set)
diff --git a/htdocs/application/controllers/api.php b/htdocs/application/controllers/api.php
index 1de7e2b..3b3703c 100644
--- a/htdocs/application/controllers/api.php
+++ b/htdocs/application/controllers/api.php
@@ -18,6 +18,11 @@ class Api extends Main
function __construct()
{
parent::__construct();
+
+ if (config_item('disable_api'))
+ {
+ die("The API has been disabled\n");
+ }
}
function index()
@@ -32,6 +37,8 @@ class Api extends Main
function create()
{
$this->load->model('pastes');
+ $this->load->library('form_validation'); //needed by parent class
+
if (!$this->input->post('text'))
{
@@ -51,6 +58,20 @@ class Api extends Main
{
$_POST['private'] = 1;
}
+
+ //validations
+
+ if (!$this->_valid_ip())
+ {
+ die("You are not allowed to paste\n");
+ }
+
+ if (!$this->_blockwords_check())
+ {
+ die("Your paste contains blocked words\n");
+ }
+
+ //create paste
$paste_url = $this->pastes->createPaste();
$data['msg'] = base_url() . $paste_url;
$this->load->view('view/api', $data);
diff --git a/htdocs/application/controllers/main.php b/htdocs/application/controllers/main.php
index ae81df7..aa0136d 100644
--- a/htdocs/application/controllers/main.php
+++ b/htdocs/application/controllers/main.php
@@ -17,6 +17,7 @@
* - captcha()
* - _valid_lang()
* - _valid_captcha()
+ * - _valid_recaptcha()
* - _valid_ip()
* - _blockwords_check()
* - _autofill_check()
@@ -35,10 +36,20 @@ class Main extends CI_Controller
parent::__construct();
$this->load->model('languages');
- if ($this->config->item('require_auth'))
+ if (config_item('require_auth'))
{
$this->load->library('auth_ldap');
}
+
+ //recaptcha
+ $this->recaptcha_publickey = config_item('recaptcha_publickey');
+ $this->recaptcha_privatekey = config_item('recaptcha_privatekey');
+
+ if ($this->recaptcha_publickey != '' && $this->recaptcha_privatekey != '')
+ {
+ $this->load->helper('recaptcha');
+ $this->use_recaptcha = true;
+ }
if (!$this->db->table_exists('ci_sessions'))
{
@@ -249,7 +260,7 @@ class Main extends CI_Controller
//codemirror languages
$this->load->config('codemirror_languages');
- $codemirror_languages = $this->config->item('codemirror_languages');
+ $codemirror_languages = config_item('codemirror_languages');
$data['codemirror_languages'] = $codemirror_languages;
//codemirror modes
@@ -263,13 +274,17 @@ class Main extends CI_Controller
}
}
$data['codemirror_modes'] = $cmm;
+
+ //recaptcha
+ $data['use_recaptcha'] = $this->use_recaptcha;
+ $data['recaptcha_publickey'] = $this->recaptcha_publickey;
if (!$this->input->post('submit'))
{
if (!$this->db_session->userdata('expire'))
{
- $default_expiration = $this->config->item('default_expiration');
+ $default_expiration = config_item('default_expiration');
$this->db_session->set_userdata('expire', $default_expiration);
}
@@ -287,7 +302,7 @@ class Main extends CI_Controller
if (!$lang)
{
- $lang = $this->config->item('default_language');
+ $lang = config_item('default_language');
}
$data['lang_set'] = $lang;
}
@@ -356,7 +371,7 @@ class Main extends CI_Controller
//form validation
$this->form_validation->set_rules($rules);
- $this->form_validation->set_message('min_length', 'The %s field can not be empty');
+ $this->form_validation->set_message('min_length', lang('empty'));
$this->form_validation->set_error_delimiters('
');
if ($this->form_validation->run() == FALSE)
@@ -367,7 +382,7 @@ class Main extends CI_Controller
else
{
- if ($this->config->item('private_only'))
+ if (config_item('private_only'))
{
$_POST['private'] = 1;
}
@@ -416,7 +431,7 @@ class Main extends CI_Controller
$this->load->helper('text');
$paste = $this->pastes->getPaste(3);
$data = $this->pastes->getReplies(3);
- $data['page_title'] = $paste['title'] . ' - ' . $this->config->item('site_name');
+ $data['page_title'] = $paste['title'] . ' - ' . config_item('site_name');
$data['feed_url'] = site_url('view/rss/' . $this->uri->segment(3));
$this->load->view('view/rss', $data);
}
@@ -434,7 +449,7 @@ class Main extends CI_Controller
if ($check)
{
- $data = $this->pastes->getPaste(3);
+ $data = $this->pastes->getPaste(3, true, $this->uri->segment(4) == 'diff');
$this->load->view('view/embed', $data);
}
else
@@ -464,7 +479,7 @@ class Main extends CI_Controller
{
$this->_valid_authentication();
- if ($this->config->item('private_only'))
+ if (config_item('private_only'))
{
show_404();
}
@@ -476,7 +491,7 @@ class Main extends CI_Controller
if ($this->uri->segment(2) == 'rss')
{
$this->load->helper('text');
- $data['page_title'] = $this->config->item('site_name');
+ $data['page_title'] = config_item('site_name');
$data['feed_url'] = site_url('lists/rss');
$data['replies'] = $data['pastes'];
unset($data['pastes']);
@@ -493,7 +508,7 @@ class Main extends CI_Controller
{
$this->_valid_authentication();
- if ($this->config->item('private_only'))
+ if (config_item('private_only'))
{
show_404();
}
@@ -519,7 +534,7 @@ class Main extends CI_Controller
{
redirect('view/raw/' . $this->uri->segment(2));
}
- $data = $this->pastes->getPaste(2, true);
+ $data = $this->pastes->getPaste(2, true, $this->uri->segment(3) == 'diff');
$data['reply_form'] = $this->_form_prep($data['lang_code'], 'Re: ' . $data['title'], $data['raw'], $data['pid']);
$this->load->view('view/view', $data);
}
@@ -534,7 +549,7 @@ class Main extends CI_Controller
$this->load->model('pastes');
$key = $this->uri->segment(2);
- if ($key != $this->config->item('cron_key'))
+ if ($key != config_item('cron_key'))
{
show_404();
}
@@ -577,17 +592,25 @@ class Main extends CI_Controller
function _valid_lang($lang)
{
$this->load->model('languages');
- $this->form_validation->set_message('_valid_lang', 'Please select your language');
+ $this->form_validation->set_message('_valid_lang', lang('valid_lang'));
return $this->languages->valid_language($lang);
}
function _valid_captcha($text)
{
- if ($this->config->item('enable_captcha'))
+ if (config_item('enable_captcha'))
{
- $this->form_validation->set_message('_valid_captcha', 'The Captcha is incorrect.');
- return strtolower($text) == strtolower($this->db_session->userdata('captcha'));
+ $this->form_validation->set_message('_valid_captcha', lang('captcha'));
+
+ if ($this->use_recaptcha)
+ {
+ return $this->_valid_recaptcha();
+ }
+ else
+ {
+ return strtolower($text) == strtolower($this->db_session->userdata('captcha'));
+ }
}
else
{
@@ -595,6 +618,26 @@ class Main extends CI_Controller
}
}
+ function _valid_recaptcha()
+ {
+
+ if ($this->input->post('recaptcha_response_field'))
+ {
+ $pk = $this->recaptcha_privatekey;
+ $ra = $_SERVER['REMOTE_ADDR'];
+ $cf = $this->input->post('recaptcha_challenge_field');
+ $rf = $this->input->post('recaptcha_response_field');
+
+ //check
+ $resp = recaptcha_check_answer($pk, $ra, $cf, $rf);
+ return $resp->is_valid;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
function _valid_ip()
{
@@ -604,7 +647,7 @@ class Main extends CI_Controller
$ip_firstpart = $ip[0] . '.' . $ip[1] . '.';
//setup message
- $this->form_validation->set_message('_valid_ip', 'You are not allowed to paste.');
+ $this->form_validation->set_message('_valid_ip', lang('not_allowed'));
//lookup
$this->db->select('ip_address, spam_attempts');
@@ -637,12 +680,19 @@ class Main extends CI_Controller
{
//setup message
- $this->form_validation->set_message('_blockwords_check', 'Your paste contains blocked words.');
+ $this->form_validation->set_message('_blockwords_check', lang('blocked_words'));
//check
- $blocked_words = $this->config->item('blocked_words');
+ $blocked_words = config_item('blocked_words');
$post = $this->input->post();
$raw = $post['code'];
+
+ if (!$blocked_words)
+ {
+ return true;
+ }
+
+ //we have blocked words
foreach (explode(',', $blocked_words) as $word)
{
$word = trim($word);
@@ -659,16 +709,16 @@ class Main extends CI_Controller
{
//setup message
- $this->form_validation->set_message('_autofill_check', 'Go away, robot!');
+ $this->form_validation->set_message('_autofill_check', lang('robot'));
//check
- return !$this->input->post('email');
+ return (!$this->input->post('email') && !$this->input->post('url'));
}
function _valid_authentication()
{
- if ($this->config->item('require_auth'))
+ if (config_item('require_auth'))
{
if (!$this->auth_ldap->is_authenticated())
@@ -683,14 +733,23 @@ class Main extends CI_Controller
{
$lang = $this->uri->segment(3);
$this->load->config('codemirror_languages');
- $cml = $this->config->item('codemirror_languages');
+ $cml = config_item('codemirror_languages');
+
+ //file path
+ $file_path = 'themes/' . config_item('theme') . '/js/';
+
+ if (!file_exists($file_path))
+ {
+ $file_path = 'themes/default/js/';
+ }
if (isset($cml[$lang]) && gettype($cml[$lang]) == 'array')
{
header('Content-Type: application/x-javascript; charset=utf-8');
+ header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 60 * 60 * 24 * 30));
foreach ($cml[$lang]['js'] as $js)
{
- echo file_get_contents('./static/js/' . $js[0]);
+ echo file_get_contents($file_path . $js[0]);
}
}
exit;
diff --git a/htdocs/application/controllers/theme_assets.php b/htdocs/application/controllers/theme_assets.php
index 5d02a88..b1a6b47 100644
--- a/htdocs/application/controllers/theme_assets.php
+++ b/htdocs/application/controllers/theme_assets.php
@@ -55,7 +55,8 @@ class Theme_assets extends CI_Controller
}
//send
- header('Content-type: ' . mime_content_type($file_path));
+ $size = getimagesize($file_path);
+ header('Content-type: ' . $size['mime']);
$this->_expires_header(30);
readfile($file_path);
}
@@ -74,8 +75,15 @@ class Theme_assets extends CI_Controller
//file path
$file_path = 'themes/' . $this->theme . '/js/' . $js_file;
+ //fallback to default js if js in theme not found
+
+ if (!file_exists($file_path))
+ {
+ $file_path = 'themes/default/js/' . $js_file;
+ }
+
//send
- header('Content-type: application/x-javascript');
+ header('Content-Type: application/x-javascript; charset=utf-8');
$this->_expires_header(30);
readfile($file_path);
}
diff --git a/htdocs/application/errors/error_404.php b/htdocs/application/errors/error_404.php
index 0b2aef9..8beb033 100644
--- a/htdocs/application/errors/error_404.php
+++ b/htdocs/application/errors/error_404.php
@@ -9,9 +9,9 @@ header("HTTP/1.1 404 Not Found");
Stikked
-
-
-
+
+
+
@@ -19,14 +19,6 @@ header("HTTP/1.1 404 Not Found");
@@ -41,10 +33,6 @@ header("HTTP/1.1 404 Not Found");
-
diff --git a/htdocs/application/helpers/language_helper.php b/htdocs/application/helpers/language_helper.php
new file mode 100644
index 0000000..567a41a
--- /dev/null
+++ b/htdocs/application/helpers/language_helper.php
@@ -0,0 +1,58 @@
+lang->line($index);
+
+ if ($id != '')
+ {
+ $line = '";
+ }
+
+ return ($line != '' ? $line : '[' . $index . ']');
+ }
+}
+
+// ------------------------------------------------------------------------
+/* End of file language_helper.php */
+/* Location: ./system/helpers/language_helper.php */
diff --git a/htdocs/application/helpers/recaptcha_helper.php b/htdocs/application/helpers/recaptcha_helper.php
new file mode 100644
index 0000000..32c4f4d
--- /dev/null
+++ b/htdocs/application/helpers/recaptcha_helper.php
@@ -0,0 +1,277 @@
+ $value )
+ $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
+
+ // Cut the last '&'
+ $req=substr($req,0,strlen($req)-1);
+ return $req;
+}
+
+
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+ $req = _recaptcha_qsencode ($data);
+
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+
+ $response = '';
+ if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
+ die ('Could not open socket');
+ }
+
+ fwrite($fs, $http_request);
+
+ while ( !feof($fs) )
+ $response .= fgets($fs, 1160); // One TCP-IP packet
+ fclose($fs);
+ $response = explode("\r\n\r\n", $response, 2);
+
+ return $response;
+}
+
+
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
+{
+ if ($pubkey == null || $pubkey == '') {
+ die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create");
+ }
+
+ if ($use_ssl) {
+ $server = RECAPTCHA_API_SECURE_SERVER;
+ } else {
+ $server = RECAPTCHA_API_SERVER;
+ }
+
+ $errorpart = "";
+ if ($error) {
+ $errorpart = "&error=" . $error;
+ }
+ return '
+
+ ';
+}
+
+
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+ var $is_valid;
+ var $error;
+}
+
+
+/**
+ * Calls an HTTP POST function to verify if the user's guess was correct
+ * @param string $privkey
+ * @param string $remoteip
+ * @param string $challenge
+ * @param string $response
+ * @param array $extra_params an array of extra variables to post to the server
+ * @return ReCaptchaResponse
+ */
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
+{
+ if ($privkey == null || $privkey == '') {
+ die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create");
+ }
+
+ if ($remoteip == null || $remoteip == '') {
+ die ("For security reasons, you must pass the remote ip to reCAPTCHA");
+ }
+
+
+
+ //discard spam submissions
+ if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
+ $recaptcha_response = new ReCaptchaResponse();
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = 'incorrect-captcha-sol';
+ return $recaptcha_response;
+ }
+
+ $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
+ array (
+ 'privatekey' => $privkey,
+ 'remoteip' => $remoteip,
+ 'challenge' => $challenge,
+ 'response' => $response
+ ) + $extra_params
+ );
+
+ $answers = explode ("\n", $response [1]);
+ $recaptcha_response = new ReCaptchaResponse();
+
+ if (trim ($answers [0]) == 'true') {
+ $recaptcha_response->is_valid = true;
+ }
+ else {
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = $answers [1];
+ }
+ return $recaptcha_response;
+
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url ($domain = null, $appname = null) {
+ return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val) {
+ $block_size = 16;
+ $numpad = $block_size - (strlen ($val) % $block_size);
+ return str_pad($val, strlen ($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky) {
+ if (! function_exists ("mcrypt_encrypt")) {
+ die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
+ }
+ $mode=MCRYPT_MODE_CBC;
+ $enc=MCRYPT_RIJNDAEL_128;
+ $val=_recaptcha_aes_pad($val);
+ return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+
+function _recaptcha_mailhide_urlbase64 ($x) {
+ return strtr(base64_encode ($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+ if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
+ die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
+ "you can do so at http://www.google.com/recaptcha/mailhide/apikey");
+ }
+
+
+ $ky = pack('H*', $privkey);
+ $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
+
+ return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given johndoe@example,com return ["john", "example.com"].
+ * the email is then displayed as john...@example.com
+ */
+function _recaptcha_mailhide_email_parts ($email) {
+ $arr = preg_split("/@/", $email );
+
+ if (strlen ($arr[0]) <= 4) {
+ $arr[0] = substr ($arr[0], 0, 1);
+ } else if (strlen ($arr[0]) <= 6) {
+ $arr[0] = substr ($arr[0], 0, 3);
+ } else {
+ $arr[0] = substr ($arr[0], 0, 4);
+ }
+ return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://www.google.com/recaptcha/mailhide/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+ $emailparts = _recaptcha_mailhide_email_parts ($email);
+ $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
+
+ return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]);
+
+}
+
+
+?>
diff --git a/htdocs/application/language/english/date_lang.php b/htdocs/application/language/english/date_lang.php
new file mode 100644
index 0000000..c0ace16
--- /dev/null
+++ b/htdocs/application/language/english/date_lang.php
@@ -0,0 +1,61 @@
+
-
- 403 Forbidden
-
-
-
-Directory access is forbidden.
-
-
-