Permalink
Browse files

Merge branch 'master' of github.com:stunti/LampCMS

Conflicts:
	lib/Lampcms/Ini.php
  • Loading branch information...
2 parents 3783c3d + 86769a7 commit 868efec61bdd157273d44f8b74075c229d832082 @stunti committed Jun 9, 2011
Showing with 12,168 additions and 1,828 deletions.
  1. +81 −0 Mycollections.php.dist
  2. +61 −3 lib/Lampcms/Points.php → Points.php.dist
  3. +2 −0 RewriteRules.txt
  4. +3 −2 acl.ini
  5. +150 −0 acl.ini.dist
  6. +103 −0 autoload.php
  7. +192 −11 config.ini
  8. +31 −60 inc.php
  9. +50 −57 lib/Lampcms/Acl/Acl.php
  10. +14 −4 lib/Lampcms/Acl/Role.php
  11. +133 −36 lib/Lampcms/Answer.php
  12. +39 −23 lib/Lampcms/AnswerParser.php
  13. +12 −15 lib/Lampcms/Answers.php
  14. +615 −0 lib/Lampcms/Api/Api.php
  15. +241 −0 lib/Lampcms/Api/v1/Question.php
  16. +504 −0 lib/Lampcms/Api/v1/Questions.php
  17. +142 −0 lib/Lampcms/Api/v1/Tags.php
  18. +194 −0 lib/Lampcms/Api/v1/Users.php
  19. +171 −0 lib/Lampcms/AvatarParser.php
  20. +2 −0 lib/Lampcms/Badwords.php
  21. +72 −11 lib/Lampcms/Base.php
  22. +144 −0 lib/Lampcms/Bitly.php
  23. +41 −37 lib/Lampcms/Cache.php
  24. +1 −1 lib/Lampcms/CacheHeaders.php
  25. +81 −48 lib/Lampcms/Captcha.php
  26. +4 −4 lib/Lampcms/Controllers/Accept.php
  27. +12 −3 lib/Lampcms/Controllers/Addcomment.php
  28. +2 −2 lib/Lampcms/Controllers/Answer.php
  29. +10 −5 lib/Lampcms/Controllers/Ask.php
  30. +54 −24 lib/Lampcms/Controllers/Askform.php
  31. +2 −4 lib/Lampcms/Controllers/Changepwd.php
  32. +515 −0 lib/Lampcms/Controllers/Connectblogger.php
  33. +124 −0 lib/Lampcms/Controllers/Connectfb.php
  34. +6 −7 lib/Lampcms/Controllers/Delete.php
  35. +45 −7 lib/Lampcms/Controllers/Edit.php
  36. +74 −22 lib/Lampcms/Controllers/Editor.php
  37. +265 −0 lib/Lampcms/Controllers/Editprofile.php
  38. +8 −1 lib/Lampcms/Controllers/Emailoptions.php
  39. +9 −3 lib/Lampcms/Controllers/Flagcomment.php
  40. +9 −13 lib/Lampcms/Controllers/Flagger.php
  41. +7 −0 lib/Lampcms/Controllers/Likecomment.php
  42. +4 −21 lib/Lampcms/Controllers/Login.php
  43. +514 −0 lib/Lampcms/Controllers/Logintumblr.php
  44. +192 −91 lib/Lampcms/Controllers/Logintwitter.php
  45. +41 −35 lib/Lampcms/Controllers/Logout.php
  46. +3 −6 lib/Lampcms/Controllers/Quickreg.php
  47. +14 −13 lib/Lampcms/Controllers/Register.php
  48. +12 −13 lib/Lampcms/Controllers/Remindpwd.php
  49. +4 −2 lib/Lampcms/Controllers/Requestactivation.php
  50. +12 −22 lib/Lampcms/Controllers/Resetpwd.php
  51. +90 −24 lib/Lampcms/Controllers/Retag.php
  52. +5 −3 lib/Lampcms/Controllers/Search.php
  53. +2 −2 lib/Lampcms/Controllers/Settings.php
  54. +14 −13 lib/Lampcms/Controllers/Shred.php
  55. +20 −21 lib/Lampcms/Controllers/Tagged.php
  56. +6 −5 lib/Lampcms/Controllers/Titlehint.php
  57. +145 −0 lib/Lampcms/Controllers/Tumblrselect.php
  58. +7 −8 lib/Lampcms/Controllers/Tweet.php
  59. +80 −20 lib/Lampcms/Controllers/Unanswered.php
  60. +94 −6 lib/Lampcms/Controllers/Userinfo.php
  61. +102 −0 lib/Lampcms/Controllers/Userinfotab.php
  62. +67 −30 lib/Lampcms/Controllers/Viewquestion.php
  63. +55 −34 lib/Lampcms/Controllers/Viewquestions.php
  64. +12 −8 lib/Lampcms/Controllers/Vote.php
  65. +33 −39 lib/Lampcms/Cookie.php
  66. +22 −32 lib/Lampcms/CookieAuth.php
  67. +19 −26 lib/Lampcms/Curl.php
  68. +48 −51 lib/Lampcms/DB.php
  69. +144 −0 lib/Lampcms/Dom/Document.php
  70. +307 −0 lib/Lampcms/Dom/Element.php
  71. +56 −0 lib/Lampcms/Dom/Exception.php
  72. +65 −0 lib/Lampcms/Dom/Node.php
  73. +64 −0 lib/Lampcms/Dom/Text.php
  74. +5 −89 lib/Lampcms/DomFeedItem.php
  75. +29 −97 lib/Lampcms/Event/Dispatcher.php
  76. +23 −18 lib/Lampcms/Event/Notification.php
  77. +38 −36 lib/Lampcms/Exception.php
  78. +72 −2 lib/Lampcms/ExternalAuth.php
  79. +373 −152 lib/Lampcms/ExternalAuthFb.php
  80. +26 −97 lib/Lampcms/ExternalAuthGfc.php
  81. +144 −0 lib/Lampcms/FS/Path.php
  82. +93 −45 lib/Lampcms/Facebook.php
  83. +27 −17 lib/Lampcms/Forms/Answerform.php
  84. +105 −40 lib/Lampcms/Forms/Askform.php
  85. +138 −23 lib/Lampcms/Forms/Form.php
  86. +174 −0 lib/Lampcms/Forms/Profile.php
  87. +148 −89 lib/Lampcms/Geoip.php
  88. +20 −14 lib/Lampcms/GeoipLocation.php
  89. +12 −12 lib/Lampcms/H2t.php
  90. +2 −0 lib/Lampcms/Http.php
  91. +202 −0 lib/Lampcms/Image/Editor.php
  92. +717 −0 lib/Lampcms/Image/EditorGD.php
  93. +83 −35 lib/Lampcms/Ini.php
  94. +288 −9 lib/Lampcms/Interfaces/All.php
  95. +7 −6 lib/Lampcms/Ip.php
  96. +30 −28 lib/Lampcms/Log.php
  97. +18 −11 lib/Lampcms/LoginForm.php
  98. +11 −20 lib/Lampcms/Mailer.php
  99. +377 −0 lib/Lampcms/Modules/Blogger/ApiClient.php
  100. +192 −0 lib/Lampcms/Modules/Blogger/BloggerPostAdapter.php
  101. +140 −0 lib/Lampcms/Modules/Blogger/Blogs.php
  102. +225 −0 lib/Lampcms/Modules/Blogger/Entry.php
  103. +75 −0 lib/Lampcms/Modules/Blogger/EntryInterface.php
  104. +207 −0 lib/Lampcms/Modules/Blogger/PostBlogger.php
  105. +56 −39 lib/Lampcms/Modules/Observers/EmailNotifier.php
  106. +8 −2 lib/Lampcms/Modules/Observers/FloodCheck.php
  107. +1 −2 lib/Lampcms/Modules/Observers/IpFilter.php
  108. +258 −0 lib/Lampcms/Modules/Observers/PostFacebook.php
  109. +226 −0 lib/Lampcms/Modules/Observers/PostTweet.php
  110. +1 −1 lib/Lampcms/Modules/Observers/Similars.php
  111. +2 −9 lib/Lampcms/Modules/Search/IndexerMySQL.php
  112. +3 −4 lib/Lampcms/Modules/Search/MySQL.php
  113. +2 −3 lib/Lampcms/{ → Modules/Search}/TitleTagsTable.php
  114. +341 −0 lib/Lampcms/Modules/Tumblr/ApiClient.php
  115. +205 −0 lib/Lampcms/Modules/Tumblr/PostTumblr.php
  116. +183 −0 lib/Lampcms/Modules/Tumblr/TumblrContent.php
  117. +215 −0 lib/Lampcms/Modules/Tumblr/TumblrPost.php
  118. +188 −0 lib/Lampcms/Modules/Tumblr/TumblrPostAdapter.php
