publify_core 9.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of publify_core might be problematic. Click here for more details.

Files changed (372) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +35 -0
  5. data/app/assets/fonts/open-sans-bold.woff +0 -0
  6. data/app/assets/fonts/open-sans.woff +0 -0
  7. data/app/assets/images/admin/loading.gif +0 -0
  8. data/app/assets/images/admin/typologo.gif +0 -0
  9. data/app/assets/images/calendar_date_select/calendar.gif +0 -0
  10. data/app/assets/images/close.gif +0 -0
  11. data/app/assets/images/closelabel.gif +0 -0
  12. data/app/assets/images/go.png +0 -0
  13. data/app/assets/images/loading.gif +0 -0
  14. data/app/assets/images/nextlabel.gif +0 -0
  15. data/app/assets/images/overlay.png +0 -0
  16. data/app/assets/images/powered.gif +0 -0
  17. data/app/assets/images/prevlabel.gif +0 -0
  18. data/app/assets/images/spinner-blue.gif +0 -0
  19. data/app/assets/images/spinner.gif +0 -0
  20. data/app/assets/images/thumb_blank.jpg +0 -0
  21. data/app/assets/javascripts/application.js +2 -0
  22. data/app/assets/javascripts/cookies.js +60 -0
  23. data/app/assets/javascripts/datetimepicker.js +1470 -0
  24. data/app/assets/javascripts/lang/da_DK.js +17 -0
  25. data/app/assets/javascripts/lang/default.js +21 -0
  26. data/app/assets/javascripts/lang/en_US.js +21 -0
  27. data/app/assets/javascripts/lang/fr_FR.js +21 -0
  28. data/app/assets/javascripts/lang/nl_NL.js +21 -0
  29. data/app/assets/javascripts/lang/zh_TW.js +17 -0
  30. data/app/assets/javascripts/lightbox.js +350 -0
  31. data/app/assets/javascripts/observe.js +28 -0
  32. data/app/assets/javascripts/publify.js +11 -0
  33. data/app/assets/javascripts/publify_admin.js +138 -0
  34. data/app/assets/javascripts/quicktags.js +440 -0
  35. data/app/assets/javascripts/set-timeago-lang.js +3 -0
  36. data/app/assets/javascripts/sidebar.js +28 -0
  37. data/app/assets/javascripts/spinnable.js +5 -0
  38. data/app/assets/javascripts/tagmanager.js +481 -0
  39. data/app/assets/javascripts/typeahead.js +1139 -0
  40. data/app/assets/javascripts/widearea.js +486 -0
  41. data/app/assets/stylesheets/accounts.css.scss +7 -0
  42. data/app/assets/stylesheets/administration_structure.css.scss +239 -0
  43. data/app/assets/stylesheets/coderay.css +135 -0
  44. data/app/assets/stylesheets/datetimepicker.css +306 -0
  45. data/app/assets/stylesheets/lightbox.css +63 -0
  46. data/app/assets/stylesheets/publify.css.scss +9 -0
  47. data/app/assets/stylesheets/publify_admin.css.scss +11 -0
  48. data/app/assets/stylesheets/rss.css +53 -0
  49. data/app/assets/stylesheets/sidebar_admin.css.scss +36 -0
  50. data/app/assets/stylesheets/tagmanager.css +102 -0
  51. data/app/assets/stylesheets/user-styles.css +29 -0
  52. data/app/assets/stylesheets/widearea.css +133 -0
  53. data/app/controllers/accounts_controller.rb +2 -0
  54. data/app/controllers/admin/base_controller.rb +41 -0
  55. data/app/controllers/admin/cache_controller.rb +33 -0
  56. data/app/controllers/admin/content_controller.rb +174 -0
  57. data/app/controllers/admin/dashboard_controller.rb +87 -0
  58. data/app/controllers/admin/feedback_controller.rb +159 -0
  59. data/app/controllers/admin/migrations_controller.rb +20 -0
  60. data/app/controllers/admin/notes_controller.rb +69 -0
  61. data/app/controllers/admin/pages_controller.rb +88 -0
  62. data/app/controllers/admin/post_types_controller.rb +56 -0
  63. data/app/controllers/admin/profiles_controller.rb +48 -0
  64. data/app/controllers/admin/redirects_controller.rb +47 -0
  65. data/app/controllers/admin/resources_controller.rb +30 -0
  66. data/app/controllers/admin/seo_controller.rb +45 -0
  67. data/app/controllers/admin/settings_controller.rb +53 -0
  68. data/app/controllers/admin/sidebar_controller.rb +66 -0
  69. data/app/controllers/admin/tags_controller.rb +53 -0
  70. data/app/controllers/admin/textfilters_controller.rb +6 -0
  71. data/app/controllers/admin/themes_controller.rb +37 -0
  72. data/app/controllers/admin/users_controller.rb +65 -0
  73. data/app/controllers/articles_controller.rb +205 -0
  74. data/app/controllers/authors_controller.rb +27 -0
  75. data/app/controllers/base_controller.rb +45 -0
  76. data/app/controllers/comments_controller.rb +69 -0
  77. data/app/controllers/content_controller.rb +31 -0
  78. data/app/controllers/feedback_controller.rb +47 -0
  79. data/app/controllers/notes_controller.rb +37 -0
  80. data/app/controllers/setup_controller.rb +62 -0
  81. data/app/controllers/tags_controller.rb +55 -0
  82. data/app/controllers/text_controller.rb +9 -0
  83. data/app/controllers/textfilter_controller.rb +3 -0
  84. data/app/controllers/theme_controller.rb +59 -0
  85. data/app/controllers/trackbacks_controller.rb +36 -0
  86. data/app/controllers/xml_controller.rb +70 -0
  87. data/app/helpers/admin/base_helper.rb +87 -0
  88. data/app/helpers/admin/feedback_helper.rb +42 -0
  89. data/app/helpers/articles_helper.rb +8 -0
  90. data/app/helpers/authors_helper.rb +39 -0
  91. data/app/helpers/base_helper.rb +246 -0
  92. data/app/helpers/blog_helper.rb +12 -0
  93. data/app/helpers/xml_helper.rb +16 -0
  94. data/app/mailers/notification_mailer.rb +38 -0
  95. data/app/models/ability.rb +52 -0
  96. data/app/models/archives_sidebar.rb +45 -0
  97. data/app/models/article/factory.rb +56 -0
  98. data/app/models/article/states.rb +178 -0
  99. data/app/models/article.rb +321 -0
  100. data/app/models/blog.rb +290 -0
  101. data/app/models/blog_sweeper.rb +86 -0
  102. data/app/models/comment.rb +53 -0
  103. data/app/models/config_manager.rb +81 -0
  104. data/app/models/content.rb +138 -0
  105. data/app/models/content_base.rb +95 -0
  106. data/app/models/feedback/states.rb +256 -0
  107. data/app/models/feedback.rb +225 -0
  108. data/app/models/meta_sidebar.rb +8 -0
  109. data/app/models/note.rb +144 -0
  110. data/app/models/page.rb +36 -0
  111. data/app/models/page_cache.rb +33 -0
  112. data/app/models/page_sidebar.rb +12 -0
  113. data/app/models/ping.rb +116 -0
  114. data/app/models/post_type.rb +15 -0
  115. data/app/models/redirect.rb +45 -0
  116. data/app/models/redirection.rb +4 -0
  117. data/app/models/resource.rb +28 -0
  118. data/app/models/search_sidebar.rb +7 -0
  119. data/app/models/sidebar.rb +138 -0
  120. data/app/models/static_sidebar.rb +20 -0
  121. data/app/models/tag.rb +63 -0
  122. data/app/models/tag_sidebar.rb +27 -0
  123. data/app/models/text_filter.rb +61 -0
  124. data/app/models/trackback.rb +58 -0
  125. data/app/models/trigger.rb +45 -0
  126. data/app/models/user.rb +148 -0
  127. data/app/services/migrator.rb +25 -0
  128. data/app/services/title_builder.rb +80 -0
  129. data/app/uploaders/resource_uploader.rb +30 -0
  130. data/app/views/accounts/confirm.html.erb +8 -0
  131. data/app/views/admin/cache/show.html.erb +18 -0
  132. data/app/views/admin/content/_article_list.html.erb +26 -0
  133. data/app/views/admin/content/_form.html.erb +165 -0
  134. data/app/views/admin/content/autosave.js.erb +5 -0
  135. data/app/views/admin/content/edit.html.erb +3 -0
  136. data/app/views/admin/content/index.html.erb +48 -0
  137. data/app/views/admin/content/index.js.erb +1 -0
  138. data/app/views/admin/content/new.html.erb +3 -0
  139. data/app/views/admin/dashboard/_comment.html.erb +18 -0
  140. data/app/views/admin/dashboard/_comments.html.erb +10 -0
  141. data/app/views/admin/dashboard/_drafts.html.erb +25 -0
  142. data/app/views/admin/dashboard/_inbound.html.erb +31 -0
  143. data/app/views/admin/dashboard/_overview.html.erb +23 -0
  144. data/app/views/admin/dashboard/_welcome.html.erb +28 -0
  145. data/app/views/admin/dashboard/index.html.erb +17 -0
  146. data/app/views/admin/feedback/_button.html.erb +19 -0
  147. data/app/views/admin/feedback/_feedback.html.erb +7 -0
  148. data/app/views/admin/feedback/_ham.html.erb +17 -0
  149. data/app/views/admin/feedback/_spam.html.erb +23 -0
  150. data/app/views/admin/feedback/article.html.erb +69 -0
  151. data/app/views/admin/feedback/edit.html.erb +48 -0
  152. data/app/views/admin/feedback/ham.js +1 -0
  153. data/app/views/admin/feedback/index.html.erb +53 -0
  154. data/app/views/admin/feedback/spam.js +1 -0
  155. data/app/views/admin/migrations/show.html.erb +39 -0
  156. data/app/views/admin/notes/_form.html.erb +37 -0
  157. data/app/views/admin/notes/_header.html.erb +6 -0
  158. data/app/views/admin/notes/_list.html.erb +13 -0
  159. data/app/views/admin/notes/_note.html.erb +14 -0
  160. data/app/views/admin/notes/edit.html.erb +11 -0
  161. data/app/views/admin/notes/index.html.erb +11 -0
  162. data/app/views/admin/notes/show.html.erb +14 -0
  163. data/app/views/admin/pages/_form.html.erb +101 -0
  164. data/app/views/admin/pages/_pages.html.erb +21 -0
  165. data/app/views/admin/pages/edit.html.erb +1 -0
  166. data/app/views/admin/pages/index.html.erb +17 -0
  167. data/app/views/admin/pages/new.html.erb +1 -0
  168. data/app/views/admin/post_types/_index_and_form.html.erb +65 -0
  169. data/app/views/admin/post_types/edit.html.erb +1 -0
  170. data/app/views/admin/post_types/index.html.erb +1 -0
  171. data/app/views/admin/profiles/index.html.erb +10 -0
  172. data/app/views/admin/redirects/_index_and_form.html.erb +68 -0
  173. data/app/views/admin/redirects/edit.html.erb +1 -0
  174. data/app/views/admin/redirects/index.html.erb +1 -0
  175. data/app/views/admin/resources/index.html.erb +68 -0
  176. data/app/views/admin/seo/_general.html.erb +123 -0
  177. data/app/views/admin/seo/_permalinks.html.erb +53 -0
  178. data/app/views/admin/seo/_titles.html.erb +210 -0
  179. data/app/views/admin/seo/show.html.erb +32 -0
  180. data/app/views/admin/settings/display.html.erb +110 -0
  181. data/app/views/admin/settings/feedback.html.erb +125 -0
  182. data/app/views/admin/settings/index.html.erb +73 -0
  183. data/app/views/admin/settings/write.html.erb +87 -0
  184. data/app/views/admin/shared/_edit.html.erb +4 -0
  185. data/app/views/admin/shared/_menu.html.erb +122 -0
  186. data/app/views/admin/shared/_twitter_alert.html.erb +3 -0
  187. data/app/views/admin/sidebar/_available.html.erb +6 -0
  188. data/app/views/admin/sidebar/_available.json.erb +6 -0
  189. data/app/views/admin/sidebar/_config.html.erb +27 -0
  190. data/app/views/admin/sidebar/_target.html.erb +9 -0
  191. data/app/views/admin/sidebar/_target_sidebar.html.erb +20 -0
  192. data/app/views/admin/sidebar/destroy.js.erb +1 -0
  193. data/app/views/admin/sidebar/index.html.erb +31 -0
  194. data/app/views/admin/sidebar/sortable.js.erb +3 -0
  195. data/app/views/admin/sidebar/update.js.erb +2 -0
  196. data/app/views/admin/tags/_index_and_form.html.erb +59 -0
  197. data/app/views/admin/tags/edit.html.erb +1 -0
  198. data/app/views/admin/tags/index.html.erb +1 -0
  199. data/app/views/admin/themes/index.html.erb +27 -0
  200. data/app/views/admin/users/_form.html.erb +215 -0
  201. data/app/views/admin/users/edit.html.erb +8 -0
  202. data/app/views/admin/users/index.html.erb +39 -0
  203. data/app/views/admin/users/new.html.erb +8 -0
  204. data/app/views/archives_sidebar/_content.html.erb +13 -0
  205. data/app/views/articles/_article.html.erb +9 -0
  206. data/app/views/articles/_article_collection.html.erb +8 -0
  207. data/app/views/articles/_article_content.html.erb +5 -0
  208. data/app/views/articles/_article_excerpt.html.erb +13 -0
  209. data/app/views/articles/_article_links.html.erb +10 -0
  210. data/app/views/articles/_comment.html.erb +1 -0
  211. data/app/views/articles/_comment_errors.html.erb +2 -0
  212. data/app/views/articles/_comment_form.html.erb +48 -0
  213. data/app/views/articles/_comment_list.html.erb +5 -0
  214. data/app/views/articles/_comment_preview.html.erb +4 -0
  215. data/app/views/articles/_full_article_content.html.erb +2 -0
  216. data/app/views/articles/_password_form.html.erb +10 -0
  217. data/app/views/articles/_protected_article_content.html.erb +6 -0
  218. data/app/views/articles/_trackback.html.erb +6 -0
  219. data/app/views/articles/archives.html.erb +25 -0
  220. data/app/views/articles/comment.js.erb +5 -0
  221. data/app/views/articles/comment_failed.js.erb +3 -0
  222. data/app/views/articles/error.html.erb +3 -0
  223. data/app/views/articles/feedback_atom_feed.atom.builder +8 -0
  224. data/app/views/articles/feedback_rss_feed.rss.builder +21 -0
  225. data/app/views/articles/index.html.erb +1 -0
  226. data/app/views/articles/index_atom_feed.atom.builder +8 -0
  227. data/app/views/articles/index_rss_feed.rss.builder +20 -0
  228. data/app/views/articles/live_search.html.erb +10 -0
  229. data/app/views/articles/read.html.erb +61 -0
  230. data/app/views/articles/search.html.erb +8 -0
  231. data/app/views/articles/trackback.xml.builder +5 -0
  232. data/app/views/articles/view_page.html.erb +3 -0
  233. data/app/views/authors/show.html.erb +40 -0
  234. data/app/views/authors/show_atom_feed.atom.builder +8 -0
  235. data/app/views/authors/show_rss_feed.rss.builder +20 -0
  236. data/app/views/comments/_comment.html.erb +16 -0
  237. data/app/views/comments/index.html.erb +1 -0
  238. data/app/views/comments/index_atom_feed.atom.builder +8 -0
  239. data/app/views/comments/index_rss_feed.rss.builder +20 -0
  240. data/app/views/comments/preview.html.erb +1 -0
  241. data/app/views/comments/preview.js.erb +3 -0
  242. data/app/views/devise/mailer/reset_password_instructions.html.erb +13 -0
  243. data/app/views/devise/passwords/edit.html.erb +28 -0
  244. data/app/views/devise/passwords/new.html.erb +20 -0
  245. data/app/views/devise/registrations/new.html.erb +36 -0
  246. data/app/views/devise/sessions/new.html.erb +32 -0
  247. data/app/views/devise/shared/_links.html.erb +15 -0
  248. data/app/views/errors/404.html.erb +2 -0
  249. data/app/views/layouts/accounts.html.erb +33 -0
  250. data/app/views/layouts/administration.html.erb +37 -0
  251. data/app/views/layouts/default.html.erb +32 -0
  252. data/app/views/layouts/editor.html.erb +31 -0
  253. data/app/views/meta_sidebar/_content.html.erb +8 -0
  254. data/app/views/notes/_note.html.erb +15 -0
  255. data/app/views/notes/error.html.erb +3 -0
  256. data/app/views/notes/index.html.erb +15 -0
  257. data/app/views/notes/show.html.erb +5 -0
  258. data/app/views/notes/show_in_reply.html.erb +16 -0
  259. data/app/views/notification_mailer/_mail_footer.html.erb +7 -0
  260. data/app/views/notification_mailer/_mail_header.html.erb +1 -0
  261. data/app/views/notification_mailer/article.html.erb +6 -0
  262. data/app/views/notification_mailer/comment.html.erb +11 -0
  263. data/app/views/notification_mailer/notif_user.html.erb +14 -0
  264. data/app/views/page_sidebar/_content.html.erb +12 -0
  265. data/app/views/search_sidebar/_content.html.erb +10 -0
  266. data/app/views/settings/done.html.erb +2 -0
  267. data/app/views/settings/install.html.erb +12 -0
  268. data/app/views/setup/index.html.erb +13 -0
  269. data/app/views/shared/_atom_header.atom.builder +6 -0
  270. data/app/views/shared/_atom_item_article.atom.builder +39 -0
  271. data/app/views/shared/_atom_item_comment.atom.builder +10 -0
  272. data/app/views/shared/_atom_item_trackback.atom.builder +9 -0
  273. data/app/views/shared/_flash.erb +10 -0
  274. data/app/views/shared/_page_header.html.erb +26 -0
  275. data/app/views/shared/_rss_item_article.rss.builder +35 -0
  276. data/app/views/shared/_rss_item_comment.rss.builder +8 -0
  277. data/app/views/shared/_rss_item_trackback.rss.builder +7 -0
  278. data/app/views/sidebar/_row.html.erb +1 -0
  279. data/app/views/sidebar/_sidebar.html.erb +5 -0
  280. data/app/views/sidebar/display_plugins.html.erb +5 -0
  281. data/app/views/sidebar/show.html.erb +1 -0
  282. data/app/views/static_sidebar/_content.html.erb +2 -0
  283. data/app/views/tag_sidebar/_content.html.erb +10 -0
  284. data/app/views/tags/index.html.erb +15 -0
  285. data/app/views/tags/show.html.erb +1 -0
  286. data/app/views/theme/static_view_test.html.erb +1 -0
  287. data/app/views/trackbacks/index_atom_feed.atom.builder +7 -0
  288. data/app/views/trackbacks/index_rss_feed.rss.builder +20 -0
  289. data/app/views/trackbacks/trackback.xml.builder +4 -0
  290. data/app/views/xml/_googlesitemap_item_article.googlesitemap.builder +5 -0
  291. data/app/views/xml/_googlesitemap_item_category.googlesitemap.builder +4 -0
  292. data/app/views/xml/_googlesitemap_item_page.googlesitemap.builder +4 -0
  293. data/app/views/xml/_googlesitemap_item_tag.googlesitemap.builder +4 -0
  294. data/app/views/xml/feed.googlesitemap.builder +7 -0
  295. data/app/views/xml/rsd.rsd.builder +8 -0
  296. data/config/i18n-tasks.yml +49 -0
  297. data/config/initializers/devise.rb +265 -0
  298. data/config/initializers/mime_types.rb +6 -0
  299. data/config/locales/da.yml +827 -0
  300. data/config/locales/de.yml +827 -0
  301. data/config/locales/en.yml +827 -0
  302. data/config/locales/es-MX.yml +827 -0
  303. data/config/locales/fr.yml +827 -0
  304. data/config/locales/he.yml +827 -0
  305. data/config/locales/it.yml +827 -0
  306. data/config/locales/ja.yml +827 -0
  307. data/config/locales/lt.yml +827 -0
  308. data/config/locales/nb-NO.yml +827 -0
  309. data/config/locales/nl.yml +827 -0
  310. data/config/locales/pl.yml +827 -0
  311. data/config/locales/pt-BR.yml +827 -0
  312. data/config/locales/ro.yml +827 -0
  313. data/config/locales/ru.yml +827 -0
  314. data/config/locales/sidebars.da.yml +20 -0
  315. data/config/locales/sidebars.de.yml +20 -0
  316. data/config/locales/sidebars.en.yml +20 -0
  317. data/config/locales/sidebars.es-MX.yml +20 -0
  318. data/config/locales/sidebars.fr.yml +20 -0
  319. data/config/locales/sidebars.he.yml +20 -0
  320. data/config/locales/sidebars.it.yml +20 -0
  321. data/config/locales/sidebars.ja.yml +20 -0
  322. data/config/locales/sidebars.lt.yml +20 -0
  323. data/config/locales/sidebars.nb-NO.yml +20 -0
  324. data/config/locales/sidebars.nl.yml +20 -0
  325. data/config/locales/sidebars.pl.yml +20 -0
  326. data/config/locales/sidebars.pt-BR.yml +20 -0
  327. data/config/locales/sidebars.ro.yml +20 -0
  328. data/config/locales/sidebars.ru.yml +20 -0
  329. data/config/locales/sidebars.zh-CN.yml +20 -0
  330. data/config/locales/sidebars.zh-TW.yml +20 -0
  331. data/config/locales/zh-CN.yml +827 -0
  332. data/config/locales/zh-TW.yml +827 -0
  333. data/config/routes.rb +177 -0
  334. data/db/migrate/113_initial_schema.rb +205 -0
  335. data/db/migrate/114_fixes_buggy_articles_and_notes.rb +52 -0
  336. data/db/migrate/115_drops_categories_for_tags.rb +34 -0
  337. data/db/migrate/20150207131657_add_missing_indexes.rb +19 -0
  338. data/db/migrate/20150807134129_simplify_redirect_relations.rb +38 -0
  339. data/db/migrate/20150808052637_add_blog_ids.rb +33 -0
  340. data/db/migrate/20150808191127_add_blog_id_to_redirects.rb +15 -0
  341. data/db/migrate/20150810094754_add_blog_id_to_tags.rb +15 -0
  342. data/db/migrate/20160108111120_add_devise_to_users.rb +53 -0
  343. data/db/migrate/20160108184201_move_last_connection_to_last_sign_in_at.rb +16 -0
  344. data/db/migrate/20160110094906_remove_profiles_rights.rb +14 -0
  345. data/db/migrate/20160605103918_replace_profile_id_with_string.rb +30 -0
  346. data/db/migrate/20160605154632_remove_profiles.rb +24 -0
  347. data/db/migrate/20160701061851_demand_blog_id_on_contents.rb +9 -0
  348. data/db/migrate/20160701062604_add_blog_id_to_resources.rb +28 -0
  349. data/db/seeds.rb +37 -0
  350. data/lib/email_notify.rb +26 -0
  351. data/lib/format.rb +17 -0
  352. data/lib/publify_core/engine.rb +23 -0
  353. data/lib/publify_core/lang.rb +5 -0
  354. data/lib/publify_core/version.rb +3 -0
  355. data/lib/publify_core.rb +56 -0
  356. data/lib/publify_guid.rb +9 -0
  357. data/lib/publify_plugins.rb +72 -0
  358. data/lib/publify_textfilter_markdown.rb +44 -0
  359. data/lib/publify_textfilter_none.rb +14 -0
  360. data/lib/publify_textfilter_smartypants.rb +14 -0
  361. data/lib/publify_textfilter_textile.rb +21 -0
  362. data/lib/publify_textfilter_twitterfilter.rb +33 -0
  363. data/lib/publify_time.rb +30 -0
  364. data/lib/sidebar_field.rb +115 -0
  365. data/lib/sidebar_registry.rb +33 -0
  366. data/lib/spam_protection.rb +101 -0
  367. data/lib/stateful.rb +106 -0
  368. data/lib/tasks/publify_core_tasks.rake +4 -0
  369. data/lib/text_filter_plugin.rb +182 -0
  370. data/lib/theme.rb +72 -0
  371. data/lib/transforms.rb +45 -0
  372. metadata +865 -0
@@ -0,0 +1,321 @@
1
+ # coding: utf-8
2
+ require 'uri'
3
+ require 'net/http'
4
+
5
+ class Article < Content
6
+ include PublifyGuid
7
+ include ConfigManager
8
+
9
+ serialize :settings, Hash
10
+
11
+ content_fields :body, :extended
12
+
13
+ validates :guid, uniqueness: true
14
+ validates :title, presence: true
15
+
16
+ has_many :pings, dependent: :destroy
17
+ has_many :trackbacks, dependent: :destroy
18
+ has_many :feedback
19
+ has_many :resources, dependent: :nullify
20
+ has_many :triggers, as: :pending_item
21
+ has_many :comments, dependent: :destroy
22
+
23
+ has_and_belongs_to_many :tags, join_table: 'articles_tags'
24
+
25
+ before_create :create_guid
26
+ before_save :set_published_at, :set_permalink
27
+ after_save :post_trigger, :keywords_to_tags, :shorten_url
28
+ after_save :send_pings
29
+ after_save :send_notifications
30
+
31
+ scope :drafts, -> { where(state: 'draft').order('created_at DESC') }
32
+ scope :child_of, ->(article_id) { where(parent_id: article_id) }
33
+ scope :published_at, ->(time_params) { published.where(published_at: PublifyTime.delta(*time_params)).order('published_at DESC') }
34
+ scope :published_since, ->(time) { published.where('published_at > ?', time).order('published_at DESC') }
35
+ scope :withdrawn, -> { where(state: 'withdrawn').order('published_at DESC') }
36
+ scope :pending, -> { where('state = ? and published_at > ?', 'publication_pending', Time.now).order('published_at DESC') }
37
+
38
+ scope :bestof, lambda {
39
+ joins(:feedback).
40
+ where('feedback.published' => true, 'feedback.type' => 'Comment',
41
+ 'contents.published' => true).
42
+ group('contents.id').
43
+ order('count(feedback.id) DESC').
44
+ select('contents.*, count(feedback.id) as comment_count').
45
+ limit(5)
46
+ }
47
+
48
+ setting :password, :string, ''
49
+
50
+ attr_accessor :draft, :keywords
51
+
52
+ include Article::States
53
+
54
+ has_state(:state, valid_states: [:new, :draft,
55
+ :publication_pending, :just_published, :published,
56
+ :just_withdrawn, :withdrawn],
57
+ initial_state: :new,
58
+ handles: [:withdraw,
59
+ :post_trigger,
60
+ :send_pings, :send_notifications,
61
+ :published_at=, :published=, :just_published?])
62
+
63
+ def set_permalink
64
+ return if state == 'draft' || permalink.present?
65
+ self.permalink = title.to_permalink
66
+ end
67
+
68
+ def has_child?
69
+ Article.exists?(parent_id: id)
70
+ end
71
+
72
+ def post_type
73
+ post_type = self[:post_type]
74
+ post_type = 'read' if post_type.blank?
75
+ post_type
76
+ end
77
+
78
+ def self.last_draft(article_id)
79
+ article = Article.find(article_id)
80
+ article = Article.child_of(article.id).first while article.has_child?
81
+ article
82
+ end
83
+
84
+ def self.search_with(params)
85
+ params ||= {}
86
+ scoped = super(params)
87
+ if %w(no_draft drafts published withdrawn pending).include?(params[:state])
88
+ scoped = scoped.send(params[:state])
89
+ end
90
+
91
+ scoped.order('created_at DESC')
92
+ end
93
+
94
+ # FIXME: Use keyword params to clean up call sites.
95
+ def permalink_url(anchor = nil, only_path = false)
96
+ @cached_permalink_url ||= {}
97
+ @cached_permalink_url["#{anchor}#{only_path}"] ||= blog.url_for(permalink_url_options, anchor: anchor, only_path: only_path)
98
+ end
99
+
100
+ def save_attachments!(files)
101
+ files ||= {}
102
+ files.values.each { |f| save_attachment!(f) }
103
+ end
104
+
105
+ def save_attachment!(file)
106
+ resources.create!(upload: file, blog: blog)
107
+ end
108
+
109
+ def trackback_url
110
+ blog.url_for("trackbacks?article_id=#{id}", only_path: false)
111
+ end
112
+
113
+ def comment_url
114
+ blog.url_for("comments?article_id=#{id}", only_path: true)
115
+ end
116
+
117
+ def preview_comment_url
118
+ blog.url_for("comments/preview?article_id=#{id}", only_path: true)
119
+ end
120
+
121
+ def feed_url(format)
122
+ "#{permalink_url}.#{format.gsub(/\d/, '')}"
123
+ end
124
+
125
+ def really_send_pings
126
+ return unless blog.send_outbound_pings
127
+
128
+ blog.urls_to_ping_for(self).each do |url_to_ping|
129
+ begin
130
+ url_to_ping.send_weblogupdatesping(blog.base_url, permalink_url)
131
+ rescue => e
132
+ logger.error(e)
133
+ # in case the remote server doesn't respond or gives an error,
134
+ # we should throw an xmlrpc error here.
135
+ end
136
+ end
137
+
138
+ html_urls_to_ping.each do |url_to_ping|
139
+ begin
140
+ url_to_ping.send_pingback_or_trackback(permalink_url)
141
+ rescue => e
142
+ logger.error(e)
143
+ # in case the remote server doesn't respond or gives an error,
144
+ # we should throw an xmlrpc error here.
145
+ end
146
+ end
147
+ end
148
+
149
+ def next
150
+ Article.where('published_at > ?', published_at).order('published_at asc').limit(1).first
151
+ end
152
+
153
+ def previous
154
+ Article.where('published_at < ?', published_at).order('published_at desc').limit(1).first
155
+ end
156
+
157
+ def self.publication_months
158
+ result = select('published_at').where('published_at is not NULL').where(type: 'Article')
159
+ result.map { |d| [d.published_at.strftime('%Y-%m')] }.uniq
160
+ end
161
+
162
+ # Finds one article which was posted on a certain date and matches the supplied dashed-title
163
+ # params is a Hash
164
+ def self.requested_article(params)
165
+ date_range = PublifyTime.delta(params[:year], params[:month], params[:day])
166
+
167
+ req_params = {}
168
+ req_params[:permalink] = params[:title] if params[:title]
169
+ req_params[:published_at] = date_range if date_range
170
+
171
+ return if req_params.empty? # no search if no params send
172
+ article = published.find_by(req_params)
173
+ return article if article
174
+
175
+ if params[:title]
176
+ req_params[:permalink] = CGI.escape(params[:title])
177
+ article = published.find_by(req_params)
178
+ return article if article
179
+ end
180
+ end
181
+
182
+ # Fulltext searches the body of published articles
183
+ def self.search(query, args = {})
184
+ query_s = query.to_s.strip
185
+ if !query_s.empty? && args.empty?
186
+ Article.searchstring(query)
187
+ elsif !query_s.empty? && !args.empty?
188
+ Article.searchstring(query).page(args[:page]).per(args[:per])
189
+ else
190
+ []
191
+ end
192
+ end
193
+
194
+ def keywords_to_tags
195
+ Tag.create_from_article!(self)
196
+ end
197
+
198
+ def interested_users
199
+ User.where(notify_on_new_articles: true)
200
+ end
201
+
202
+ def notify_user_via_email(user)
203
+ EmailNotify.send_article(self, user) if user.notify_via_email?
204
+ end
205
+
206
+ def comments_closed?
207
+ !(allow_comments? && in_feedback_window?)
208
+ end
209
+
210
+ def html_urls
211
+ urls = []
212
+ html.gsub(/<a\s+[^>]*>/) do |tag|
213
+ if tag =~ /\bhref=(["']?)([^ >"]+)\1/
214
+ urls.push(Regexp.last_match[2].strip)
215
+ end
216
+ end
217
+ urls.uniq
218
+ end
219
+
220
+ def pings_closed?
221
+ !(allow_pings? && in_feedback_window?)
222
+ end
223
+
224
+ # check if time to comment is open or not
225
+ def in_feedback_window?
226
+ blog.sp_article_auto_close.zero? ||
227
+ published_at.to_i > blog.sp_article_auto_close.days.ago.to_i
228
+ end
229
+
230
+ def content_fields
231
+ [:body, :extended]
232
+ end
233
+
234
+ # The web interface no longer distinguishes between separate "body" and
235
+ # "extended" fields, and instead edits everything in a single edit field,
236
+ # separating the extended content using "\<!--more-->".
237
+ def body_and_extended
238
+ if extended.blank?
239
+ body
240
+ else
241
+ body + "\n<!--more-->\n" + extended
242
+ end
243
+ end
244
+
245
+ # Split apart value around a "\<!--more-->" comment and assign it to our
246
+ # #body and #extended fields.
247
+ def body_and_extended=(value)
248
+ parts = value.split(/\n?<!--more-->\n?/, 2)
249
+ self.body = parts[0]
250
+ self.extended = parts[1] || ''
251
+ end
252
+
253
+ def password_protected?
254
+ !password.blank?
255
+ end
256
+
257
+ def add_comment(params)
258
+ comments.build(params)
259
+ end
260
+
261
+ def access_by?(user)
262
+ user.admin? || user_id == user.id
263
+ end
264
+
265
+ def already_ping?(url)
266
+ pings.map(&:url).include?(url)
267
+ end
268
+
269
+ def allow_comments?
270
+ return allow_comments unless allow_comments.nil?
271
+ blog.default_allow_comments
272
+ end
273
+
274
+ def allow_pings?
275
+ return allow_pings unless allow_pings.nil?
276
+ blog.default_allow_pings
277
+ end
278
+
279
+ def published_comments
280
+ comments.published.oldest_first
281
+ end
282
+
283
+ def published_trackbacks
284
+ trackbacks.published.oldest_first
285
+ end
286
+
287
+ def published_feedback
288
+ feedback.published.oldest_first
289
+ end
290
+
291
+ protected
292
+
293
+ def set_published_at
294
+ if published && self[:published_at].nil?
295
+ self[:published_at] = created_at || Time.now
296
+ end
297
+ end
298
+
299
+ private
300
+
301
+ def permalink_url_options
302
+ format_url = blog.permalink_format.dup
303
+ format_url.gsub!('%year%', published_at.year.to_s)
304
+ format_url.gsub!('%month%', sprintf('%.2d', published_at.month))
305
+ format_url.gsub!('%day%', sprintf('%.2d', published_at.day))
306
+ format_url.gsub!('%title%', URI.encode(permalink.to_s))
307
+ if format_url[0, 1] == '/'
308
+ format_url[1..-1]
309
+ else
310
+ format_url
311
+ end
312
+ end
313
+
314
+ def html_urls_to_ping
315
+ urls_to_ping = []
316
+ html_urls.delete_if { |url| already_ping?(url) }.uniq.each do |url_to_ping|
317
+ urls_to_ping << pings.build('url' => url_to_ping)
318
+ end
319
+ urls_to_ping
320
+ end
321
+ end
@@ -0,0 +1,290 @@
1
+ # The Blog class represents the one and only blog. It stores most
2
+ # configuration settings and is linked to most of the assorted content
3
+ # classes via has_many.
4
+ #
5
+ # Once upon a time, there were plans to make publify handle multiple blogs,
6
+ # but it never happened and publify is now firmly single-blog.
7
+ #
8
+ class Blog < ActiveRecord::Base
9
+ include ConfigManager
10
+ include Rails.application.routes.url_helpers
11
+
12
+ has_many :contents
13
+ has_many :articles
14
+ has_many :feedback, through: :articles
15
+
16
+ has_many(:published_articles,
17
+ ->() { includes(:tags).where(published: true).order('contents.published_at DESC') },
18
+ class_name: 'Article')
19
+
20
+ has_many :pages
21
+ has_many :tags
22
+ has_many :notes
23
+
24
+ has_many :redirects
25
+ has_many :sidebars, ->() { order('active_position ASC') }
26
+
27
+ attr_accessor :custom_permalink
28
+
29
+ default_scope -> { order('id') }
30
+
31
+ validates :blog_name, presence: true
32
+
33
+ serialize :settings, Hash
34
+
35
+ # Description
36
+ setting :blog_name, :string, 'My Shiny Weblog!'
37
+ setting :blog_subtitle, :string, ''
38
+ setting :geourl_location, :string, ''
39
+ setting :canonical_server_url, :string, '' # Deprecated
40
+ setting :lang, :string, 'en_US'
41
+ setting :title_prefix, :integer, 0 # Deprecated but needed for a migration
42
+
43
+ # Spam
44
+ setting :sp_global, :boolean, false
45
+ setting :sp_article_auto_close, :integer, 0
46
+ setting :sp_url_limit, :integer, 0
47
+ setting :sp_akismet_key, :string, ''
48
+ setting :use_recaptcha, :boolean, false
49
+
50
+ # Mostly Behaviour
51
+ setting :text_filter, :string, 'markdown smartypants'
52
+ setting :comment_text_filter, :string, 'markdown smartypants'
53
+ setting :limit_article_display, :integer, 10
54
+ setting :limit_archives_display, :integer, 20
55
+ setting :limit_rss_display, :integer, 10
56
+ setting :default_allow_pings, :boolean, false
57
+ setting :default_allow_comments, :boolean, true
58
+ setting :default_moderate_comments, :boolean, false
59
+ setting :link_to_author, :boolean, false
60
+ setting :show_extended_on_rss, :boolean, true # deprecated but still needed for backward compatibility
61
+ setting :hide_extended_on_rss, :boolean, false
62
+ setting :theme, :string, 'plain'
63
+ setting :plugin_avatar, :string, ''
64
+ setting :global_pings_disable, :boolean, false
65
+ setting :ping_urls, :string, "http://blogsearch.google.com/ping/RPC2\nhttp://rpc.technorati.com/rpc/ping\nhttp://ping.blo.gs/\nhttp://rpc.weblogs.com/RPC2"
66
+ setting :send_outbound_pings, :boolean, true
67
+ setting :email_from, :string, 'publify@example.com'
68
+ setting :allow_signup, :integer, 0
69
+ setting :date_format, :string, '%d/%m/%Y'
70
+ setting :time_format, :string, '%Hh%M'
71
+ setting :image_avatar_size, :integer, 48
72
+ setting :image_thumb_size, :integer, 125
73
+ setting :image_medium_size, :integer, 600
74
+
75
+ # SEO
76
+ setting :meta_description, :string, ''
77
+ setting :meta_keywords, :string, ''
78
+ setting :google_analytics, :string, ''
79
+ setting :feedburner_url, :string, ''
80
+ setting :rss_description, :boolean, false
81
+ setting :rss_description_text, :string, <<EOS
82
+ <hr />
83
+ <p><small>Original article written by %author% and published on <a href='%blog_url%'>%blog_name%</a>
84
+ | <a href='%permalink_url%'>direct link to this article</a>
85
+ | If you are reading this article anywhere other than on <a href='%blog_url%'>%blog_name%</a>,
86
+ it has been illegally reproduced and without proper authorization.</small></p>
87
+ EOS
88
+ setting :permalink_format, :string, '/%year%/%month%/%day%/%title%'
89
+ setting :robots, :string, 'User-agent: *\nAllow: /\nDisallow: /admin\n'
90
+ setting :humans, :string, <<EOS
91
+ /* TEAM */
92
+ Your title: Your name.
93
+ Site: email, link to a contact form, etc.
94
+ Twitter: your Twitter username.
95
+
96
+ /* SITE */
97
+ Software: Publify [http://publify.co] #{PublifyCore::VERSION}
98
+ EOS
99
+ setting :index_categories, :boolean, true # deprecated but still needed for backward compatibility
100
+ setting :unindex_categories, :boolean, false
101
+ setting :index_tags, :boolean, true # deprecated but still needed for backward compatibility
102
+ setting :unindex_tags, :boolean, false
103
+ setting :admin_display_elements, :integer, 10
104
+ setting :google_verification, :string, ''
105
+ setting :nofollowify, :boolean, true # deprecated but still needed for backward compatibility
106
+ setting :dofollowify, :boolean, false
107
+ setting :use_canonical_url, :boolean, false
108
+ setting :use_meta_keyword, :boolean, true
109
+ setting :home_title_template, :string, '%blog_name% | %blog_subtitle%' # spec OK
110
+ setting :home_desc_template, :string, '%blog_name% | %blog_subtitle% | %meta_keywords%' # OK
111
+ setting :article_title_template, :string, '%title% | %blog_name%'
112
+ setting :article_desc_template, :string, '%excerpt%'
113
+ setting :page_title_template, :string, '%title% | %blog_name%'
114
+ setting :page_desc_template, :string, '%excerpt%'
115
+ setting :paginated_title_template, :string, '%blog_name% | %blog_subtitle% %page%'
116
+ setting :paginated_desc_template, :string, '%blog_name% | %blog_subtitle% | %meta_keywords% %page%'
117
+ setting :tag_title_template, :string, 'Tag: %name% | %blog_name% %page%'
118
+ setting :tag_desc_template, :string, '%name% | %blog_name% | %blog_subtitle% %page%'
119
+ setting :author_title_template, :string, '%author% | %blog_name%'
120
+ setting :author_desc_template, :string, '%author% | %blog_name% | %blog_subtitle%'
121
+ setting :archives_title_template, :string, 'Archives for %blog_name% %date% %page%'
122
+ setting :archives_desc_template, :string, 'Archives for %blog_name% %date% %page% %blog_subtitle%'
123
+ setting :search_title_template, :string, 'Results for %search% | %blog_name% %page%'
124
+ setting :search_desc_template, :string, 'Results for %search% | %blog_name% | %blog_subtitle% %page%'
125
+ setting :statuses_title_template, :string, 'Notes | %blog_name% %page%'
126
+ setting :statuses_desc_template, :string, 'Notes | %blog_name% | %blog_subtitle% %page%'
127
+ setting :status_title_template, :string, '%body% | %blog_name%'
128
+ setting :status_desc_template, :string, '%excerpt%'
129
+
130
+ setting :custom_tracking_field, :string, ''
131
+ # setting :meta_author_template, :string, "%blog_name% | %nickname%"
132
+
133
+ setting :twitter_consumer_key, :string, ''
134
+ setting :twitter_consumer_secret, :string, ''
135
+ setting :custom_url_shortener, :string, ''
136
+ setting :statuses_in_timeline, :boolean, true
137
+
138
+ validate :permalink_has_identifier
139
+ # validates :base_url, presence: true
140
+
141
+ # Find the Blog that matches a specific base URL. If no Blog object is found
142
+ # that matches, then grab the first blog. If *that* fails, then create a new
143
+ # Blog. The last case should only be used when Publify is first installed.
144
+ def self.find_blog(base_url)
145
+ Blog.find_by(base_url: base_url) || Blog.first || Blog.new
146
+ end
147
+
148
+ # In settings with :article_id
149
+ def ping_article!(settings)
150
+ unless global_pings_enabled? && settings.key?(:url) && settings.key?(:article_id)
151
+ throw :error, 'Invalid trackback or trackbacks not enabled'
152
+ end
153
+ article = Article.find(settings[:article_id])
154
+ throw :error, 'Trackback not saved' unless article.allow_pings?
155
+ article.trackbacks.create!(settings)
156
+ end
157
+
158
+ def global_pings_enabled?
159
+ !global_pings_disable?
160
+ end
161
+
162
+ # Check that all required blog settings have a value.
163
+ def configured?
164
+ settings.key?('blog_name')
165
+ end
166
+
167
+ # The +Theme+ object for the current theme.
168
+ def current_theme(reload = nil)
169
+ @current_theme = nil if reload
170
+ @current_theme ||= Theme.find(theme) || Theme.new('', '')
171
+ end
172
+
173
+ # Generate a URL based on the +base_url+. This allows us to generate URLs
174
+ # without needing a controller handy, so we can produce URLs from within models
175
+ # where appropriate.
176
+ #
177
+ # It also caches the result in the Rails cache, so repeated URL generation
178
+ # requests should be fast, as they bypass all of Rails' route logic.
179
+ def url_for_with_base_url(options = {}, extra_params = {})
180
+ case options
181
+ when String
182
+ url_generated = if extra_params[:only_path]
183
+ root_path
184
+ else
185
+ base_url
186
+ end
187
+ url_generated += "/#{options}" # They asked for 'url_for "/some/path"', so return it unedited.
188
+ url_generated += "##{extra_params[:anchor]}" if extra_params[:anchor]
189
+ url_generated
190
+ when Hash
191
+ merged_opts = options.reverse_merge!(only_path: false, controller: '',
192
+ action: 'permalink',
193
+ host: host_with_port,
194
+ script_name: root_path)
195
+ cache_key = merged_opts.values.prepend('blog-urlfor-withbaseurl').join('-')
196
+ unless Rails.cache.exist?(cache_key)
197
+ Rails.cache.write(cache_key, url_for_without_base_url(merged_opts))
198
+ end
199
+ Rails.cache.read(cache_key)
200
+ else
201
+ raise "Invalid URL in url_for: #{options.inspect}"
202
+ end
203
+ end
204
+
205
+ alias_method_chain :url_for, :base_url
206
+
207
+ # The URL for a static file.
208
+ # FIXME: Let carrierwave handle this by itself
209
+ def file_url(filename)
210
+ if CarrierWave.configure { |config| config.storage == CarrierWave::Storage::Fog }
211
+ filename
212
+ else
213
+ url_for "files/#{filename}", only_path: false
214
+ end
215
+ end
216
+
217
+ def articles_matching(query, args = {})
218
+ Article.search(query, args)
219
+ end
220
+
221
+ def per_page(format)
222
+ return limit_article_display if format.nil? || format == 'html'
223
+ limit_rss_display
224
+ end
225
+
226
+ def rss_limit_params
227
+ limit = limit_rss_display.to_i
228
+ if limit.zero?
229
+ {}
230
+ else
231
+ { limit: limit }
232
+ end
233
+ end
234
+
235
+ def permalink_has_identifier
236
+ unless permalink_format =~ /(%title%)/
237
+ errors.add(:base, I18n.t('errors.permalink_need_a_title'))
238
+ end
239
+
240
+ if permalink_format =~ /\.(atom|rss)$/
241
+ errors.add(:permalink_format, I18n.t('errors.cant_end_with_rss_or_atom'))
242
+ end
243
+ end
244
+
245
+ def root_path
246
+ split_base_url[:root_path]
247
+ end
248
+
249
+ def text_filter_object
250
+ TextFilter.find_or_default(text_filter)
251
+ end
252
+
253
+ def urls_to_ping_for(article)
254
+ urls_to_ping = []
255
+ ping_urls.gsub(/ +/, '').split(/[\n\r]+/).map(&:strip).delete_if { |u| article.already_ping?(u) }.uniq.each do |url|
256
+ urls_to_ping << article.pings.build('url' => url)
257
+ end
258
+ urls_to_ping
259
+ end
260
+
261
+ def has_twitter_configured?
262
+ return false if twitter_consumer_key.nil? || twitter_consumer_secret.nil?
263
+ return false if twitter_consumer_key.empty? || twitter_consumer_secret.empty?
264
+ true
265
+ end
266
+
267
+ def allow_signup?
268
+ allow_signup == 1
269
+ end
270
+
271
+ def shortener_url
272
+ custom_url_shortener.present? ? custom_url_shortener : base_url
273
+ end
274
+
275
+ private
276
+
277
+ def host_with_port
278
+ split_base_url[:host_with_port]
279
+ end
280
+
281
+ def split_base_url
282
+ unless @split_base_url
283
+ unless base_url =~ /(https?):\/\/([^\/]*)(.*)/
284
+ raise "Invalid base_url: #{base_url}"
285
+ end
286
+ @split_base_url = { protocol: Regexp.last_match[1], host_with_port: Regexp.last_match[2], root_path: Regexp.last_match[3].gsub(%r{/$}, '') }
287
+ end
288
+ @split_base_url
289
+ end
290
+ end
@@ -0,0 +1,86 @@
1
+ class BlogSweeper < ActionController::Caching::Sweeper
2
+ observe Blog, User, Article, Page, Comment, Trackback, Note, Tag
3
+
4
+ def pending_sweeps
5
+ @pending_sweeps ||= Set.new
6
+ end
7
+
8
+ def run_pending_page_sweeps
9
+ pending_sweeps.each do |each|
10
+ send(each)
11
+ end
12
+ end
13
+
14
+ def after_comments_create
15
+ expire_for(controller.send(:instance_variable_get, :@comment))
16
+ end
17
+
18
+ alias after_comments_update after_comments_create
19
+ alias after_articles_comment after_comments_create
20
+
21
+ def after_comments_destroy
22
+ expire_for(controller.send(:instance_variable_get, :@comment), true)
23
+ end
24
+
25
+ alias after_articles_nuke_comment after_comments_destroy
26
+
27
+ def after_articles_trackback
28
+ expire_for(controller.send(:instance_variable_get, :@trackback))
29
+ end
30
+
31
+ def after_articles_nuke_trackback
32
+ expire_for(controller.send(:instance_variable_get, :@trackback), true)
33
+ end
34
+
35
+ def after_save(record)
36
+ expire_for(record) unless record.is_a?(Article) && record.state == :draft
37
+ end
38
+
39
+ def after_destroy(record)
40
+ expire_for(record, true)
41
+ end
42
+
43
+ # TODO: Simplify this. Almost every sweep amounts to a sweep_all.
44
+ def expire_for(record, destroying = false)
45
+ case record
46
+ when Page
47
+ pending_sweeps << :sweep_pages
48
+ when Content
49
+ if record.invalidates_cache?(destroying)
50
+ pending_sweeps << :sweep_articles << :sweep_pages
51
+ end
52
+ when Tag
53
+ pending_sweeps << :sweep_articles << :sweep_pages
54
+ when Blog, User, Comment, Trackback
55
+ pending_sweeps << :sweep_all << :sweep_theme
56
+ end
57
+ run_pending_page_sweeps unless controller
58
+ end
59
+
60
+ def sweep_all
61
+ PageCache.sweep_all
62
+ end
63
+
64
+ def sweep_theme
65
+ PageCache.sweep_theme_cache
66
+ end
67
+
68
+ def sweep_articles
69
+ PageCache.sweep_all
70
+ end
71
+
72
+ def sweep_pages
73
+ PageCache.zap_pages(%w(pages))
74
+ end
75
+
76
+ def logger
77
+ @logger ||= ::Rails.logger || Logger.new(STDERR)
78
+ end
79
+
80
+ private
81
+
82
+ def callback(timing)
83
+ super
84
+ run_pending_page_sweeps if timing == :after
85
+ end
86
+ end