Sorry, we could not display the entire diff because it was too big.
View
81 Mycollections.php.dist
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * License, TERMS and CONDITIONS
+ *
+ * This software is lisensed under the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) version 3
+ * Please read the license here : http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * ATTRIBUTION REQUIRED
+ * 4. All web pages generated by the use of this software, or at least
+ * the page that lists the recent questions (usually home page) must include
+ * a link to the http://www.lampcms.com and text of the link must indicate that
+ * the website\'s Questions/Answers functionality is powered by lampcms.com
+ * An example of acceptable link would be "Powered by <a href="http://www.lampcms.com">LampCMS</a>"
+ * The location of the link is not important, it can be in the footer of the page
+ * but it must not be hidden by style attibutes
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This product includes GeoLite data created by MaxMind,
+ * available from http://www.maxmind.com/
+ *
+ *
+ * @author Dmitri Snytkine <cms@lampcms.com>
+ * @copyright 2005-2011 (or current year) ExamNotes.net inc.
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE (LGPL) version 3
+ * @link http://www.lampcms.com Lampcms.com project
+ * @version Release: @package_version@
+ *
+ *
+ */
+
+
+namespace Lampcms\My;
+
+/**
+ * This is not a class!
+ *
+ * The purpose of this file
+ * is to define custom
+ * Mongo Collections YOU may have created for your custom modules
+ * By default there are no values here but this file is still required!
+ *
+ * Look in lib/Lampcms/Mongo/Collections for actual file and how
+ * the actual entries look like.
+ *
+ * @author Dmitri Snytkine
+ *
+ */
+
+
+
+/**
+ * Example: If you create custom module
+ * and it requires Mongo collection named MYSTUFF
+ * then you would have an entry like the one below
+ * (but it would not be commented out of cause)
+ *
+ *
+ */
+// const MYSTUFF = 'MYSTUFF';
+
View
64 lib/Lampcms/Points.php → Points.php.dist
@@ -20,7 +20,7 @@
* 4. All web pages generated by the use of this software, or at least
* the page that lists the recent questions (usually home page) must include
* a link to the http://www.lampcms.com and text of the link must indicate that
- * the website's Questions/Answers functionality is powered by lampcms.com
+ * the website\'s Questions/Answers functionality is powered by lampcms.com
* An example of acceptable link would be "Powered by <a href="http://www.lampcms.com">LampCMS</a>"
* The location of the link is not important, it can be in the footer of the page
* but it must not be hidden by style attibutes
@@ -53,7 +53,9 @@
namespace Lampcms;
/**
- * Constants of reputation point per action performed
+ * Constants of reputation points per action performed
+ * as well as points required to perform certain actions
+ *
*
* @author Dmitri Snytkine
*
@@ -67,20 +69,23 @@ class Points
*/
const UPVOTE_Q = 5;
+
/**
*
* Someone voted for your answer
* @var int
*/
const UPVOTE_A = 10;
+
/**
*
* Someone accepted your answer as best answer
* @var int
*/
const BEST_ANSWER = 15;
+
/**
*
* You accepted someones answer to your question
@@ -96,18 +101,71 @@ class Points
*/
const CAST_DOWNVOTE = -1;
+
/**
*
* Someone voted down your answer or question
* @var int
*/
const DOWNVOTE = -2;
-
+
+
/**
* Your Q or A received marked as offensive 5 times
* @var int
*/
const OFFENSIVE = -100;
+ /**
+ * User shared (posted)
+ * Question or Answer to external site
+ * via API (like Twitter or Facebook)
+ * Enter description here ...
+ * @var unknown_type
+ */
+ const SHARED_CONTENT = 5;
+
+
+ /**
+ * REPUTATION ACL LEVELS BELOW!
+ */
+
+ /**
+ * need this many points to retag other
+ * user's question
+ *
+ * @var int
+ */
+ const RETAG = 500;
+
+ /**
+ * Need this many points to upvote
+ *
+ * @var int
+ */
+ const VOTE_UP = 15;
+
+ /**
+ * Need this many points to downvote
+ *
+ * @var int
+ */
+ const VOTE_DOWN = 125;
+ /**
+ * Need this many point to edit
+ * Other user's content
+ * Enter description here ...
+ * @var int
+ */
+ const EDIT = 2000;
+
+ /**
+ * Need this many points to
+ * Comment of other user's Question or Answer
+ *
+ * @var int
+ */
+ const COMMENT = 25;
+
}
View
2 RewriteRules.txt
@@ -44,3 +44,5 @@ RewriteRule ^/([a-zA-Z\-]+)/page([0-9]+)\.html$ /index.php?a=$1&pageID=$2
RewriteRule ^/aa/([0-9]+)/([a-f0-9]+)$ /index.php?a=activate&eid=$1&hash=$2
RewriteRule ^/([a-zA-Z\-]+)/$ /index.php?a=$1
RewriteRule ^/search/(m|r)/(.*)/page([0-9]+)\.html$ /index.php?a=search&ord=$1&q=$2&pageID=$3
+RewriteRule ^/tab/(a|q)/([0-9]+)/([a-zA-Z]+)/page([0-9]+)\.html$ /index.php?a=userinfotab&tab=$1&uid=$2&sort=$3&pageID=$4 [L]
+RewriteRule ^/editprofile/([0-9]+) /index.php?a=editprofile&uid=$1 [L]
View
5 acl.ini
@@ -12,6 +12,7 @@ view_question = A
view_answers = A
view_comments = A
login = A
+read = A
;
;unregistered on not logged in user
@@ -76,6 +77,7 @@ unban_user = A
close_question = A
edit_any_comment = A
+
;
;can do most of the things
@@ -99,7 +101,7 @@ ban_user = A
shred_user = A
change_user_role = A
make_sticky = A
-
+edit_any_profile = A
;
;user caught spamming
@@ -146,4 +148,3 @@ register_email = A
[unactivated_external]
parent_id = registered
-;
View
150 acl.ini.dist
@@ -0,0 +1,150 @@
+; Access control config
+; this file has a format of php .ini file
+; IMPORTANT: keep this outsite the web dir
+; This file should never be accessible with a browser
+;
+; Normally you don't have to edit this file
+; unless new permission types are added
+
+; base group, every group inherits from it
+[everyone]
+view_question = A
+view_answers = A
+view_comments = A
+login = A
+read = A
+
+;
+;unregistered on not logged in user
+[guest]
+parent_id = everyone
+register = A
+ask = D
+answer = D
+comment = D
+vote = D
+accept = D
+
+
+;
+;users who registered but not yet confirmed email address
+[unactivated]
+parent_id = everyone
+register = A
+edit_profile = A
+register_email = A
+ask = D
+answer = D
+comment = D
+
+
+;
+;regular member
+[registered]
+parent_id = everyone
+register = D
+change_password = A
+edit_profile = A
+add_blog_post = A
+post_by_email = A
+ask = A
+answer = A
+comment = D
+vote = A
+accept = A
+
+
+
+;
+;regular member
+[virtual]
+parent_id = registered
+
+;
+;can moderate some resources
+;but still needs specific permissions on resource
+[moderator]
+parent_id = registered
+edit_question = A
+edit_answer = A
+delete_question = A
+delete_answer = A
+delete_comment = A
+retag = A
+comment = A
+ban_user = A
+unban_user = A
+close_question = A
+edit_any_comment = A
+
+
+
+;
+;can do most of the things
+[administrator]
+parent_id = moderator
+register = D
+change_password = A
+edit_profile = A
+add_blog_post = A
+post_by_email = A
+ask = A
+answer = A
+comment = A
+rate_question = A
+rate_answer = A
+accept = A
+rate = A
+delete_question = A
+delete_answer = A
+ban_user = A
+shred_user = A
+change_user_role = A
+make_sticky = A
+edit_any_profile = A
+
+;
+;user caught spamming
+[spammer]
+parent_id = registered
+ask = D
+answer = D
+comment = D
+
+
+;
+;user privileges suspended
+[suspended]
+parent_id = everyone
+register = D
+ask = D
+answer = D
+comment = D
+vote = D
+accept = D
+
+;
+;user account marked as deleted
+[deleted]
+register = D
+ask = D
+answer = D
+comment = D
+vote = D
+accept = D
+login = D
+
+;
+;Users without email address.
+;Usually they joined with 3rd party auth like Twitter
+;or FriendConnect
+[external_auth]
+parent_id = registered
+register_email = A
+
+
+; external user who has not confirmed
+; an email address
+[unactivated_external]
+parent_id = registered
+
View
103 autoload.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * License, TERMS and CONDITIONS
+ *
+ * This software is lisensed under the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) version 3
+ * Please read the license here : http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * ATTRIBUTION REQUIRED
+ * 4. All web pages generated by the use of this software, or at least
+ * the page that lists the recent questions (usually home page) must include
+ * a link to the http://www.lampcms.com and text of the link must indicate that
+ * the website\'s Questions/Answers functionality is powered by lampcms.com
+ * An example of acceptable link would be "Powered by <a href="http://www.lampcms.com">LampCMS</a>"
+ * The location of the link is not important, it can be in the footer of the page
+ * but it must not be hidden by style attibutes
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This product includes GeoLite data created by MaxMind,
+ * available from http://www.maxmind.com/
+ *
+ *
+ * @author Dmitri Snytkine <cms@lampcms.com>
+ * @copyright 2005-2011 (or current year) ExamNotes.net inc.
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE (LGPL) version 3
+ * @link http://www.lampcms.com Lampcms.com project
+ * @version Release: @package_version@
+ *
+ *
+ */
+
+
+
+/**
+ * Autoloader for vtemplates
+ *
+ * @param string $classname
+ */
+function templateLoader($className){
+
+
+ /**
+ * This is important
+ * This autoloader will be the first
+ * one in the __autoload stack (we pass true as 3rd arg
+ * to spl_autoload_register())
+ *
+ * Since this autoload can only
+ * handle template files, any file
+ * not starting with 'tpl' is not
+ * the responsibility of this loader
+ * and we must return false to save further
+ * pointless processing.
+ */
+ if(0 !== strpos($className, 'tpl') ){
+
+ return false;
+ }
+
+ $styleId = (defined('STYLE_ID')) ? STYLE_ID : '1';
+ $dir = (defined('VTEMPLATES_DIR')) ? VTEMPLATES_DIR : 'www';
+
+ $file = LAMPCMS_WWW_DIR.'style'.DIRECTORY_SEPARATOR.STYLE_ID.DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.$className.'.php';
+
+ /**
+ * Smart fallback to www dir
+ * if template does not exist in mobile version
+ * But if template file also does not exist in www
+ * and in mobile dir, then it will raise an error
+ * beause we using require this time instead in include && ('www' !== $dir)
+ */
+ if( ( false === include($file)) && ('www' !== $dir) ){
+
+ require LAMPCMS_WWW_DIR.'style'.DIRECTORY_SEPARATOR.STYLE_ID.DIRECTORY_SEPARATOR.'www'.DIRECTORY_SEPARATOR.$className.'.php';
+ }
+
+ return true;
+}
+
+
+$oLoader = new Lampcms\SplClassLoader(null, $libDir);
+$oLoader->register();
+spl_autoload_register('templateLoader', false, true);
View
203 config.ini
@@ -10,6 +10,16 @@ Persistent = 0
[MONGO]
server = "mongodb://127.0.0.2:27017"
db = "LAMPCMS"
+; If you already have existing
+; Mongo Database with existing collections
+; you may want to set the prefix
+; all collections used by this program will
+; be prefixed with this word.
+; For example you may set prefix to "Lampcms"
+; then collection USERS will become LampcmsUSERS
+; This will take care of possible name collisions with
+; existing collections
+prefix = ""
[CACHE_MONGO]
; good option to use the same db as in "MONGO" section
@@ -20,6 +30,31 @@ collection = "C_Cache"
; set to true when debugging to enable
; debug log and raize error reporting level
DEBUG = true
+;
+; Minimum number of tags question must have
+; set to 0 to make tags optional
+;
+MIN_QUESTION_TAGS = 1
+;
+; Maximum number of tags Question can have
+; This will be enforced when question is submitted
+; and when question is retagged
+MAX_QUESTION_TAGS = 5
+;
+; Minimun length of question in chars
+MIN_QUESTION_CHARS = 10
+;
+; Minimum required length of question title
+MIN_TITLE_CHARS = 10
+;
+; Minimum number of words required in question
+MIN_QUESTION_WORDS = 3
+;
+; Minimum length of answer in chars
+MIN_ANSWER_CHARS = 10
+;
+; Minimum number of words required for answer
+MIN_ANSWER_WORDS = 3
; maximum commets per item
; set to 0 to disable comments feature
MAX_COMMENTS = 20
@@ -68,7 +103,7 @@ SERVER_TIMEZONE = America/Chicago
;
SKIP_CACHE = false
;
-;Leave at null unless
+;Leave blank unless
;you need to set cookie under some
;global domain.
;For example if your Q and A site is on
@@ -77,11 +112,13 @@ SKIP_CACHE = false
;of oursite.com, then you
;should set this value
;
-COOKIE_DOMAIN = null
+COOKIE_DOMAIN =
;
-;system path to temporary directory. Must we writable to php
+; system path to temporary directory. Must we writable to php
+; if not sure - leave blank
+;
;
-TEMP_DIR = /tmp
+TEMP_DIR =
;
;Some configuration constants
;Leave black if you host images, css and js
@@ -93,12 +130,20 @@ IMAGE_SITE = ""
CSS_SITE = ""
JS_SITE = ""
AVATAR_IMG_SITE = ""
-;site of square avatar in pixels
+;size of square avatar in pixels
AVATAR_SQUARE_SIZE= 40
+;maximum allowed file size of
+; uploaded avatar in bytes.
+; default 1000000 means 1MB
+MAX_AVATAR_UPLOAD_SIZE = 1024000
+;
;
;Name of GeoIP file - must be in the LAMPCMS_DIR (root dir of program)
-;Download it from maxmind.com
-;http://www.maxmind.com/app/geolitecity
+;Download it from maxmind.com and save as GeoLiteCity.dat
+;
+; http://www.maxmind.com/app/geolitecity
+;
+; Or leave value of GEOIP_FILE blank to disable GeoIP lookup
;
GEOIP_FILE = GeoLiteCity.dat
;
@@ -127,18 +172,24 @@ POSTFIX_PATH = /usr/sbin/sendmail
; email address of developer.
; Developer will be notified of php errors and various bad situations on the site //message@ptd.net
EMAIL_DEVELOPER = "me@me.me"
-; email address of admin. Admin will also be notified on important events and errors
+; email address of admin. Required value!
+; Admin will also be notified on important events and errors
EMAIL_ADMIN = "me@me.me"
;
-; emails to new registrations sent from this domain
+;
+; Emails to new registrations sent from this domain
+; Required value!
EMAIL_DOMAIN =
+;
+; SALT is Required value!
; Make sure to set the value of SALT to a random string of about 40 chars
; then write it down and store it like gold!
; and never change it again!
; if it's lost, you will not be able to authenticate
; any existing users - users will never be able to login!
SALT = 'abcdefg';
-
+;
+; COOKIE_SALT is Required value
;Enter some random string BEFORE launching your site
;but DONT EVER CHANGE IT AFTER
;you launched your site, otherwise users will not be
@@ -169,6 +220,25 @@ GFC_ID =
; to disable autocomplete
;
DISABLE_AUTOCOMPLETE = false
+;
+; Add "Code editor" tools to RTE Editor
+; This is very useful for programming - related Q&A Sites
+; but totally unnecessary for non-programming sites,
+; so it's disabled by default
+ENABLE_CODE_EDITOR = false;
+; Options of RTE Editor
+[EDITOR]
+;
+; Add "Code editor" tools to RTE Editor
+; This is very useful for programming - related Q&A Sites
+; but totally unnecessary for non-programming sites,
+; so it's disabled by default
+ENABLE_CODE_EDITOR = false;
+;
+; Add "YouTube" button to editor
+; to allow adding youtube videos
+; to Questions and Answers
+ENABLE_YOUTUBE = true;
[CAPTCHA]
; to disable captcha for any reason
@@ -250,12 +320,27 @@ TWITTER_OAUTH_SECRET =
; join
TWITTER_USERNAME =
+[TUMBLR]
+; You must register your app
+; with Tumblr and get OAUTH_KEY and OAUTH_SECRET
+; Go to this url to get yours: http://www.tumblr.com/oauth/apps
+;
+OAUTH_KEY =
+OAUTH_SECRET =
+
[FACEBOOK]
; Get your APP_ID and API_SECRET here:
; http://developers.facebook.com/setup/
; To setup new application and get API_KEY
; go here: http://www.facebook.com/developers/
;
+; IMPORTANT! when settin up your Facebook APP,
+; DO NOT SET value for "Site Domain" - leave it blank
+; otherwise Facebook will be setting cookie using
+; .yourdomain.com and it will be very difficult to delete
+; this cookie unless you also set the exact same value
+; like .yourdomain.com in site file's COOKIE_DOMAIN setting
+;
; user picture is not in any json, its simply this:
; http://graph.facebook.com/$UID/picture
API_KEY =
@@ -266,7 +351,10 @@ APP_SECRET =
; You should require publish_stream also if
; you want to post something to user 'wall'
EXTENDED_PERMS = "email,publish_stream,offline_access"
-POST_TO_WALL = true
+; Enter full url of your site's logo image
+; This should be fairly small image (about 50x50 or so)
+; If set, it will appear on posts to Facebook as an icon
+SITE_LOGO =
; Custom classes that extend LampcmsObserver
; can be listed here and they will be automatically
@@ -284,10 +372,103 @@ POST_TO_WALL = true
ipFilter= "\\Lampcms\\Modules\\Observers\\IpFilter"
floodCheck = "\\Lampcms\\Modules\\Observers\\FloodCheck"
questionSimilar = "\\Lampcms\\Modules\\Observers\\Similars"
+
+; If twitter filter is enabled (not commented out here)
+; then a checkbox to "Post to Twitter" will be
+; added to "Ask" and "Answer" forms
+; Make sure you actually enabled Twitter API integration
+; before enabling this filter otherwise it will not work
+; Check the [TWITTER] section of this file for enabling
+; the Twitter API
+;
+;twitter = "\\Lampcms\\Modules\\Observers\\PostTweet"
+
+; If facebook filter is enabled (not commented out here)
+; then a checkbox to "Post to Twitter" will be
+; added to "Ask" and "Answer" forms
+; Make sure you actually enabled Facebook API integration
+; before enabling this filter otherwise it will not work
+; Check the [FACEBOOK] section of this file for enabling
+; the FACEBOOK API
+;
+;facebook = "\\Lampcms\\Modules\\Observers\\PostFacebook"
+
+; If tumblr filter is enabled (not commented out here)
+; then a checkbox to "Post to Tumblr" will be
+; added to "Ask" and "Answer" forms
+; Make sure you actually enabled Tumblr API integration
+; before enabling this filter otherwise it will not work
+; Check the [TUMBLR] section of this file for enabling
+; the Tumblr API
+;
+;tumblr = "\\Lampcms\\Modules\\Tumblr\\PostTumblr"
+
+; If blogger filter is enabled (not commented out here)
+; then a checkbox to "Post to Blogger" will be
+; added to "Ask" and "Answer" forms
+; Make sure you actually enabled Blogger API integration
+; before enabling this filter otherwise it will not work
+; Check the [BLOGGER] section of this file for enabling
+; the Blogger API
+;
+;blogger = "\\Lampcms\\Modules\\Blogger\\PostBlogger"
+
+; EmailNotifier can take long to run
+; it's best to put this filter as the last filter
+;
EmailNotifier = "\\Lampcms\\Modules\\Observers\\EmailNotifier"
+; bit.ly use used for shortening urls
+; this is useful when posting questions/answers
+; to Twitter.
+; if you not using the Twitter Module then
+; you not going to need this
+;
+; Signup for bit.ly account to get
+; your username and api key
+; go here to get started: http://bit.ly/a/your_api_key
+;
+[BITLY]
+user=
+api_key =
+
[CURL]
; primary ip address from which curl will connect
ip = "127.0.0.1"
; secondary ip address
ip2 = "127.0.0.2"
+
+[BLOGGER]
+; You must do these steps while logged in to Google with you
+; Google account - this is usually the same as your Gmail account
+;
+; To get your blogger API KEY and Secret start here:
+; http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
+;
+; You will need to register your domain with Google.
+; This included downloading some html file from Google
+; then uploading it to root dir of your site and then clicking "verify" button,
+; proving to Google that you are the admin of that domain.
+;
+; Once that is done you need to go here: https://www.google.com/accounts/UpdateDomain
+; and enter some string that you must create yourself -
+; some type of long secret string, into the
+; "Target URL path prefix"
+; That will become your app's OAuth Consumer Key
+; and Google will generate the OAuth Consumer Secret value for you.
+; Then enter the values here
+;
+OAUTH_KEY =
+OAUTH_SECRET =
+
+
+
+[API]
+; Maximum results an API can return per page
+MAX_RESULTS = 100
+; Dalily access limit for not logged in users
+DAILY_LIMIT_ANON = 150
+; Daily access limit for logged in users
+DAILY_LIMIT_APP = 3000
+; Daily limit for authenticated user
+DAILY_LIMIT_USER = 10000
View
91 inc.php
@@ -49,14 +49,15 @@
mb_internal_encoding("UTF-8");
}
-function exception_handler($e)
-{
- echo 'Eeeeee '.$e->getMessage()."\n<br>";
+function exception_handler($e){
+ //echo 'Eeeeee '.$e->getMessage()."\n<br>";
try {
- $strHtml = 'ooopsy... '.Lampcms\Responder::makeErrorPage('<strong>Error:</strong> '.Lampcms\Exception::formatException($e));
+ $err = Lampcms\Responder::makeErrorPage('<strong>Error:</strong> '.Lampcms\Exception::formatException($e));
$extra = (isset($_SERVER)) ? ' $_SERVER: '.print_r($_SERVER, 1) : ' no extra';
- mail(DEVELOPER_EMAIL, 'ErrorHandle in inc.php', $strHtml.$extra);
- exit ($strHtml);
+ if(strlen(trim(constant('DEVELOPER_EMAIL'))) > 1){
+ @mail(DEVELOPER_EMAIL, 'ErrorHandle in inc.php', $err.$extra);
+ }
+ exit ($err);
}catch(\Exception $e) {
echo 'Error in Exception handler: : '.$e->getMessage().' line '.$e->getLine().$e->getTraceAsString();
}
@@ -68,6 +69,7 @@ function exception_handler($e)
*
*/
if(!function_exists('fastcgi_finish_request')){
+ define('NO_FFR', true);
function fastcgi_finish_request(){}
}
@@ -80,6 +82,9 @@ function fastcgi_finish_request(){}
require $lampcmsClasses.'Interfaces'.DIRECTORY_SEPARATOR.'All.php';
require $lampcmsClasses.'Exception.php';
require $lampcmsClasses.'Object.php';
+require $lampcmsClasses.'Responder.php';
+require $lampcmsClasses.'Mongo'.DIRECTORY_SEPARATOR.'Collections.php';
+require LAMPCMS_PATH.DIRECTORY_SEPARATOR.'Mycollections.php';
require $lampcmsClasses.'Ini.php';
require $lampcmsClasses.'Log.php';
require $lampcmsClasses.'Request.php';
@@ -90,6 +95,18 @@ function fastcgi_finish_request(){}
require $lampcmsClasses.'Registry.php';
require $lampcmsClasses.'Template'.DIRECTORY_SEPARATOR.'Template.php';
+/**
+ * Points.php is in non-standard directory,
+ * in fact this file is not even included in distro
+ * User must rename Points.php.dist to Points.php
+ * That's why we should manually included it
+ * because autoloader will not be able to find it.
+ * This file only contains a few constants - it's cheap
+ * to include it every time, and with APC cache it will
+ * be cached.
+ */
+require LAMPCMS_PATH.DIRECTORY_SEPARATOR.'Points.php';
+
/**
@@ -153,59 +170,9 @@ function LampcmsErrorHandler($errno, $errstr, $errfile, $errline)
}
$old_error_handler = set_error_handler("LampcmsErrorHandler");
+// autoloader here
+require 'autoload.php';
-/**
- * Autoloader for vtemplates
- *
- * @param string $classname
- */
-function templateLoader($className){
-
- //d('className: '.$className);
-
- /**
- * This is important
- * This autoloader will be the first
- * one in the __autoload stack (we pass true as 3rd arg
- * to spl_autoload_register())
- *
- * Since this autoload can only
- * handle template files, any file
- * not starting with 'tpl' is not
- * the responsibility of this loader
- * and we must return false to save further
- * pointless processing.
- */
- if(0 !== strpos($className, 'tpl') ){
-
- return false;
- }
-
- $styleId = (defined('STYLE_ID')) ? STYLE_ID : '1';
- $dir = (defined('VTEMPLATES_DIR')) ? VTEMPLATES_DIR : 'www';
-
- $file = LAMPCMS_WWW_DIR.'style'.DIRECTORY_SEPARATOR.STYLE_ID.DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.$className.'.php';
- d('looking for template file : '.$file);
-
- /**
- * Smart fallback to www dir
- * if template does not exist in mobile version
- * But if template file also does not exist in www
- * and in mobile dir, then it will raise an error
- * beause we using require this time instead in include && ('www' !== $dir)
- */
- if( ( false === include($file)) && ('www' !== $dir) ){
- d('Unable to include template file '.$file.' looking if www dir');
-
- require LAMPCMS_WWW_DIR.'style'.DIRECTORY_SEPARATOR.STYLE_ID.DIRECTORY_SEPARATOR.'www'.DIRECTORY_SEPARATOR.$className.'.php';
- }
-
- return true;
-}
-
-$oLoader = new Lampcms\SplClassLoader(null, $libDir);
-$oLoader->register();
-spl_autoload_register('templateLoader', false, true);
$oRegistry = \Lampcms\Registry::getInstance();
try{
@@ -219,9 +186,13 @@ function templateLoader($className){
define('LAMPCMS_SALT', $oINI->SALT);
define('COOKIE_SALT', $oINI->COOKIE_SALT);
define('DEFAULT_LANG', $oINI->DEFAULT_LANG);
- define('COOKIE_DOMAIN', $oINI->COOKIE_DOMAIN);
+ define('COOKIE_DOMAIN', $oINI->COOKIE_DOMAIN );
define('IMAGE_SITE', $oINI->IMAGE_SITE);
- define('GEOIP_FILE', $oINI->GEOIP_FILE);
+ $geofile = trim($oINI->GEOIP_FILE);
+ if(!empty($geofile)){
+ define('GEOIP_FILE', $geofile);
+ }
+
define('AVATAR_IMG_SITE', $oINI->AVATAR_IMG_SITE);
if (!empty($dataDir)) {
View
107 lib/Lampcms/Acl/Acl.php
@@ -126,8 +126,7 @@ class Acl implements \Serializable
* via allow() or deny() methods
*
*/
- public function __construct()
- {
+ public function __construct(){
$iniFile = LAMPCMS_PATH.DIRECTORY_SEPARATOR.'acl.ini';
@@ -201,8 +200,7 @@ public function __construct()
* @uses RoleRegistry::add()
* @return object $this
*/
- public function addRole($role, $parents = null)
- {
+ public function addRole($role, $parents = null){
if (is_string($role)) {
$role = new Role($role);
}
@@ -228,11 +226,11 @@ public function addRole($role, $parents = null)
* @uses RoleRegistry::get()
* @return AclRole
*/
- public function getRole($role)
- {
+ public function getRole($role){
return $this->_getRoleRegistry()->get($role);
}
+
/**
* Returns true if and only if the Role exists in the registry
*
@@ -242,11 +240,11 @@ public function getRole($role)
* @uses RoleRegistry::has()
* @return boolean
*/
- public function hasRole($role)
- {
+ public function hasRole($role){
return $this->_getRoleRegistry()->has($role);
}
+
/**
* Returns true if and only if $role inherits from $inherit
*
@@ -262,11 +260,11 @@ public function hasRole($role)
* @uses RoleRegistry::inherits()
* @return boolean
*/
- public function inheritsRole($role, $inherit, $onlyParents = false)
- {
+ public function inheritsRole($role, $inherit, $onlyParents = false){
return $this->_getRoleRegistry()->inherits($role, $inherit, $onlyParents);
}
+
/**
* Removes the Role from the registry
*
@@ -276,8 +274,7 @@ public function inheritsRole($role, $inherit, $onlyParents = false)
* @uses RoleRegistry::remove()
* @return Acl Provides a fluent interface
*/
- public function removeRole($role)
- {
+ public function removeRole($role){
$this->_getRoleRegistry()->remove($role);
if ($role instanceof RoleInterface) {
@@ -304,14 +301,14 @@ public function removeRole($role)
return $this;
}
+
/**
* Removes all Roles from the registry
*
* @uses RoleRegistry::removeAll()
* @return Acl Provides a fluent interface
*/
- public function removeRoleAll()
- {
+ public function removeRoleAll(){
$this->_getRoleRegistry()->removeAll();
foreach ($this->_rules['allResources']['byRoleId'] as $roleIdCurrent => $rules) {
@@ -326,6 +323,7 @@ public function removeRoleAll()
return $this;
}
+
/**
* Adds a Resource having an identifier unique to the ACL
*
@@ -337,9 +335,7 @@ public function removeRoleAll()
* @throws AclException
* @return Acl Provides a fluent interface
*/
- public function addResource(Resource $resource, $parent = null)
- {
-
+ public function addResource(Resource $resource, $parent = null){
$resourceId = $resource->getResourceId();
@@ -383,8 +379,7 @@ public function addResource(Resource $resource, $parent = null)
* @throws AclException
* @return ResourceInterface
*/
- public function get($resource)
- {
+ public function get($resource){
if ($resource instanceof Resource) {
$resourceId = $resource->getResourceId();
} else {
@@ -399,6 +394,7 @@ public function get($resource)
return $this->_resources[$resourceId]['instance'];
}
+
/**
* Returns true if and only if the Resource exists in the ACL
*
@@ -407,8 +403,7 @@ public function get($resource)
* @param ResourceInterface|string $resource
* @return boolean
*/
- public function has($resource)
- {
+ public function has($resource){
if ($resource instanceof Resource) {
$resourceId = $resource->getResourceId();
} else {
@@ -418,6 +413,7 @@ public function has($resource)
return isset($this->_resources[$resourceId]);
}
+
/**
* Returns true if and only if $resource inherits from $inherit
*
@@ -433,8 +429,7 @@ public function has($resource)
* @throws AclException
* @return boolean
*/
- public function inherits($resource, $inherit, $onlyParent = false)
- {
+ public function inherits($resource, $inherit, $onlyParent = false){
try {
$resourceId = $this->get($resource)->getResourceId();
$inheritId = $this->get($inherit)->getResourceId();
@@ -463,6 +458,7 @@ public function inherits($resource, $inherit, $onlyParent = false)
return false;
}
+
/**
* Removes a Resource and all of its children
*
@@ -472,8 +468,7 @@ public function inherits($resource, $inherit, $onlyParent = false)
* @throws AclException
* @return Acl Provides a fluent interface
*/
- public function remove(Resource $resource)
- {
+ public function remove(Resource $resource){
try {
$resourceId = $this->get($resource)->getResourceId();
} catch (AclException $e) {
@@ -502,13 +497,13 @@ public function remove(Resource $resource)
return $this;
}
+
/**
* Removes all Resources
*
* @return Acl Provides a fluent interface
*/
- public function removeAll()
- {
+ public function removeAll(){
foreach ($this->_resources as $resourceId => $resource) {
foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $rules) {
if ($resourceId === $resourceIdCurrent) {
@@ -522,6 +517,7 @@ public function removeAll()
return $this;
}
+
/**
* Adds an "allow" rule to the ACL
*
@@ -531,11 +527,11 @@ public function removeAll()
* @param Assert Interface $assert
* @return Acl Provides
*/
- public function allow($roles = null, $resources = null, $privileges = null, Assert $assert = null)
- {
+ public function allow($roles = null, $resources = null, $privileges = null, Assert $assert = null){
return $this->setRule(self::OP_ADD, self::TYPE_ALLOW, $roles, $resources, $privileges, $assert);
}
+
/**
* Adds a "deny" rule to the ACL
*
@@ -546,11 +542,11 @@ public function allow($roles = null, $resources = null, $privileges = null, Asse
* @uses Acl::setRule()
* @return Acl Provides a fluent interface
*/
- public function deny($roles = null, $resources = null, $privileges = null, Assert $assert = null)
- {
+ public function deny($roles = null, $resources = null, $privileges = null, Assert $assert = null){
return $this->setRule(self::OP_ADD, self::TYPE_DENY, $roles, $resources, $privileges, $assert);
}
+
/**
* Removes "allow" permissions from the ACL
*
@@ -560,11 +556,11 @@ public function deny($roles = null, $resources = null, $privileges = null, Asser
* @uses Acl::setRule()
* @return Acl Provides a fluent interface
*/
- public function removeAllow($roles = null, $resources = null, $privileges = null)
- {
+ public function removeAllow($roles = null, $resources = null, $privileges = null){
return $this->setRule(self::OP_REMOVE, self::TYPE_ALLOW, $roles, $resources, $privileges);
}
+
/**
* Removes "deny" restrictions from the ACL
*
@@ -574,11 +570,11 @@ public function removeAllow($roles = null, $resources = null, $privileges = null
* @uses Acl::setRule()
* @return Acl Provides a fluent interface
*/
- public function removeDeny($roles = null, $resources = null, $privileges = null)
- {
+ public function removeDeny($roles = null, $resources = null, $privileges = null){
return $this->setRule(self::OP_REMOVE, self::TYPE_DENY, $roles, $resources, $privileges);
}
+
/**
* Performs operations on ACL rules
*
@@ -632,8 +628,7 @@ public function removeDeny($roles = null, $resources = null, $privileges = null)
* @return Acl Provides a fluent interface
*/
public function setRule($operation, $type, $roles = null, $resources = null, $privileges = null,
- Assert $assert = null)
- {
+ Assert $assert = null){
// ensure that the rule type is valid; normalize input to uppercase
$type = strtoupper($type);
if (self::TYPE_ALLOW !== $type && self::TYPE_DENY !== $type) {
@@ -751,6 +746,7 @@ public function setRule($operation, $type, $roles = null, $resources = null, $pr
return $this;
}
+
/**
* Returns true if and only if the Role has access to the Resource
*
@@ -779,8 +775,7 @@ public function setRule($operation, $type, $roles = null, $resources = null, $pr
* @uses RoleRegistry::get()
* @return boolean
*/
- public function isAllowed($role = null, $resource = null, $privilege = null)
- {
+ public function isAllowed($role = null, $resource = null, $privilege = null){
// reset role & resource to null
$this->_isAllowedRole = $this->_isAllowedResource = null;
@@ -848,6 +843,7 @@ public function isAllowed($role = null, $resource = null, $privilege = null)
}
}
+
/**
* Returns the Role registry for this ACL
*
@@ -856,14 +852,14 @@ public function isAllowed($role = null, $resource = null, $privilege = null)
*
* @return AclRoleRegistry
*/
- protected function _getRoleRegistry()
- {
+ protected function _getRoleRegistry(){
if (null === $this->_roleRegistry) {
$this->_roleRegistry = new RoleRegistry();
}
return $this->_roleRegistry;
}
+
/**
* Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule
* allowing/denying $role access to all privileges upon $resource
@@ -875,8 +871,7 @@ protected function _getRoleRegistry()
* @param ResourceInterface $resource
* @return boolean|null
*/
- protected function _roleDFSAllPrivileges(RoleInterface $role, Resource $resource = null)
- {
+ protected function _roleDFSAllPrivileges(RoleInterface $role, Resource $resource = null){
$dfs = array(
'visited' => array(),
'stack' => array()
@@ -897,6 +892,7 @@ protected function _roleDFSAllPrivileges(RoleInterface $role, Resource $resource
return null;
}
+
/**
* Visits an $role in order to look for a rule allowing/denying $role access to all privileges upon $resource
*
@@ -911,8 +907,7 @@ protected function _roleDFSAllPrivileges(RoleInterface $role, Resource $resource
* @return boolean|null
* @throws AclException
*/
- protected function _roleDFSVisitAllPrivileges(RoleInterface $role, Resource $resource = null, &$dfs = null)
- {
+ protected function _roleDFSVisitAllPrivileges(RoleInterface $role, Resource $resource = null, &$dfs = null){
if (null === $dfs) {
throw new AclException('$dfs parameter may not be null');
@@ -937,6 +932,7 @@ protected function _roleDFSVisitAllPrivileges(RoleInterface $role, Resource $res
return null;
}
+
/**
* Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule
* allowing/denying $role access to a $privilege upon $resource
@@ -950,8 +946,7 @@ protected function _roleDFSVisitAllPrivileges(RoleInterface $role, Resource $res
* @return boolean|null
* @throws AclException
*/
- protected function _roleDFSOnePrivilege(RoleInterface $role, Resource $resource = null, $privilege = null)
- {
+ protected function _roleDFSOnePrivilege(RoleInterface $role, Resource $resource = null, $privilege = null){
if (null === $privilege) {
throw new AclException('$privilege parameter may not be null');
@@ -977,6 +972,7 @@ protected function _roleDFSOnePrivilege(RoleInterface $role, Resource $resource
return null;
}
+
/**
* Visits an $role in order to look for a rule allowing/denying $role access to a $privilege upon $resource
*
@@ -993,8 +989,7 @@ protected function _roleDFSOnePrivilege(RoleInterface $role, Resource $resource
* @throws AclException
*/
protected function _roleDFSVisitOnePrivilege(RoleInterface $role, Resource $resource = null,
- $privilege = null, &$dfs = null)
- {
+ $privilege = null, &$dfs = null){
if (null === $privilege) {
/**
* @see AclException
@@ -1023,6 +1018,7 @@ protected function _roleDFSVisitOnePrivilege(RoleInterface $role, Resource $reso
return null;
}
+
/**
* Returns the rule type associated with the specified Resource, Role, and privilege
* combination.
@@ -1044,8 +1040,7 @@ protected function _roleDFSVisitOnePrivilege(RoleInterface $role, Resource $reso
* @param string $privilege
* @return string|null
*/
- protected function _getRuleType(Resource $resource = null, RoleInterface $role = null, $privilege = null)
- {
+ protected function _getRuleType(Resource $resource = null, RoleInterface $role = null, $privilege = null){
// get the rules for the $resource and $role
if (null === ($rules = $this->_getRules($resource, $role))) {
return null;
@@ -1086,6 +1081,7 @@ protected function _getRuleType(Resource $resource = null, RoleInterface $role =
}
}
+
/**
* Returns the rules associated with a Resource and a Role, or null if no such rules exist
*
@@ -1099,8 +1095,7 @@ protected function _getRuleType(Resource $resource = null, RoleInterface $role =
* @param boolean $create
* @return array|null
*/
- protected function &_getRules(Resource $resource = null, RoleInterface $role = null, $create = false)
- {
+ protected function &_getRules(Resource $resource = null, RoleInterface $role = null, $create = false){
// create a reference to null
$null = null;
$nullRef =& $null;
@@ -1147,8 +1142,7 @@ protected function &_getRules(Resource $resource = null, RoleInterface $role = n
* @return array of registered roles
*
*/
- public function getRegisteredRoles()
- {
+ public function getRegisteredRoles(){
return $this->_getRoleRegistry()->getRoles();
}
@@ -1166,8 +1160,7 @@ public function serialize(){
}
- public function unserialize($serialized)
- {
+ public function unserialize($serialized){
$a = unserialize($serialized);
$this->_resources = $a['resources'];
$this->_getRoleRegistry()->setRoles($a['roles']);
View
18 lib/Lampcms/Acl/Role.php
@@ -34,8 +34,7 @@ class Role implements RoleInterface
* @param string $id
* @return void
*/
- public function __construct($roleId)
- {
+ public function __construct($roleId){
$this->_roleId = (string)$roleId;
}
@@ -44,9 +43,20 @@ public function __construct($roleId)
*
* @return string
*/
- public function getRoleId()
- {
+ public function getRoleId(){
return $this->_roleId;
}
+
+ /**
+ * This method was not originally in
+ * Zend_Acl library
+ * Added by Dmitri Snytkine specifically for
+ * Lampcms project
+ * (non-PHPdoc)
+ * @see Lampcms\Interfaces.RoleInterface::setRoleId()
+ */
+ public function setRoleId($role){
+ $this->_roleId = $role;
+ }
}
View
169 lib/Lampcms/Answer.php
@@ -64,8 +64,8 @@
class Answer extends MongoDoc implements Interfaces\Answer, Interfaces\UpDownRatable, Interfaces\CommentedResource
{
- public function __construct(Registry $oRegistry, array $a = array()){
-
+ public function __construct(Registry $oRegistry, array $a = null){
+ $a = ($a) ? $a : array();
parent::__construct($oRegistry, 'ANSWERS', $a);
}
@@ -86,8 +86,7 @@ public function getResourceTypeId(){
* @return object $this
*/
public function setAccepted(){
- $this->offsetSet('accepted', true);
- $this->touch();
+ parent::offsetSet('accepted', true);
return $this;
}
@@ -99,8 +98,7 @@ public function setAccepted(){
* @return object $this
*/
public function unsetAccepted(){
- $this->offsetSet('accepted', false);
- $this->touch();
+ parent::offsetSet('accepted', false);
return $this;
}
@@ -150,8 +148,12 @@ public function getUsername(){
*/
public function setDeleted(User $user, $reason = null){
if(0 === $this->getDeletedTime()){
- $this->offsetSet('i_del_ts', time());
- $this->offsetSet('a_deleted',
+ if($reason){
+ $reason = \strip_tags((string)$reason);
+ }
+
+ parent::offsetSet('i_del_ts', time());
+ parent::offsetSet('a_deleted',
array(
'username' => $user->getDisplayName(),
'i_uid' => $user->getUid(),
@@ -160,8 +162,6 @@ public function setDeleted(User $user, $reason = null){
'hts' => date('F j, Y g:i a T')
)
);
-
- $this->touch();
}
return $this;
@@ -178,6 +178,9 @@ public function setDeleted(User $user, $reason = null){
* @return object $this
*/
public function setEdited(User $user, $reason = ''){
+ if(!empty($reason)){
+ $reason = \strip_tags((string)$reason);
+ }
$aEdited = $this->offsetGet('a_edited');
if(empty($aEdited) || !is_array($aEdited)){
@@ -191,9 +194,7 @@ public function setEdited(User $user, $reason = ''){
'reason' => $reason,
'hts' => date('F j, Y g:i a T'));
- $this->offsetSet('a_edited', $aEdited);
-
- $this->touch();
+ parent::offsetSet('a_edited', $aEdited);
return $this;
}
@@ -246,14 +247,14 @@ public function addUpVote($inc = 1){
$score = (int)$this->offsetGet('i_votes');
$total = ($score + $inc);
- $this->offsetSet('i_up', max(0, ($tmp + $inc)) );
- $this->offsetSet('i_votes', $total );
+ parent::offsetSet('i_up', max(0, ($tmp + $inc)) );
+ parent::offsetSet('i_votes', $total );
/**
* Plural extension handling
*/
$v_s = (1 === abs($total) ) ? '' : 's';
- $this->offsetSet('v_s', $v_s);
+ parent::offsetSet('v_s', $v_s);
return $this;
}
@@ -273,14 +274,14 @@ public function addDownVote($inc = 1){
$score = (int)$this->offsetGet('i_votes');
$total = ($score - $inc);
- $this->offsetSet('i_down', max(0, ($tmp + $inc)) );
- $this->offsetSet('i_votes', $total);
+ parent::offsetSet('i_down', max(0, ($tmp + $inc)) );
+ parent::offsetSet('i_votes', $total);
/**
* Plural extension handling
*/
$v_s = (1 === abs($total) ) ? '' : 's';
- $this->offsetSet('v_s', $v_s);
+ parent::offsetSet('v_s', $v_s);
return $this;
}
@@ -310,6 +311,7 @@ public function getScore(){
return $this->offsetGet('i_votes');
}
+
/**
* Get full (absolute) url for this question,
* including the http and our domain
@@ -322,18 +324,61 @@ public function getScore(){
*
* @return string url for this question
*/
- public function getUrl(){
+ public function getUrl($short = false){
return $this->oRegistry->Ini->SITE_URL.'/q'.$this->offsetGet('i_qid').'/#ans'.$this->offsetGet('_id');
}
/**
* (non-PHPdoc)
+ * @see Lampcms\Interfaces.Post::getBody()
+ */
+ public function getBody(){
+ return $this->offsetGet('b');
+ }
+
+
+ /**
+ * (non-PHPdoc)
+ * @see Lampcms\Interfaces.Post::getTitle()
+ */
+ public function getTitle(){
+ return $this->offsetGet('title');
+ }
+
+
+ /**
+ * (non-PHPdoc)
+ * @see Lampcms\Interfaces.Post::getSeoUrl()
+ */
+ public function getSeoUrl(){
+ return '';
+ }
+
+
+ /**
+ * (non-PHPdoc)
* @see Lampcms\Interfaces.CommentedResource::addComment()
*/
public function addComment(CommentParser $oComment){
- $aKeys = array('_id', 'i_uid', 'i_prnt', 'username', 'avtr', 'b_owner', 'b', 't', 'ts');
+ $aKeys = array(
+ '_id',
+ 'i_uid',
+ 'i_prnt',
+ 'username',
+ 'avtr',
+ 'b_owner',
+ 'b',
+ 't',
+ 'ts',
+ 'cc',
+ 'cn',
+ 'reg',
+ 'city',
+ 'zip',
+ 'lat',
+ 'lon');
$aComments = $this->getComments();
d('aComments: '.print_r($aComments, 1));
@@ -343,11 +388,11 @@ public function addComment(CommentParser $oComment){
* because we don't need them here
*/
$aComment = $oComment->getArrayCopy();
- $aComment = array_intersect_key($aComment, array_flip($aKeys));
+ $aComment = \array_intersect_key($aComment, array_flip($aKeys));
$aComments[] = $aComment;
- $this->offsetSet('comments', $aComments);
+ $this->offsetSet('a_comments', $aComments);
$this->increaseCommentsCount();
return $this;
@@ -368,16 +413,29 @@ public function getCommentsCount(){
/**
*
- * Enter description here ...
+ * Increase value of i_comments by 1
+ * The i_comments is a counter
+ *
+ * @return object $this
*/
- public function increaseCommentsCount(){
+ public function increaseCommentsCount($count = 1){
+ if(!is_int($count)){
+ throw new \InvalidArgumentException('$count must be integer. was: '.gettype($count));
+ }
+
/**
* Now increase comments count
*/
$commentsCount = $this->getCommentsCount();
d('$commentsCount '.$commentsCount);
- $this->offsetSet('i_comments', ($commentsCount + 1) );
+ /**
+ * Must use parent::offsetSet because
+ * $this->offsetSet will point back to this
+ * method and enter infinite loop untill
+ * we run out of memory
+ */
+ parent::offsetSet('i_comments', ($commentsCount + $count) );
return $this;
}
@@ -395,30 +453,30 @@ public function increaseCommentsCount(){
*/
public function deleteComment($id){
- if(!$this->checkOffset('comments')){
+ if(0 === $this->getCommentsCount()){
e('This question does not have any comments');
return $this;
}
- $aComments = $this->offsetGet('comments');
+ $aComments = $this->offsetGet('a_comments');
for($i = 0; $i<count($aComments); $i+=1){
if($id == $aComments[$i]['_id']){
d('unsetting comment: '.$i);
- array_splice($aComments, $i, 1);
+ \array_splice($aComments, $i, 1);
break;
}
}
$newCount = count($aComments);
if( 0 === $newCount){
- $this->offsetUnset('comments');
+ $this->offsetUnset('a_comments');
} else {
- $this->offsetSet('comments', $aComments);
+ $this->offsetSet('a_comments', $aComments);
}
- $this->offsetSet('i_comments', $newCount );
+ $this->increaseCommentsCount(-1);
return $this;
}
@@ -431,10 +489,11 @@ public function deleteComment($id){
*
*/
public function getComments(){
- return $this->getFallback('comments', array());
+
+ return $this->offsetGet('a_comments');
}
-
+
/**
* Get id of question for this answer
*
@@ -443,8 +502,8 @@ public function getComments(){
public function getQuestionId(){
return (int)$this->offsetGet('i_qid');
}
-
-
+
+
/**
* Get uid of user who asked the question
* for which this is the answer
@@ -458,4 +517,42 @@ public function getQuestionOwnerId(){
return (int)$this->offsetGet('i_quid');
}
+
+ /**
+ * This method prevents setting some
+ * values directly
+ *
+ * (non-PHPdoc)
+ * @see ArrayObject::offsetSet()
+ */
+ public function offsetSet($index, $newval){
+ switch($index){
+ case 'accepted':
+ throw new DevException('value of accepted cannot be set directly. Use setAccepted() or unsetAccepted() methods');
+ break;
+
+ case 'i_comments':
+ throw new DevException('value of i_comments cannot be set directly. Use increaseCommentsCount() method');
+ break;
+
+ case 'i_down':
+ case 'i_up':
+ case 'i_votes':
+ throw new DevException('value of '.$index.' keys cannot be set directly. Use addDownVote or addUpVote to add votes');
+ break;
+
+ case 'a_deleted':
+ case 'i_del_ts':
+ throw new DevException('value of '.$index.' cannot be set directly. Must use setDeleted() method for that');
+ break;
+
+ case 'a_edited':
+ throw new DevException('value of a_edited cannot be set directly. Must use setEdited() method for that');
+ break;
+
+ default:
+ parent::offsetSet($index, $newval);
+ }
+ }
+
}
View
62 lib/Lampcms/AnswerParser.php
@@ -52,6 +52,8 @@
namespace Lampcms;
+use Lampcms\String\HTMLStringParser;
+
/**
* Class responsible for parsing submitted
* answer object.
@@ -85,8 +87,13 @@ class Answerparser extends LampcmsObject
protected $oQuestion;
+ /**
+ * Cache object
+ * @var object of type \Lampcms\Cache
+ */
protected $oCache;
+
/**
* Object of newly created answer
* an object of type Answer represents one
@@ -96,6 +103,7 @@ class Answerparser extends LampcmsObject
*/
protected $oAnswer = null;
+
public function __construct(Registry $oRegistry){
$this->oRegistry = $oRegistry;
/**
@@ -172,31 +180,28 @@ protected function makeAnswer(){
/**
* Must pass array('drop-proprietary-attributes' => false)
- * otherwise tidy removes rel="code" // ->makeClickable() // was after getBody
+ * otherwise tidy removes rel="code"
*/
- $oBody = $this->oSubmittedAnswer->getBody()->tidy()->safeHtml()->asHtml();
+ $aEditorConfig = $this->oRegistry->Ini->getSection('EDITOR');
+ $tidyConfig = ($aEditorConfig['ENABLE_CODE_EDITOR']) ? array('drop-proprietary-attributes' => false) : null;
+ $oBody = $this->oSubmittedAnswer->getBody()->tidy($tidyConfig)->safeHtml()->asHtml();
- $htmlBody = DomFeedItem::loadFeedItem($oBody)->getFeedItem();
+ $htmlBody = HTMLStringParser::factory($oBody)->parseCodeTags()->linkify()->importCDATA()->setNofollow()->valueOf();
- d('after DomFeedItem: '.$htmlBody);
+ d('after HTMLStringParser: '.$htmlBody);
$username = $this->oSubmittedAnswer->getUserObject()->getDisplayName();
$uid = $this->oSubmittedAnswer->getUserObject()->getUid();
$qid = $this->oSubmittedAnswer->getQid();
- $hash = hash('md5', strtolower($htmlBody.$qid));
+ $hash = hash('md5', \mb_strtolower($htmlBody.$qid));
/**
- * @todo can parse forMakrdown now but ideally
- * parseMarkdown() would be done inside Utf8string
- * as well as parseSmilies
- *
- * @todo Can't remember why we need to copy the title
+ *
+ * We need to copy the title
* here too because Answer by itself does not have own
- * title. This must have something to do with the way
- * I expected to render this - without the need to also
- * query the QUESTIONS collection but jsut can't remember
- * what it was for now...
+ * title but we need a title when displaying links
+ * to answer on profile pages
*
* @todo later can also parse for smilies here
*
@@ -208,11 +213,12 @@ protected function makeAnswer(){
'i_qid' => $qid,
'i_uid' => $uid,
'i_quid' => $this->oQuestion->getOwnerId(),
- 'title' => $this->oQuestion->title,
+ 'title' => $this->oQuestion->getTitle(),
'hash' => $hash,
'username' => $username,
'ulink' => '<a href="'.$this->oSubmittedAnswer->getUserObject()->getProfileUrl().'">'.$username.'</a>',
'avtr' => $this->oSubmittedAnswer->getUserObject()->getAvatarSrc(),
+ 'i_words' => $oBody->asPlainText()->getWordsCount(),
'i_up' => 0,
'i_down' => 0,
'i_votes' => 0,
@@ -347,7 +353,7 @@ protected function checkForDuplicate($hash){
* and add Answerer User to list
* of Question contributors
* (this is for the dot-folders feature)
- *
+ *
* The increaseAnswerCount will also update
* the last modified timestamp for question
*