Compare commits

...

511 Commits

Author SHA1 Message Date
1db9d411c5 Merge pull request #1420 from modos189/v2_display_picture
improved display pictures
2015-09-14 17:15:40 +02:00
451bad02f0 improved display pictures 2015-09-14 02:12:39 +03:00
b004a236ba Merge pull request #1401 from wallabag/v2-baggy-themes
Cleanup baggy
2015-09-13 21:07:27 +02:00
1a5f7e2d88 A little more width for filter view 2015-09-13 19:53:09 +02:00
5e98404dfb Re-add preview picture on baggy
Which should has been removed on merge
2015-09-13 15:17:58 +02:00
463573bf69 Update deps 2015-09-13 15:07:15 +02:00
5def3f5862 Filters view on side for baggy 2015-09-13 14:56:34 +02:00
71e51207ce Fix tests 2015-09-13 14:56:34 +02:00
1137fae94d Lower domain search length
When searching for "bbc" I got no result .. sigh.
2015-09-13 13:35:12 +02:00
d2fcbf5d84 Handle filter form using some JS
Instead of displaying an ugly form
2015-09-13 13:35:12 +02:00
19c283140e Cleanup base layout 2015-09-13 13:35:12 +02:00
89ee994f77 Remove some global assets
Some global assets where dedicated to baggy
Remove some non-used css
2015-09-13 13:35:12 +02:00
a78d6afeaa Move baggy theme in its folder 2015-09-13 13:35:12 +02:00
4d5fd9be81 Merge pull request #1417 from wallabag/v2-display-picture
fix #972: add preview pictures
2015-09-13 11:41:23 +02:00
40f59b219b Merge pull request #1418 from wallabag/v2-previewpicture-filter
filter for entries with previewPicture
2015-09-13 10:14:42 +02:00
497e0cad7c add test for previewPicture filter 2015-09-13 10:11:22 +02:00
b026d3b115 add previewPicture on baggy theme 2015-09-13 10:03:53 +02:00
616f9fea26 forgot case for previewPicture filter 2015-09-13 08:43:15 +02:00
a3bcd60a37 filter for entries with previewPicture 2015-09-12 17:08:12 +02:00
fb96ea8845 Merge pull request #1362 from wallabag/v2-fosuser
implement FosUser
2015-09-12 16:13:40 +02:00
e610143f51 add preview pictures 2015-09-12 13:39:01 +02:00
af43bd3767 Fix tests
Ensure that created use during install command will always be unique.
We assume that the install command must be run to initialize a wallabag instance. NEVER to add more user.

Also, use a better way to retrieve the real name of the database and not the one defined in parameters.yml (which isn't the same for test envi because the dbname isn't defined in parameters.yml but directly in config_test.yml)
2015-09-12 11:36:16 +02:00
3f7a62908c fix tests for FosUser 2015-09-11 20:32:37 +02:00
a1691859ca implement FosUser 2015-09-11 20:32:37 +02:00
9c08a891f9 Merge pull request #1397 from wallabag/v2-graby
Integrate graby
2015-09-11 20:17:42 +02:00
f1e29e69cb CS 2015-09-10 22:00:53 +02:00
558d9aabab Move fetching content in a separate class 2015-09-10 21:57:25 +02:00
75c3478a0c Update deps 2015-09-10 15:09:44 +02:00
49e564ec15 Merge pull request #1403 from wallabag/v2-material-full-size-domain-filter
Use full size of the panel for domain-filtering
2015-08-26 07:13:11 +02:00
e643992350 typo 2015-08-26 00:24:33 +02:00
b125ed0394 Use full size of the panel for domain-filtering
For longer domains
2015-08-26 00:19:17 +02:00
c6da9bea71 Merge pull request #1400 from wallabag/v2-fix-1357
fix #1357, truncate domain name if it's too loooong
2015-08-25 07:51:55 +02:00
50243f0e34 fix #1357, truncate domain name if it's too loooong 2015-08-24 22:09:57 +02:00
d13de40db6 Update url from graby 2015-08-24 19:52:31 +02:00
a1413a3da9 CS 2015-08-24 12:35:02 +02:00
fad316151c Integrate graby 2015-08-24 12:27:17 +02:00
8c55a9e6c9 Merge pull request #1395 from wallabag/v2-fix-1378
fix #1378: nice display for tags list
2015-08-24 12:16:08 +02:00
230413bdd1 Merge pull request #1396 from wallabag/j0k3r-patch-1
Apply margin only on settings page
2015-08-24 12:04:24 +02:00
dc1c2debfb Apply margin only on settings page 2015-08-24 12:03:00 +02:00
a754db33c9 fix #1378: nice display for tags list 2015-08-24 11:59:53 +02:00
7083d183b9 Merge pull request #1392 from wallabag/v2-fix-redirect
Fix redirect after deletion
2015-08-24 10:44:14 +02:00
8bb1f3d69a Merge pull request #1393 from wallabag/fix-filter-same-day
Fix date filter on same day
2015-08-24 10:39:24 +02:00
f90af145ca Add test for same day filter 2015-08-23 22:06:27 +02:00
bccb5bba75 Merge pull request #1384 from wallabag/v2-fix-config-display
fix #1371 config screen: display bug in RSS tab
2015-08-23 13:17:21 +02:00
7d6c3edcdd Fix date filter on same day
Fix #1379
2015-08-22 15:36:07 +02:00
ec00964de2 Merge pull request #1372 from wallabag/v2-assign-tags
assign tags to an entry
2015-08-22 12:56:42 +02:00
7244d6cb61 assign tags to an entry 2015-08-22 12:40:48 +02:00
83aaf84195 Fix display issue in config rss tab 2015-08-22 12:30:06 +02:00
16a3d04cbd Fix redirect after deletion
Fix #1391
2015-08-22 12:09:27 +02:00
f9d5155abf Merge pull request #1390 from wallabag/coderating
Enable code rating on Scrutinizer
2015-08-21 18:11:52 +02:00
b45c188516 Enable code rating on Scrutinizer 2015-08-21 18:00:02 +02:00
f506da40e2 Merge pull request #1385 from wallabag/v2-status-filter
filters: implement status filter and a new view (to display all entries)
2015-08-21 17:49:20 +02:00
3b84dc08fc restore composer.lock 2015-08-21 11:02:22 +02:00
78f66dcc52 Merge pull request #1389 from wallabag/v2-fix-duplicate
remove dead code
2015-08-21 11:00:49 +02:00
c937de3443 remove dead code 2015-08-21 08:36:57 +02:00
2b7a488917 filters: adapt queryBuilder for 'all' view 2015-08-21 07:38:18 +02:00
e177976099 filters: add test for status filter and adapt other tests results 2015-08-21 07:30:48 +02:00
89659c9eae filters: implement status filter and a new view (to display all entries) 2015-08-21 07:30:48 +02:00
109d67dbb1 Merge pull request #1386 from wallabag/v2-refactor
WIP – Fixing things around 💨
2015-08-20 21:51:02 +02:00
6682139ec5 CS 2015-08-20 20:39:52 +02:00
e6f55346fd Add test on getting starred entries using the API 2015-08-20 20:39:26 +02:00
eccf5eb2e0 Add title in "picto-link"
Picto aren't always obvious for every one. So it's better to have some title when we move the mouse over.
2015-08-20 20:39:26 +02:00
1dbcd63b59 Update baggy about page
According to what have been done on the material theme
2015-08-20 20:39:26 +02:00
4793ee6509 Fixed my name & website 👌 2015-08-20 20:39:26 +02:00
6eebd8c909 Remove unsed things 2015-08-20 20:39:26 +02:00
0ab7404f93 Refactorize the way to retrieve entries
One place to retrieve entries in Entry & Rss controller.
More simple and easy to maintain.
2015-08-20 20:39:22 +02:00
4fcb7eaf13 Merge pull request #1383 from wallabag/cs
CS
2015-08-20 08:22:39 +02:00
8ce32af612 CS
We shouldn't forget to run `php-cs-fixer` time to time
2015-08-20 07:53:55 +02:00
34437f408c Merge pull request #1369 from wallabag/v2-bottombar
fix #1332: bottom bar to display message
2015-08-19 21:27:49 +02:00
ab4aeb8bd8 Merge pull request #1375 from wallabag/v2-fix-1371
fix #1368 config: redirect on correct tab in material theme
2015-08-19 21:26:29 +02:00
fdab81e910 warning bar: add parameter to dis/enable it 2015-08-19 16:00:15 +02:00
c3fdbcc60f Merge pull request #1374 from wallabag/v2-fix-filters-display
filters: enhance view for domain name
2015-08-19 15:32:38 +02:00
e62d27ff9b bottom bar to display message 2015-08-19 15:14:08 +02:00
8b8cdabc89 config: redirect on correct tab in material theme 2015-08-19 15:10:11 +02:00
bdd23b076a filters: enhance view for domain name 2015-08-19 14:55:39 +02:00
7b2d336893 Merge pull request #1342 from wallabag/v2-domain-filter
fix #981: add filter on domain name
2015-08-19 14:33:46 +02:00
443cecd2d8 add filter on domain name 2015-08-19 14:27:00 +02:00
b71ebd9af9 Merge pull request #1366 from wallabag/fix-tags-view
fix tag view in material theme
2015-08-19 12:02:24 +02:00
22ed64522a Merge pull request #1365 from wallabag/v2-typo-pagination
change </div> into </ul>
2015-08-19 11:21:31 +02:00
2e02b50409 Merge pull request #1367 from wallabag/v2-fix-actions-label
action labels depend on status
2015-08-19 11:20:22 +02:00
a3b4e8a2c0 Merge pull request #1363 from wallabag/v2-add-date-filter-view
add creation date filter view
2015-08-19 11:19:43 +02:00
d5e9a99ce6 Merge pull request #1370 from wallabag/v2-composer-cleanup
fix 1356: diet for composer
2015-08-19 11:19:04 +02:00
68568bf0b7 diet for composer 2015-08-18 21:53:11 +02:00
02947111c0 change </div> into </ul> 2015-08-18 18:20:07 +02:00
e68d9179a1 fix tag view in material theme 2015-08-18 18:18:35 +02:00
c713273619 action labels depend on status 2015-08-18 18:13:30 +02:00
3f357ee241 add test 2015-08-18 16:33:32 +02:00
c3cb46809b Merge pull request #1341 from wallabag/v2-capistrano
capistrano config
2015-08-18 16:14:23 +02:00
72ea6dd1a7 add creation date filter view 2015-08-18 15:26:45 +02:00
54f2b4a254 Merge pull request #1353 from wallabag/v2-pluriel
check if one entry or not
2015-08-18 14:29:10 +02:00
3162601c59 Merge pull request #1343 from wallabag/v2-filter-date
[WIP] filter by creation date
2015-08-18 14:28:43 +02:00
6819604185 Merge pull request #1354 from wallabag/v2-clean
some cleanup
2015-08-18 09:11:40 +02:00
f967422fae Update CONTRIBUTING.md 2015-08-18 08:49:42 +02:00
428af5a8c3 usage of transchoice 2015-08-18 08:32:50 +02:00
fd72e99d53 remove capistrano in gitignore 2015-08-18 08:26:41 +02:00
2a2903ceaa some cleanup 2015-08-17 23:31:10 +02:00
fac3f8abfa Merge pull request #1355 from wallabag/v2-clear-button
clean -> clear
2015-08-17 23:22:24 +02:00
e40ff14d7d Merge pull request #1358 from wallabag/nicosomb-patch-1
Disable external_code_coverage on Scrutinizr
2015-08-17 23:21:59 +02:00
a2cdaa8cdd disable external_code_coverage 2015-08-17 23:11:20 +02:00
4a230f9844 change timeout because scrutinizer failed 2015-08-17 21:39:07 +02:00
5f246a5543 clean -> clear 2015-08-17 20:12:11 +02:00
2ba06b1ee2 check if one entry or not 2015-08-17 18:02:54 +02:00
3c5b025ac3 filter by creation date 2015-08-17 15:54:49 +02:00
ceb79aa016 capistrano config 2015-08-17 15:36:27 +02:00
925d8ab316 Merge pull request #1337 from modos189/v2_material
fixes material
2015-08-17 15:32:59 +02:00
d5b28518e9 fix 2015-08-17 16:30:30 +03:00
0a3a5f6cd7 Merge pull request #1352 from wallabag/v2-fix-pagination
fix #1350: fix pagination with filters
2015-08-17 15:19:35 +02:00
ab2c93c7eb add test 2015-08-17 15:15:51 +02:00
727b39a90e Fix calendar in chromium and reducing the size of the calendar 2015-08-17 15:43:44 +03:00
c14a7c4251 fix #1350: fix pagination with filters 2015-08-17 12:13:37 +02:00
c37381b946 Merge pull request #1349 from wallabag/v2-add-original-link
add link to original article in material theme
2015-08-17 09:20:41 +02:00
790d18a319 GUI for filter by creation date #1343 2015-08-17 03:12:14 +03:00
6fd3d82c01 Hide open menu on page reading articles 2015-08-17 02:02:55 +03:00
fcb3faf109 My implementation progress bar at the top of the page #1348 2015-08-17 01:50:46 +03:00
d75a9fa38b Fix:
When I click on "new article" icon, and on the cross after, the filter icon is no more visible.
    When I change the size of my browser window, the filter appears but I didn't click on the icon
    Bug: can't click on pagination > 1
    display bug: when we load homepage, we see quickly the filter form
    new entry form: when we click on the field, the history of the field is at the left of the screen, not below the field (see screenshot)
2015-08-17 01:29:51 +03:00
0e7cf1fc50 Merge remote-tracking branch 'origin/v2' into v2_material 2015-08-17 00:33:03 +03:00
9cc6bd87fe add link to original article in material theme 2015-08-16 21:05:37 +02:00
80127e4fb1 Merge pull request #1338 from wallabag/v2-add-titles
change title for material pages / about page
2015-08-13 11:53:34 +02:00
4ca0c9139c fix diaspora url 2015-08-13 09:18:41 +02:00
a64f1d9f2d change title for material pages / about page 2015-08-13 09:16:22 +02:00
bac5a34552 Fix form rendere 2015-08-12 23:52:40 +03:00
a737d2a0ee Merge remote-tracking branch 'origin/v2' into v2_material 2015-08-12 23:02:19 +03:00
545b852f46 Merge pull request #1331 from wallabag/v2-disable-download
disable download links on entry view
2015-08-12 21:58:46 +02:00
392f4a2681 #1320 Design for filters 2015-08-12 22:55:44 +03:00
120544cccd disable download links on entry view 2015-08-12 21:52:39 +02:00
82b07eb272 Merge pull request #1334 from wallabag/v2-store-domainname
store domainName in database
2015-08-12 21:45:21 +02:00
c2257428b2 store domainName in database 2015-08-12 21:16:00 +02:00
8ba913d87a improved view 2015-08-12 20:27:30 +03:00
06fdfd025e fix #1321 2015-08-12 19:18:31 +03:00
d990dc6f05 Merge pull request #1328 from wallabag/v2-fix-1324
fix #1324: do not display pagination when only 1 page
2015-08-12 14:12:08 +02:00
bdf39ff10d remove pagination if page == 1 with baggy theme 2015-08-12 14:06:56 +02:00
2ac2e0bc2b fix #1324: do not display pagination when only 1 page 2015-08-12 14:05:53 +02:00
1a0ea1f35a Merge pull request #1326 from wallabag/v2-fix-1299
fix #1299: change send buttons on config page
2015-08-12 13:42:32 +02:00
43e6f47d5b fix #1299: change send buttons on config page 2015-08-12 13:35:48 +02:00
9f1d650ae8 Merge pull request #1325 from wallabag/v2-fix-1314
fix #1314: change max-width in material theme
2015-08-12 13:31:34 +02:00
b69fc0628a fix #1314: change max-width in material theme 2015-08-12 13:26:49 +02:00
a8596c35c8 Merge pull request #1323 from wallabag/v2-1302-checkbox
fix #1302: add 'stay connected' checkbox
2015-08-12 13:23:52 +02:00
a15692b1b7 Merge pull request #1312 from wallabag/v2-fix-1311
fix #1311, redirect after login
2015-08-12 13:21:16 +02:00
6622cf9968 add translation 2015-08-12 13:21:07 +02:00
7fc14130c7 add test 2015-08-12 13:18:39 +02:00
579764b264 fix indentation 2015-08-12 13:03:26 +02:00
3e1f25e22f Merge pull request #1322 from wallabag/v2-fix-1303
fix #1303, add link to homepage on forgot password page
2015-08-12 12:43:02 +02:00
5a58461491 add 'stay connected' checkbox 2015-08-12 12:27:12 +02:00
773ed2e7a6 fix #1303, add link to homepage on forgot password page 2015-08-12 12:16:50 +02:00
496f21e6fa Merge pull request #1319 from wallabag/v2-form-header
add new post form in material header
2015-08-12 10:14:44 +02:00
053b9568b2 add new post form in material header 2015-08-12 09:52:36 +02:00
930334cd6d Merge pull request #1297 from wallabag/v2-estimated-time
store estimated reading time in database (#393)
2015-08-12 09:05:21 +02:00
2686457448 store estimated reading time / filters on reading time 2015-08-12 09:01:29 +02:00
fedaf00537 Merge pull request #1317 from wallabag/v2-fix-typo
fix link in howto page
2015-08-11 21:26:31 +02:00
ea8da8c6d5 fix link in howto page 2015-08-11 21:12:08 +02:00
95135988f9 Merge pull request #1316 from wallabag/v2-focus-searchform
fix #1310 add focus to search form
2015-08-11 20:00:30 +02:00
d85454fbf8 add focus to search form 2015-08-11 18:07:02 +02:00
728a432850 fix #1311, redirect after login 2015-08-10 22:37:56 +02:00
f59601fced Merge pull request #1298 from modos189/v2_fix_material
fix material
2015-08-10 19:35:23 +02:00
0e654f6273 Merge remote-tracking branch 'origin/v2' into v2_fix_material
# Conflicts:
#	src/Wallabag/CoreBundle/Resources/views/themes/material/base.html.twig
2015-08-10 15:25:23 +03:00
f48a018929 Merge pull request #1295 from wallabag/v2-howto
add howto page
2015-08-10 14:15:11 +02:00
b958d9e59b remove useless line 2015-08-10 14:13:23 +02:00
4919584b87 Merge remote-tracking branch 'origin/v2' into v2_fix_material
# Conflicts:
#	src/Wallabag/CoreBundle/Resources/views/themes/material/base.html.twig
2015-08-10 12:27:12 +03:00
1473e8c9fb add tests for static pages 2015-08-10 08:19:40 +02:00
47cadf36c8 Merge pull request #1292 from wallabag/v2-tags-route
Add tags list display
2015-08-09 22:47:28 +02:00
20a69dffe7 Merge pull request #1304 from wallabag/v2-rename-starred-menu
rename favorite in starred
2015-08-09 20:47:13 +02:00
009696d0a8 rename favorite in starred 2015-08-09 20:31:53 +02:00
e9d5c2bf02 Merge pull request #1296 from wallabag/v2-fix-564
fix #564: replace Untitled by the domain name
2015-08-08 20:58:03 +02:00
946d6a5124 Preparation for adding links 2015-08-08 01:30:52 +03:00
a6523cfe86 fix #1281 2015-08-08 00:16:14 +03:00
c54ea989a3 fix #1281 (notifications when we star articles are buggy)
All notification corrected
2015-08-08 00:08:29 +03:00
342f0cc55a fix #1281 (When I save 10 articles, I've got 4 lines: 3 articles on 1st line, 3 on 2nd one, only 1 on 3rd line and 3 on last lines (chrome and firefox)) 2015-08-08 00:00:11 +03:00
0e7650683d Title in navigation bar 2015-08-07 23:59:11 +03:00
768303a573 fix #1282 2015-08-07 23:29:21 +03:00
0bc2baa65c fix #564: replace Untitled by the domain name 2015-08-07 21:57:53 +02:00
b7dd5f824c add howto page 2015-08-07 21:22:43 +02:00
54139268f8 Merge pull request #1294 from wallabag/v2-fix-1282
fix #1282: add title on wallabag logo
2015-08-07 20:56:45 +02:00
44a16e82d8 fix #1282: add title on wallabag logo 2015-08-07 20:47:19 +02:00
d0b90fbe18 unit test 2015-08-07 20:29:03 +02:00
55333dfd21 Merge pull request #1293 from wallabag/v2-items-per-page
get itemsPerPage for unread/fav/archive views
2015-08-07 20:10:07 +02:00
47e12c3677 fix display 2015-08-07 20:07:39 +02:00
3f3fbef11f Add tags list display 2015-08-07 18:17:23 +02:00
48ffc5a4b6 get itemsPerPage for unread/fav/archive views 2015-08-07 18:04:46 +02:00
6ecdd48a3f Merge pull request #1286 from wallabag/v2-issue-1283
fix #1283: display the good title for each category
2015-08-06 04:38:04 +03:00
b17874a7d5 Many corrections material theme 2015-08-06 04:22:45 +03:00
308db01684 change order of condition 2015-08-05 21:16:48 +02:00
b1a65df9df fix #1283: display the good title for each category 2015-08-05 21:10:20 +02:00
8d9b8912af Merge pull request #1279 from wallabag/material-default
set material to default theme \o/
2015-08-04 23:13:15 +02:00
4ab58dcf6c set material to default theme \o/ 2015-08-04 22:51:21 +02:00
9e07dc982c Merge pull request #1276 from modos189/v2
Added Material theme
2015-08-04 22:42:33 +02:00
9948d899d3 Fixes and improve css @media 2015-08-04 19:39:26 +03:00
53e121881b Added Material theme 2015-08-04 17:18:15 +03:00
7e63b892f9 Merge pull request #1250 from frankoa/v2_pagination_and_api
Adds pagerfanta paginator everywhere, modifies article routing.
2015-07-29 09:02:30 +02:00
9fb6ac830f Adds pagerfanta paginator everywhere, modifies article routing. Change API for is_starred and is_archived 2015-07-28 23:23:49 +02:00
9b9b05008a Merge branch 'v2-edit-title' into v2 2015-06-08 16:35:41 +02:00
ac9d58211e Merge branch 'v2' into v2-edit-title 2015-06-08 16:35:02 +02:00
3cf22a0541 Merge pull request #1206 from wallabag/sf-2.7
Upgrade to Symfony 2.7
2015-06-03 21:24:11 +02:00
82d6d9cb06 Add basic title edition
Fix #218
I mean basic, because there is no javascript at all. It could be a nice edit-in-place. But for the moment, it is simple.
2015-06-02 18:56:07 +02:00
75e9d1df03 Update to Symfony 2.7
And fix some deps instead of using dev tags
2015-06-02 16:58:19 +02:00
170746f99d Remove phinx
Doctrine handle quite correctly database migration. Thanks to `doctrine:schema:update`
2015-06-02 16:54:52 +02:00
51d9699fa1 Update deps 2015-06-01 17:39:05 +02:00
2878416f8b Merge pull request #1167 from wallabag/v2-api-bundle
Move API stuff in ApiBundle
2015-06-01 15:49:49 +02:00
4346a86068 CS 2015-05-30 13:59:33 +02:00
399bd777d7 Update deps 2015-05-30 13:42:38 +02:00
2f3c816579 Update naming strategy since Doctrine 2.5
See 20fb8270dc
2015-05-30 13:40:39 +02:00
9a014e48d6 Disable coverage
It takes ages to process and most of the time the build fail for "execution time" too long.
Too much time already burned to investigate it.
We'll investigate later, it's not a priority atm.
2015-05-30 13:31:54 +02:00
98510a4189 Merge pull request #1180 from wallabag/v2patch
Add some required
2015-04-15 17:29:28 +02:00
c7d3bf1671 name not required 2015-04-15 17:19:37 +02:00
4d6e818e40 changed email fields with the email type and added required parameter on some stuff 2015-04-15 16:50:20 +02:00
1cbef2d3b5 Enable debug on phpunit 2015-04-04 21:55:06 +02:00
04aaa199b7 Add Travis & Scrutinizer badges 2015-04-02 11:45:53 +02:00
132f614dee Avoid / in feed token
Of course, it breaks the url and the route matcher for each feed route
2015-04-01 21:59:13 +02:00
9744e97131 Fix tests 2015-04-01 21:59:13 +02:00
769e19dc4a Move API stuff in ApiBundle 2015-04-01 21:59:12 +02:00
e3c34bfc06 Merge pull request #1164 from wallabag/v2-remove-username-in-config
Remove ability to change username
2015-04-01 21:58:08 +02:00
d6fa2f70ac Merge pull request #1165 from wallabag/v2-prefix-db
Prefix table
2015-04-01 21:53:48 +02:00
276a1e9d3f And phpunit with html coverage to ant
Launching `ant phpunit` will now generate HTML Coverage
2015-04-01 21:32:02 +02:00
164bd80118 Ability to prefix tables
Will fix #799
2015-04-01 21:32:02 +02:00
c844dc0c50 Remove ability to change username
Since password are linked to username it was hard to change username while checking that the password is the good one.

Instead of doing crazy things to achieve that, I act that user won't be able to update username.

Also, username (and email) must be unique, since people logged in using username and can request a new password using email.

This should fix #1149
2015-04-01 21:23:27 +02:00
1a93ee423b Merge pull request #1166 from wallabag/v2-rss
Add RSS feeds
2015-04-01 21:08:56 +02:00
7d74a2f32b Force raw on content
We don't want Symfony to escape html content
2015-04-01 16:11:19 +02:00
14d7a69b8c Avoid timeout on code coverage from Scrutinizer 2015-03-31 22:48:01 +02:00
34c06cabef Use lemonde instead of mailjet
Mailjet seems to be laggy, hope that LeMonde will be more reliable in the future.

@see https://travis-ci.org/wallabag/wallabag/jobs/56246231
2015-03-31 22:48:01 +02:00
0ee043f745 Update InstallCommand test
They are god damn too long to execute because it launch external command (mostly related to doctrine).

So I've added a PHPUnit @group (`command-doctrine`) so that we can avoid launching them on a regular basis, like that:

`phpunit --exclude-group command-doctrine`
2015-03-31 22:48:01 +02:00
371ac69a6b Add tests
and fix few mistakes
2015-03-31 22:48:00 +02:00
2385f891e5 Sort by id is faster
Since it's the primary key
2015-03-31 22:47:43 +02:00
0c83fd5994 Add rss for entries
will fix #1000
2015-03-31 22:47:43 +02:00
f98a2a0fc3 Merge pull request #1152 from wallabag/v2-forgot-password
Handle forgot password
2015-03-30 17:05:37 +02:00
bdf2add2e8 Merge pull request #1163 from wallabag/v2-speed-up-tests
Speed up tests
2015-03-28 10:46:33 +01:00
3e6b7ea0e9 Rewrite travis & add scrutinizer 2015-03-28 00:25:47 +01:00
6141388969 Enable hhvm & nightly for curiosity 2015-03-27 19:59:45 +01:00
2d733277e6 Switch to Docker-based infrastructure 2015-03-27 19:59:42 +01:00
a05be8abec Use doctrine cache for tests 2015-03-27 19:49:11 +01:00
d0c2243b10 Add some tests 2015-03-08 22:47:32 +01:00
6894d48e03 Handle forgot password 2015-03-08 07:35:24 +01:00
f37d1427a1 Merge pull request #1110 from wallabag/v2-api-hypermedia
[WIP] API : hypermedia & tags
2015-03-06 21:48:33 +01:00
6e22bd737b Use pager in getEntries() and return Hateoas collection 2015-03-06 21:11:02 +01:00
bcf53ab75b Return pager into EntryRepository (for entries only) 2015-03-06 21:11:01 +01:00
a24f2c8808 Add Pagerfanta 2015-03-06 21:11:01 +01:00
48b67328e2 add getUser on Tag entity 2015-03-06 21:09:15 +01:00
efad7e53a1 add more log on AccessDeniedException 2015-03-06 21:09:15 +01:00
2ab8cb6816 fix tests 2015-03-06 21:09:15 +01:00
db2b4bf678 remove JsonResponse 2015-03-06 21:09:15 +01:00
b0cce9e636 fix tests for GET /entries/tags 2015-03-06 21:09:15 +01:00
1df1204d94 remove useless code 2015-03-06 21:09:15 +01:00
6ee416a069 commit bug with getSalt 2015-03-06 21:09:15 +01:00
0ca374e6a1 replace Response with JsonResponse 2015-03-06 21:09:15 +01:00
d8f9f37ab2 remove debug lines 2015-03-06 21:09:15 +01:00
092ca70725 add relation between user and tags, tests are broken 2015-03-06 21:09:15 +01:00
a36737f485 POST entries/tags with test 2015-03-06 20:50:31 +01:00
46bbd8d321 relation between tags and entries 2015-03-06 20:50:31 +01:00
6c87418ff0 fixtures for tag 2015-03-06 20:50:30 +01:00
1bd12b6229 fix GET /api/entries/{entry}/tags 2015-03-06 20:50:30 +01:00
0a018fe039 add relation between entry and tag 2015-03-06 20:50:30 +01:00
6d37a7e6c1 remove dumb code 2015-03-06 20:50:30 +01:00
b3dc0749d3 remove GET /tags/id 2015-03-06 20:50:30 +01:00
2691cf0438 GET /api/tags/id_tag method 2015-03-06 20:50:30 +01:00
1d14779154 remove isDeleted flag 2015-03-06 20:50:30 +01:00
aa4d6562c1 improve hateoas implementation 2015-03-06 20:50:30 +01:00
0ed6302212 returns serialzed object for GET /entries 2015-03-06 20:50:30 +01:00
0f00688096 first draft of hypermedia implementation 2015-03-06 20:50:29 +01:00
73b7744383 Merge pull request #1144 from wallabag/v2-build
Simplify build system
2015-03-04 06:25:17 +01:00
8378485e33 Simplify build system 2015-03-03 19:20:08 +01:00
ba7b9d48d4 Merge pull request #1132 from wallabag/v2-theme
V2 theme
2015-03-02 21:23:19 +01:00
3e30422cda Only one pattern for LiipTheme
Others patterns aren't required (but I think it's still important to have them around)
2015-03-01 20:25:43 +01:00
495aecfe74 Cleanup & simplify theme 2015-03-01 10:49:17 +01:00
71798e4ec4 Remove old themes 2015-03-01 10:49:16 +01:00
32da2a70ef Add LiipThemeBundle
Re-defined the config / user relation to be OneToOne bidirectionnal.
ConfigType is now a service so I can inject the list of available themes that are also used by LiipThemeBundle

Force sqlite for test
In case of people use a different driver in parameter.yml (yes I do :))
2015-03-01 10:49:16 +01:00
fca3c75723 config for CORS 2015-02-28 13:14:43 +01:00
dcae2fc25d enable CORS 2015-02-27 21:26:43 +01:00
0e7971d835 Merge pull request #1095 from wallabag/v2-config
V2 config
2015-02-23 20:56:09 +01:00
c641baad0e More tests on the install command 2015-02-22 23:29:48 +01:00
732c2ad897 sqlite doesn't support getListDatabasesSQL 2015-02-22 17:18:54 +01:00
0bf99bb144 Improve install command & add test
Also add fixtures for Config

InstallCommand now check if database, schema are here and ask the user what to do (keep or trash & re-create)
2015-02-22 14:35:36 +01:00
0bd2cb1ecd Handle default value for new user 2015-02-22 10:50:27 +01:00
e4977b8a86 Adding new user 2015-02-22 09:30:25 +01:00
c0d9eba07f Updating logged in user (email, name, etc ..) 2015-02-17 22:45:20 +01:00
d9085c63e3 Handle password change 2015-02-17 21:03:23 +01:00
7781faa0b0 Use a form type for entry 2015-02-16 21:31:58 +01:00
78cedc2262 Cleanup 2015-02-16 21:31:58 +01:00
4d85d7e9ba Implement simple config 2015-02-16 21:31:58 +01:00
7a577c519f Fix indentation in templates 2015-02-16 21:31:58 +01:00
55f58c9c5e Update UserConfig schema 2015-02-16 21:31:58 +01:00
2f6a596760 Merge pull request #1070 from wallabag/v2-api-tests
1st draft for testing API
2015-02-12 08:50:06 +01:00
8c7e0f95b9 remove debug lines 2015-02-12 08:46:40 +01:00
d9b7175593 test if GET /api/entries returns 1 or more results 2015-02-11 18:22:59 +01:00
59f18f9a85 create single test for bad headers 2015-02-11 16:08:13 +01:00
9ca5fd43f9 test with bad headers 2015-02-11 15:35:40 +01:00
f170f31594 add test for empty salt 2015-02-11 15:15:06 +01:00
874e3e10a4 phpdoc 2015-02-11 11:52:10 +01:00
f8c2736a10 remove docs 2015-02-11 09:39:42 +01:00
70b54da2b1 test line, forgot to remove it 2015-02-11 07:52:58 +01:00
c9fa9677c1 DELETE entry and use of query for fetch entries 2015-02-11 07:43:43 +01:00
fa8d563934 Merge pull request #1072 from wallabag/v2-entry-test
Add more tests to Entry controller + security
2015-02-11 06:45:14 +01:00
19aee7cd54 refactor and test one entry 2015-02-11 06:41:44 +01:00
2725de8efb cs 2015-02-11 06:31:16 +01:00
91f78f26f2 first test for API, need refactor 2015-02-11 06:28:23 +01:00
2734044aca add test for api/salts 2015-02-11 06:28:23 +01:00
0536b809b0 Test for GET on empty database 2015-02-11 06:27:50 +01:00
e1dd7f70c5 first test for API, need refactor 2015-02-11 06:27:05 +01:00
f5deb024a2 add test for api/salts 2015-02-11 06:27:04 +01:00
68c6f1bd7f Test for GET on empty database 2015-02-11 06:27:04 +01:00
da93261a7d Quick fix in build.xml
We don't need to purge the database since it was just re-created
2015-02-10 22:56:48 +01:00
3d2b2d62be Avoid user to see other entries
hehe :)
2015-02-10 22:56:44 +01:00
eb3bd7efb7 Add more tests on Entry controller
Also add more fixtures
2015-02-10 22:32:42 +01:00
f59f45d740 Merge pull request #1069 from wallabag/v2-fix-return-entries
GET /api/entries returns object, no more array
2015-02-10 14:51:32 +01:00
017e20895f findEntries returns array 2015-02-10 13:53:00 +01:00
2c0ffcf397 Merge pull request #1068 from wallabag/v2-api-authentication
V2 api authentication
2015-02-10 13:49:57 +01:00
3d3368cfd5 change test if we have no entry in GET /api/entries 2015-02-10 13:47:57 +01:00
92504e0dd4 move dir check into constructor 2015-02-10 13:35:34 +01:00
11204db45a change phpdoc 2015-02-10 12:14:09 +01:00
d4c029f46e review from @j0k3r 2015-02-10 12:12:44 +01:00
c5e8ba25bb getSalt method 2015-02-10 08:35:43 +01:00
eaf95758dc GET /api/entries returns object, no more array 2015-02-10 06:44:38 +01:00
7ffb1e80bf replace services.xml into services.yml 2015-02-09 22:54:29 +01:00
5078e8360a PSR 3 2015-02-09 22:43:06 +01:00
d29bfaf139 fix return on API call and fix id in clear for user 2015-02-09 22:40:20 +01:00
2a94b1d1b7 log for authentication on API 2015-02-09 22:07:39 +01:00
cbce162b40 Merge pull request #1063 from wallabag/v2-rename-tags-entity
Rename Tags entity
2015-02-09 15:52:10 +01:00
fb8389f463 change settings for TagsEntries model 2015-02-09 15:41:07 +01:00
970c40bb93 restore TagsEntries 2015-02-09 15:07:48 +01:00
0ac38198ab authentication on API 2015-02-09 13:59:48 +01:00
653e8be4c1 rename Tags entity
why did I delete this file?

rename Tags entity

rename Tags entity
2015-02-09 12:58:44 +01:00
89c03230c3 Merge pull request #1062 from wallabag/v2-relation-entry-user
add a real relation between user and entry
2015-02-09 12:52:06 +01:00
3b815d2de5 Add some fixtures
Improve test, so user can login
Fix some leftJoin
Cleanup EntryController
2015-02-08 23:13:40 +01:00
d91691573f Add custom auth encoder & provider
These custom classes allow Wallabag v2 to be compatible with Wallabag v1 salted password
2015-02-08 23:13:40 +01:00
7812f508bc create an Entry with a User in parameter 2015-02-08 23:13:40 +01:00
5f09650eef add a real relation between user and entry 2015-02-08 23:13:40 +01:00
8af35ad932 Merge pull request #1066 from wallabag/v2-api-tests-entry
V2 api tests entry
2015-02-07 20:39:03 +01:00
9c0c882006 Add some tests on EntryController
Also, create database schema on test initialisation
2015-02-07 18:30:46 +01:00
94f2364cd8 Fix #1057
Unexisting function
2015-02-07 18:29:05 +01:00
8125b415d8 Avoid raw javascript in template
It kills the Symfony Crawler :)
2015-02-07 18:28:31 +01:00
d01db0c71d Update deps 2015-02-06 22:52:51 +01:00
ed4d5cf2d7 Merge pull request #1065 from FabienM/v2-bundles-cleanup
Cleanup default assets symlinks
2015-02-06 22:43:19 +01:00
427b61a35b Cleanup default assets symlinks 2015-02-06 22:36:02 +01:00
7f2d9f9613 Do not display download progress in Travis 2015-02-06 15:38:10 +01:00
c64a14787d Merge pull request #1061 from wallabag/v2-cleanup-entities
Remove temporary entities
2015-02-06 14:56:47 +01:00
02b225a82e Remove temporary entities 2015-02-06 14:26:37 +01:00
15d33c24dc Merge pull request #1060 from wallabag/api-rename-user
rename User entity
2015-02-06 14:23:55 +01:00
2f69eb4afa rename User entity 2015-02-06 14:18:01 +01:00
29c4517f7a Merge pull request #1059 from wallabag/rename-entry
Rename entry
2015-02-06 09:55:16 +01:00
be463487cc rename Entries to Entry 2015-02-06 07:45:32 +01:00
905ae369bd normalize entries fields 2015-02-05 22:33:36 +01:00
c8dee95396 Merge pull request #1055 from wallabag/v2-api-patch-methid
PATCH method, boolean for some parameters and change entity methods name
2015-02-05 21:51:05 +01:00
c0284f6182 remove persist() for PATCH and DELETE 2015-02-05 21:36:39 +01:00
93e28e4d2e remove unused files 2015-02-05 21:33:22 +01:00
5644c2d88e Merge pull request #1054 from wallabag/v2-api-set-title-post
we can now set a title to the article when we use POST /api/entries
2015-02-05 19:07:30 +01:00
de00c9208d Merge pull request #1048 from wallabag/v2-sort-entries
sort entries in repository
2015-02-05 19:06:48 +01:00
2c093b03de PATCH method, boolean for some parameters and change entity methods name 2015-02-05 18:21:31 +01:00
9e0fff7cb0 simplify code 2015-02-05 18:19:34 +01:00
77bb7b92a2 we can now set a title to the article when we use POST /api/entries 2015-02-05 18:05:27 +01:00
3bb7c5ffec Update branch name in README 2015-02-05 09:19:17 +01:00
c2e2906c8d fix travis configuration 2015-02-05 09:06:13 +01:00
bc782eaa72 sort entries in repository 2015-02-05 07:54:04 +01:00
34d15eb4d0 change database structure for Entries 2015-02-04 22:25:44 +01:00
1b0e6e9ae6 forgot one parameter 2015-02-04 21:34:03 +01:00
61b9fdd5e4 restore full database settings 2015-02-04 21:26:15 +01:00
eacaf7f864 change type for isRead, isFav and isDeleted fields, as said @j0k3r 2015-02-04 18:21:45 +01:00
6079aaa33d change delete status for GET /api/entries method 2015-02-04 18:12:13 +01:00
6e334aba68 for GET /api/entries, star, delete and archive status are no more necessary 2015-02-04 18:06:42 +01:00
42a9064620 implement delete method 2015-02-04 17:54:23 +01:00
889249804f disable authentication for the moment 2015-02-02 12:54:14 +01:00
c5772d118f Installation should be launch manually
Also upadte readme for v2 and define a test database (for the future)
2015-02-02 07:48:16 +01:00
2e45e7bebc New wallabag installer
Instead of the legacy bin/install here is a symfony command that can initialize wallabag.

There are still work to do on the requirements part (to be sure that wallabag can run like a charm).

I've also added (but commented) the fixtures load part (which will need an extra doctrine package). We'll see that point later.
2015-02-01 20:16:27 +01:00
8394ab4619 Merge pull request #1036 from j0k3r/refactor-update-composer
Update composer
2015-01-31 21:49:44 +01:00
4cfbd5d893 Merge pull request #1037 from j0k3r/refactor-cs
CS
2015-01-31 21:24:20 +01:00
7df80cb32c CS 2015-01-31 19:12:49 +01:00
daacffefa6 Use tagged version in composer 2015-01-31 19:02:59 +01:00
1990517b22 remove Acme and AppBundle 2015-01-31 15:36:04 +01:00
c3235553dd first implementation of security 2015-01-31 15:14:10 +01:00
71691fe44a Merge pull request #1035 from j0k3r/refactor
Tests are working again
2015-01-31 10:29:30 +01:00
aa6e27cf4f Tests are working again 2015-01-31 09:35:50 +01:00
4ffc77d9f5 Move phpunit into app folder 2015-01-30 15:47:27 +01:00
fdcbdda1ad grrr, remove call to bootstrap 2015-01-30 11:29:50 +01:00
367664ee87 finally fix phpunit and travis? 2015-01-30 11:23:18 +01:00
e11e03cb32 fix phpunit 2015-01-30 10:58:59 +01:00
3ba208b205 fix phpunit configuration 2015-01-30 10:49:47 +01:00
127915f4ea remove bootstrap in phpunit 2015-01-30 09:11:59 +01:00
03493be075 tell to travis that I code in PHP 2015-01-30 09:09:53 +01:00
843dbe5195 create entry via API 2015-01-30 09:05:54 +01:00
a8c90c5c1b add documentation for API 2015-01-30 07:50:52 +01:00
a65f5d5563 fix config for rest bundle 2015-01-29 21:49:44 +01:00
27f15aa4ca improve API 2015-01-29 20:32:11 +01:00
f8bf895254 routing for API, trying to respect #414 2015-01-29 16:56:58 +01:00
589dce52c6 disable dev environment 2015-01-28 21:28:12 +01:00
38ba7ed972 skeleton for DELETE and PATCH methods 2015-01-28 18:18:57 +01:00
3e5a342f65 bundle for API 2015-01-28 18:14:04 +01:00
e4788de51e 1st implementation of wallabag api, yeah 2015-01-28 17:09:27 +01:00
569f8d6851 add dependencies for API 2015-01-28 16:15:06 +01:00
19f2f11ee8 fix themes symlinks 2015-01-28 13:58:12 +01:00
9e11bfa4a6 wrong path for database file 2015-01-28 13:54:24 +01:00
7dfc3c2b58 fix config.yml 2015-01-28 13:46:51 +01:00
80709502c7 fix parameters config 2015-01-28 13:43:23 +01:00
2cdb0b8f40 change gitignore, last time, I promised 2015-01-28 13:28:12 +01:00
b2d9357c78 change gitignore 2015-01-28 13:27:00 +01:00
c4b1e79018 change gitignore 2015-01-28 13:26:36 +01:00
dc61832a9e change gitignore 2015-01-28 13:23:07 +01:00
33767049a5 change gitignore 2015-01-28 13:10:59 +01:00
0c678cf24a rename test file 2015-01-27 13:17:37 +01:00
b9ec99e25b replace legacy calls with new one 2015-01-27 13:08:02 +01:00
d692b3b08d remove legacy code 2015-01-27 13:07:27 +01:00
6b767d1cc0 refactoring for fetching content 2015-01-26 22:15:19 +01:00
ad4d1caa9e move WallabagBundle into Wallabag:CoreBundle 2015-01-23 16:28:37 +01:00
b84a80559a some parameters, new entry form, etc. 2015-01-23 14:58:17 +01:00
163eae0bb1 toggle archive / fav actions 2015-01-23 12:45:24 +01:00
bd9f08157c article view, fav list, archive list 2015-01-22 21:11:22 +01:00
9d50517cea migrating legacy to symfony 2015-01-22 17:18:56 +01:00
2b9fe72b39 remove foo test 2015-01-22 10:14:37 +01:00
93fd4692f6 symfony is there 2015-01-22 08:30:07 +01:00
0440249631 move templates into resources 2015-01-21 16:04:05 +01:00
3eb951572d add some documentation at the end of installation 2015-01-21 15:50:51 +01:00
9de6a0a7cc gitignore for app/cache 2015-01-21 15:02:29 +01:00
19875ef0da add install script after composer install 2015-01-21 14:45:39 +01:00
00fcfd299b whoops, deleted install folder 2015-01-20 14:43:57 +01:00
79e051a1f2 restructure folders 2015-01-20 14:11:26 +01:00
97a2dd74c8 phinx needs a sqlite3 file 2015-01-20 07:51:07 +01:00
8d6ff10e8e test for migration 2015-01-20 07:50:50 +01:00
9a5c1bc62a move install files into bin folder 2015-01-20 07:42:20 +01:00
6ad93dff69 new folders 2015-01-20 07:40:39 +01:00
c78c1a3f08 @fivefilters via composer 2015-01-19 21:27:22 +01:00
9e7f6caf03 htmlawed via composer 2015-01-19 16:53:59 +01:00
820d81aa61 simplepie via composer 2015-01-19 14:48:03 +01:00
3329f1bf3d tcpdf via composer 2015-01-19 14:36:17 +01:00
90c67dbd12 update composer.lock 2015-01-19 13:50:31 +01:00
96b2c59c04 update composer 2015-01-19 13:38:57 +01:00
3d99ce9dad travis configuration 2015-01-19 13:37:32 +01:00
99410a21eb phpepub via composer 2015-01-19 13:00:33 +01:00
1345a10788 phinx for database migration 2015-01-19 12:21:49 +01:00
f3052b4542 foo test 2015-01-19 11:59:22 +01:00
e342acf7ba add phpunit 2015-01-19 11:47:44 +01:00
2b17e0aa77 bin folder 2015-01-19 11:29:43 +01:00
dda7884ace pagination with composer and move FlattrItem 2015-01-19 11:29:25 +01:00
10939766de replace session class 2015-01-18 22:25:29 +01:00
a20f96b76d replace flash messages library 2015-01-18 22:11:41 +01:00
adf17b677e remove 3rd libraries 2015-01-18 20:07:46 +01:00
894cd087f4 remove autoload section in composer.json 2015-01-16 20:56:46 +01:00
44f1fef018 packagist 2015-01-16 20:45:23 +01:00
170a1407fe Merge pull request #690 from doc75/log_auth_error
Add message in web server log in case of authentication failure
2015-01-16 20:06:57 +01:00
b68f0a81e5 Merge pull request #1003 from vpmalley/dev
[RSS] introducing query param 'limit' for max items in RSS feed
2015-01-16 20:04:56 +01:00
7fe8a9adc4 [RSS] introducing query param 'limit' to restrict the number of items to display in RSS feeds. 2015-01-16 11:42:39 -05:00
af5c371e95 Merge pull request #999 from moparisthebest/additions_dev
Miscellaneous additions
2015-01-13 22:45:33 +01:00
13c7f9a462 Add ability to mark all articles from a tag as read 2015-01-12 19:52:41 -05:00
512e5e5bd1 Add ability to delete all articles matching a search 2015-01-12 19:52:41 -05:00
7f782e4496 Add ability to tag an article on creation 2015-01-12 19:52:41 -05:00
c86b40f014 add message in web server log in case of authentication failure to enable the usage of fail2ban on failed login attempts 2015-01-05 10:21:04 +01:00
8ae45e7fe2 fixes #963 and use our own readability.php file for mobiClass 2015-01-03 13:03:26 +01:00
166ff0a093 updated french mo file (see #986) 2015-01-03 11:40:19 +01:00
82978fbd57 Merge branch 'master' into dev
To get the errors
2015-01-03 11:38:32 +01:00
1186b3b67a Merge pull request #986 from goofy-bz/patch-2
Update fr_FR.utf8.po
2015-01-02 21:23:42 +01:00
30b948e68b Update fr_FR.utf8.po
formulation (trivial)
2015-01-02 21:13:54 +01:00
1aa1461a2e Merge pull request #974 from jbfavre/fix_ftrss_call_can_break_import
Make call to FTRSS silent to avoid warnings which can break import
2014-12-26 10:31:15 +01:00
92ae99bd29 Merge branch 'dev' of https://github.com/wallabag/wallabag into dev 2014-12-26 10:27:30 +01:00
d4d33a4130 deleted (again) courgette 2014-12-26 10:25:49 +01:00
7a21c308be Merge pull request #975 from wallabag/fixflattrcalls
don't call flattr if flattr is disabled
2014-12-23 15:34:05 +01:00
37cad52229 don't call flattr if flattr is disabled 2014-12-22 16:26:23 +01:00
81315897f0 Make call to FTRSS silent to avoid warnings which can break import 2014-12-21 22:41:04 +01:00
9254b6cf46 Merge pull request #971 from wallabag/fix-jquery-installation
Fix jquery installation
2014-12-19 21:06:06 +01:00
0e65fa85d3 remove idea files 2014-12-18 10:37:17 +01:00
4eb71ab555 change jquery path into installation script 2014-12-18 10:36:47 +01:00
e9a64ef8a9 Merge pull request #923 from wallabag/add-html-doc
add HTML documentation
2014-12-17 22:59:28 +01:00
a50d7f0f20 link to doc inside wallabag:about 2014-12-17 22:55:33 +01:00
2903ffc54f Merge branch 'add-html-doc' of https://github.com/wallabag/wallabag into documentation-integration 2014-12-17 22:44:36 +01:00
5ea5310ab4 enable showing or not for epub/mobi/pdf export buttons 2014-12-14 15:17:39 +01:00
1256e4c645 Merge branch 'tcitworld-ebook' into dev 2014-12-14 00:16:39 +01:00
dc69d3e8d8 merge epub with all the dev evolutions 2014-12-14 00:16:22 +01:00
9c55ed0923 diaspora on all themes 2014-12-07 22:24:25 +01:00
7c2c49d9b1 added diaspora sharing 2014-12-06 18:42:29 +01:00
41bd2be68a Merge pull request #958 from etiess/patch-2
Update wallabag_compatibility_test.php
2014-11-26 14:08:51 +01:00
66d7a4dcd8 Update wallabag_compatibility_test.php
Explain how to install Tidy
2014-11-26 14:07:27 +01:00
b9c026ce32 Merge branch 'remove-courgette' into dev
Conflicts:
	themes/courgette/_view.twig
2014-11-24 22:56:10 +01:00
c4457fba85 upgrade documentation 2014-11-24 13:46:39 +01:00
d4b42995f7 add link to documentation into installation 2014-11-24 13:46:11 +01:00
485d57972e Merge pull request #939 from jsit/globaljs
_global-izing some more js & css
2014-11-24 13:23:53 +01:00
85c5a1ff8d failover if theme folder doesn't exist 2014-11-24 13:11:57 +01:00
7b8bb75228 Merge pull request #942 from wallabag/carrot
implementing carrot into wallabag
2014-11-21 22:15:17 +01:00
fe16457efc Merge pull request #945 from jsit/carrot
Fixing icon text on unread page
2014-11-21 22:10:02 +01:00
46533cac7d Fixing icon text on unread page 2014-11-21 16:07:15 -05:00
747a15841d Merge pull request #944 from jsit/carrot
Globalizing and creating two variants of Carrot.org icon
2014-11-21 21:47:37 +01:00
fc01f94387 Globalizing and creating two variants of Carrot.org icon; tidying up some CSS 2014-11-21 15:30:59 -05:00
e9d4d17693 fix merge confict 2014-11-19 16:54:28 +01:00
25f9c66834 Merge pull request #943 from wallabag/fixFlattrs
fix Flattrs
2014-11-19 16:40:36 +01:00
d25a3f13c2 default deactivated 2014-11-19 16:40:02 +01:00
b13376e918 fix Flattrs 2014-11-19 16:35:44 +01:00
c8b4ef7fed implementing carrot into wallabag 2014-11-19 16:27:56 +01:00
b0f9f5ac21 Merge pull request #938 from jsit/firefoxiconfix
Fix for favicons in Firefox
2014-11-18 22:36:53 +01:00
6062f74c6b Updating Baggy theme's head.twig to locate _global js/css 2014-11-18 10:07:32 -05:00
eb365a01fb _global-izing some more js & css 2014-11-18 10:01:37 -05:00
eb0c88a9d4 Fix for favicons in Firefox (FF only uses the last declared favicon, not the most appropriate: https://bugzilla.mozilla.org/show_bug.cgi?id=751712) 2014-11-18 09:28:39 -05:00
db3bffa284 Merge pull request #937 from jsit/favicons
Moving favicons to new _global theme dir and adjusting <link> tags
2014-11-17 23:15:47 +01:00
ca6c0de380 Adjusting Template class so that _global is ignored as a theme 2014-11-17 17:11:33 -05:00
d91ff81ca6 Modifying Courgette theme to comply with new app icon image location 2014-11-17 16:59:53 -05:00
9d2140c9a1 Fixing earlier commit wherein I lowercased some JS calls 2014-11-17 16:54:15 -05:00
7a0f454d39 Removing app icons from previous locations 2014-11-17 16:51:38 -05:00
d5b717dc77 Moving app icon images to /themes/_global/img/appicon/, updating Baggy and Default themes to point there 2014-11-17 16:49:34 -05:00
7cb517ce54 Adding/fixing favicon <link>s in Baggy theme header 2014-11-17 14:28:07 -05:00
a0c57b35a3 add HTML documentation 2014-11-04 08:33:05 +01:00
9f86454b48 deleting send to kindle function 2014-09-28 17:20:35 +02:00
b852df020c add extension for pdf file 2014-09-28 12:18:47 +02:00
fa926fb47c offering download for pdf file and comment in code 2014-09-27 19:59:43 +02:00
6fc2c29daa revert routing bad deleting 2014-09-27 19:47:50 +02:00
a1b31d93b6 get up to date 2014-09-27 19:42:37 +02:00
824f8c45ed changed mpdf with tcpdf 2014-09-27 19:34:17 +02:00
d4690a8fa1 removed unnecessary fonts 2014-08-21 18:54:25 +02:00
b83690ebd8 removing examples for mpdf 2014-08-04 21:34:44 +02:00
358c689cec little fix in locale files 2014-08-03 18:06:37 +02:00
ab86a5124a more translations 2014-07-26 13:04:12 +02:00
8492f37323 translation stuff (en & fr done) 2014-07-26 12:22:33 +02:00
f8c3798522 little better 2014-07-26 11:52:43 +02:00
d49446ff98 bug with extension in the filename 2014-07-25 01:38:28 +02:00
dc59f164a9 send2kindle 2014-07-25 01:33:31 +02:00
deab6280d3 mobi (not tested on actual device) and pdf working 2014-07-25 00:33:19 +02:00
d07abb5c42 updated mpdf to 5.7.2 2014-07-24 22:01:35 +02:00
fb9df0c269 use directly MOBIClass 2014-07-24 21:56:04 +02:00
c70bfefc68 add mobi and pdf to routing 2014-07-24 15:59:08 +02:00
15317991f3 from epub to all kind of ebooks 2014-07-24 15:53:23 +02:00
4188f38ad5 add pdf and mobi libraries 2014-07-24 15:49:36 +02:00
1961 changed files with 31554 additions and 107769 deletions

10
.editorconfig Normal file
View File

@ -0,0 +1,10 @@
; top-most EditorConfig file
root = true
; Unix-style newlines
[*]
end_of_line = LF
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true

47
.gitignore vendored
View File

@ -1,9 +1,38 @@
.DS_Store
assets/*
cache/*
vendor
composer.phar
db/poche.sqlite
inc/poche/config.inc.php
inc/3rdparty/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer/
.vagrant
# Cache and logs (Symfony2)
/app/cache/*
/app/logs/*
!app/cache/.gitkeep
!app/logs/.gitkeep
# Cache and logs (Symfony3)
/var/cache/*
/var/logs/*
!var/cache/.gitkeep
!var/logs/.gitkeep
# Parameters
/app/config/parameters.yml
/app/config/parameters.ini
# Managed by Composer
/app/bootstrap.php.cache
/var/bootstrap.php.cache
/bin/*
!bin/console
!bin/symfony_requirements
/vendor/
# Assets and user uploads
/web/bundles/
/web/uploads/
# Build
/app/build
/build
# Composer PHAR
/composer.phar
# Data for wallabag
data/assets/*
data/db/wallabag*.sqlite

27
.scrutinizer.yml Normal file
View File

@ -0,0 +1,27 @@
filter:
paths:
- src/*
excluded_paths:
- 'vendor/*'
- 'app/*'
- 'web/*'
- 'src/Wallabag/*Bundle/Tests/*'
- '*Test.php'
tools:
php_cs_fixer: true
php_analyzer: true
php_mess_detector: true
php_changetracking: true
php_code_sniffer: true
php_pdepend: true
sensiolabs_security_checker: true
#external_code_coverage:
# timeout: 3600
php_code_coverage: true
php_sim: false
php_cpd: false
checks:
php:
code_rating: true

45
.travis.yml Normal file
View File

@ -0,0 +1,45 @@
language: php
# faster builds on docker-container setup
sudo: false
# cache vendor dirs
cache:
directories:
- vendor
- $HOME/.composer/cache
php:
- 5.4
- 5.5
- 5.6
- hhvm
- nightly
matrix:
fast_finish: true
allow_failures:
- php: hhvm
- php: nightly
branches:
only:
- v2
install:
- composer self-update
# build coverage only on one build, to speed up results feedbacks
# before_script:
# - if [[ "$TRAVIS_PHP_VERSION" = "5.6" ]]; then PHPUNIT_FLAGS="--coverage-clover=coverage.clover"; else PHPUNIT_FLAGS=""; fi;
script:
- ant prepare
- bin/phpunit --exclude-group command-doctrine --debug $PHPUNIT_FLAGS
# after_script:
# - |
# if [ $TRAVIS_PHP_VERSION = '5.6' ]; then
# wget https://scrutinizer-ci.com/ocular.phar
# php ocular.phar code-coverage:upload --format=php-clover coverage.clover
# fi

View File

@ -6,8 +6,8 @@ Please [open a new issue](https://github.com/wallabag/wallabag/issues/new).
To fix the bug quickly, we need some infos:
* your wallabag version (on top of the ./index.php file, and also on config page)
* your webserver installation :
* type of hosting (shared or dedicaced)
* in case of a dedicaced server, the server and OS used
* type of hosting (shared or dedicated)
* in case of a dedicated server, the server and OS used
* the php version used, eventually `phpinfo()`
* which storage system you choose at install (SQLite, MySQL/MariaDB or PostgreSQL)
* any problem on the `wallabag_compatibility_test.php` page
@ -27,4 +27,4 @@ Note : If you have large portions of text, use [Github's Gist service](https://g
## You want to fix a bug or to add a feature
Please fork wallabag and work with **the dev branch** only. **Do not work on master branch**.
[Don't forget to read our guidelines](https://github.com/wallabag/wallabag/blob/dev/GUIDELINES.md).
[Don't forget to read our guidelines](https://github.com/wallabag/wallabag/blob/dev/GUIDELINES.md).

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2014 Nicolas Lœuillet
Copyright (c) 2013-2015 Nicolas Lœuillet
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.

View File

@ -1,17 +1,6 @@
wallabag is based on :
* PHP Readability https://bitbucket.org/fivefilters/php-readability
* Full Text RSS http://code.fivefilters.org/full-text-rss/src
* logo by Maylis Agniel https://github.com/wallabag/logo
* icons http://icomoon.io
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
* Twig http://twig.sensiolabs.org
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
* Pagination https://github.com/daveismyname/pagination
* PHPePub https://github.com/Grandt/PHPePub/
wallabag is mainly developed by [Nicolas Lœuillet](https://github.com/nicosomb) under the MIT License.
wallabag is mainly developed by Nicolas Lœuillet under the MIT License
Thank you so much to [@tcitworld](https://github.com/tcitworld) and [@j0k3r](https://github.com/j0k3r).
Thank you so much to @tcitworld and @mariroz.
Contributors : https://github.com/wallabag/wallabag/graphs/contributors
Thank you [to others contributors](https://github.com/wallabag/wallabag/graphs/contributors
).

29
Capfile Normal file
View File

@ -0,0 +1,29 @@
# Load DSL and set up stages
require 'capistrano/setup'
# Include default deployment tasks
require 'capistrano/deploy'
require 'capistrano/symfony'
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
# require 'capistrano/bundler'
# require 'capistrano/rails/assets'
# require 'capistrano/rails/migrations'
# require 'capistrano/passenger'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

5
Gemfile Normal file
View File

@ -0,0 +1,5 @@
source "https://rubygems.org"
gem 'capistrano', '~> 3.1'
gem 'capistrano-symfony', '~> 0.1', :github => 'capistrano/symfony'
gem 'capistrano-composer', '~> 0.0.3'

41
Gemfile.lock Normal file
View File

@ -0,0 +1,41 @@
GIT
remote: git://github.com/capistrano/symfony.git
revision: ca56a01b817097d2831400ef9b1867fc8e07dcf8
specs:
capistrano-symfony (0.4.0)
capistrano (~> 3.1)
capistrano-composer (~> 0.0.3)
capistrano-file-permissions (~> 0.1.0)
GEM
remote: https://rubygems.org/
specs:
capistrano (3.4.0)
i18n
rake (>= 10.0.0)
sshkit (~> 1.3)
capistrano-composer (0.0.6)
capistrano (>= 3.0.0.pre)
capistrano-file-permissions (0.1.1)
capistrano (~> 3.1)
colorize (0.7.7)
i18n (0.7.0)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.2)
rake (10.4.2)
sshkit (1.7.1)
colorize (>= 0.7.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
PLATFORMS
ruby
DEPENDENCIES
capistrano (~> 3.1)
capistrano-composer (~> 0.0.3)
capistrano-symfony (~> 0.1)!
BUNDLED WITH
1.10.6

View File

@ -1,9 +1,26 @@
# what is wallabag ?
wallabag is a self hostable application allowing you to not miss any content anymore. Click, save, read it when you can. It extracts content so that you can read it when you have time.
[![Build Status](https://travis-ci.org/wallabag/wallabag.svg?branch=v2)](https://travis-ci.org/wallabag/wallabag)
[![Code Coverage](https://scrutinizer-ci.com/g/wallabag/wallabag/badges/coverage.png?b=v2)](https://scrutinizer-ci.com/g/wallabag/wallabag/?branch=v2)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wallabag/wallabag/badges/quality-score.png?b=v2)](https://scrutinizer-ci.com/g/wallabag/wallabag/?branch=v2)
# What is wallabag ?
wallabag is a self hostable application allowing you to not miss any content anymore.
Click, save, read it when you can. It extracts content so that you can read it when you have time.
More informations on our website: [wallabag.org](http://wallabag.org)
# Want to test the v2 ?
Keep in mind it's an **instable** branch, everything can be broken :)
```
git clone https://github.com/wallabag/wallabag.git -b v2
cd wallabag
composer install
php app/console wallabag:install
php app/console server:run
```
## License
Copyright © 2013-2014 Nicolas Lœuillet <nicolas@loeuillet.org>
Copyright © 2013-2015 Nicolas Lœuillet <nicolas@loeuillet.org>
This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the COPYING file for more details.

0
TRANSLATION.md Executable file → Normal file
View File

7
app/.htaccess Normal file
View File

@ -0,0 +1,7 @@
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>

9
app/AppCache.php Normal file
View File

@ -0,0 +1,9 @@
<?php
require_once __DIR__.'/AppKernel.php';
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
class AppCache extends HttpCache
{
}

46
app/AppKernel.php Normal file
View File

@ -0,0 +1,46 @@
<?php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\RestBundle\FOSRestBundle(),
new FOS\UserBundle\FOSUserBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
new Nelmio\CorsBundle\NelmioCorsBundle(),
new Liip\ThemeBundle\LiipThemeBundle(),
new Wallabag\CoreBundle\WallabagCoreBundle(),
new Wallabag\ApiBundle\WallabagApiBundle(),
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
new Lexik\Bundle\FormFilterBundle\LexikFormFilterBundle(),
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
$bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
}
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
}

0
assets/.gitignore → app/Resources/views/.gitkeep Executable file → Normal file
View File

758
app/SymfonyRequirements.php Normal file
View File

@ -0,0 +1,758 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* Users of PHP 5.2 should be able to run the requirements checks.
* This is why the file and all classes must be compatible with PHP 5.2+
* (e.g. not using namespaces and closures).
*
* ************** CAUTION **************
*
* DO NOT EDIT THIS FILE as it will be overridden by Composer as part of
* the installation/update process. The original file resides in the
* SensioDistributionBundle.
*
* ************** CAUTION **************
*/
/**
* Represents a single PHP requirement, e.g. an installed extension.
* It can be a mandatory requirement or an optional recommendation.
* There is a special subclass, named PhpIniRequirement, to check a php.ini configuration.
*
* @author Tobias Schultze <http://tobion.de>
*/
class Requirement
{
private $fulfilled;
private $testMessage;
private $helpText;
private $helpHtml;
private $optional;
/**
* Constructor that initializes the requirement.
*
* @param bool $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
{
$this->fulfilled = (bool) $fulfilled;
$this->testMessage = (string) $testMessage;
$this->helpHtml = (string) $helpHtml;
$this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
$this->optional = (bool) $optional;
}
/**
* Returns whether the requirement is fulfilled.
*
* @return bool true if fulfilled, otherwise false
*/
public function isFulfilled()
{
return $this->fulfilled;
}
/**
* Returns the message for testing the requirement.
*
* @return string The test message
*/
public function getTestMessage()
{
return $this->testMessage;
}
/**
* Returns the help text for resolving the problem.
*
* @return string The help text
*/
public function getHelpText()
{
return $this->helpText;
}
/**
* Returns the help text formatted in HTML.
*
* @return string The HTML help
*/
public function getHelpHtml()
{
return $this->helpHtml;
}
/**
* Returns whether this is only an optional recommendation and not a mandatory requirement.
*
* @return bool true if optional, false if mandatory
*/
public function isOptional()
{
return $this->optional;
}
}
/**
* Represents a PHP requirement in form of a php.ini configuration.
*
* @author Tobias Schultze <http://tobion.de>
*/
class PhpIniRequirement extends Requirement
{
/**
* Constructor that initializes the requirement.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
{
$cfgValue = ini_get($cfgName);
if (is_callable($evaluation)) {
if (null === $testMessage || null === $helpHtml) {
throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.');
}
$fulfilled = call_user_func($evaluation, $cfgValue);
} else {
if (null === $testMessage) {
$testMessage = sprintf('%s %s be %s in php.ini',
$cfgName,
$optional ? 'should' : 'must',
$evaluation ? 'enabled' : 'disabled'
);
}
if (null === $helpHtml) {
$helpHtml = sprintf('Set <strong>%s</strong> to <strong>%s</strong> in php.ini<a href="#phpini">*</a>.',
$cfgName,
$evaluation ? 'on' : 'off'
);
}
$fulfilled = $evaluation == $cfgValue;
}
parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional);
}
}
/**
* A RequirementCollection represents a set of Requirement instances.
*
* @author Tobias Schultze <http://tobion.de>
*/
class RequirementCollection implements IteratorAggregate
{
private $requirements = array();
/**
* Gets the current RequirementCollection as an Iterator.
*
* @return Traversable A Traversable interface
*/
public function getIterator()
{
return new ArrayIterator($this->requirements);
}
/**
* Adds a Requirement.
*
* @param Requirement $requirement A Requirement instance
*/
public function add(Requirement $requirement)
{
$this->requirements[] = $requirement;
}
/**
* Adds a mandatory requirement.
*
* @param bool $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null)
{
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false));
}
/**
* Adds an optional recommendation.
*
* @param bool $fulfilled Whether the recommendation is fulfilled
* @param string $testMessage The message for testing the recommendation
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null)
{
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true));
}
/**
* Adds a mandatory requirement in form of a php.ini configuration.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false));
}
/**
* Adds an optional recommendation in form of a php.ini configuration.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true));
}
/**
* Adds a requirement collection to the current set of requirements.
*
* @param RequirementCollection $collection A RequirementCollection instance
*/
public function addCollection(RequirementCollection $collection)
{
$this->requirements = array_merge($this->requirements, $collection->all());
}
/**
* Returns both requirements and recommendations.
*
* @return array Array of Requirement instances
*/
public function all()
{
return $this->requirements;
}
/**
* Returns all mandatory requirements.
*
* @return array Array of Requirement instances
*/
public function getRequirements()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns the mandatory requirements that were not met.
*
* @return array Array of Requirement instances
*/
public function getFailedRequirements()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && !$req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns all optional recommendations.
*
* @return array Array of Requirement instances
*/
public function getRecommendations()
{
$array = array();
foreach ($this->requirements as $req) {
if ($req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns the recommendations that were not met.
*
* @return array Array of Requirement instances
*/
public function getFailedRecommendations()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && $req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns whether a php.ini configuration is not correct.
*
* @return bool php.ini configuration problem?
*/
public function hasPhpIniConfigIssue()
{
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) {
return true;
}
}
return false;
}
/**
* Returns the PHP configuration file (php.ini) path.
*
* @return string|false php.ini file path
*/
public function getPhpIniConfigPath()
{
return get_cfg_var('cfg_file_path');
}
}
/**
* This class specifies all requirements and optional recommendations that
* are necessary to run the Symfony Standard Edition.
*
* @author Tobias Schultze <http://tobion.de>
* @author Fabien Potencier <fabien@symfony.com>
*/
class SymfonyRequirements extends RequirementCollection
{
const REQUIRED_PHP_VERSION = '5.3.3';
/**
* Constructor that initializes the requirements.
*/
public function __construct()
{
/* mandatory requirements follow */
$installedPhpVersion = phpversion();
$this->addRequirement(
version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='),
sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion),
sprintf('You are running PHP version "<strong>%s</strong>", but Symfony needs at least PHP "<strong>%s</strong>" to run.
Before using Symfony, upgrade your PHP installation, preferably to the latest version.',
$installedPhpVersion, self::REQUIRED_PHP_VERSION),
sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion)
);
$this->addRequirement(
version_compare($installedPhpVersion, '5.3.16', '!='),
'PHP version must not be 5.3.16 as Symfony won\'t work properly with it',
'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)'
);
$this->addRequirement(
is_dir(__DIR__.'/../vendor/composer'),
'Vendor libraries must be installed',
'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. '.
'Then run "<strong>php composer.phar install</strong>" to install them.'
);
$cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache';
$this->addRequirement(
is_writable($cacheDir),
'app/cache/ or var/cache/ directory must be writable',
'Change the permissions of either "<strong>app/cache/</strong>" or "<strong>var/cache/</strong>" directory so that the web server can write into it.'
);
$logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs';
$this->addRequirement(
is_writable($logsDir),
'app/logs/ or var/logs/ directory must be writable',
'Change the permissions of either "<strong>app/logs/</strong>" or "<strong>var/logs/</strong>" directory so that the web server can write into it.'
);
$this->addPhpIniRequirement(
'date.timezone', true, false,
'date.timezone setting must be set',
'Set the "<strong>date.timezone</strong>" setting in php.ini<a href="#phpini">*</a> (like Europe/Paris).'
);
if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
$timezones = array();
foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
foreach ($abbreviations as $abbreviation) {
$timezones[$abbreviation['timezone_id']] = true;
}
}
$this->addRequirement(
isset($timezones[@date_default_timezone_get()]),
sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
);
}
$this->addRequirement(
function_exists('json_encode'),
'json_encode() must be available',
'Install and enable the <strong>JSON</strong> extension.'
);
$this->addRequirement(
function_exists('session_start'),
'session_start() must be available',
'Install and enable the <strong>session</strong> extension.'
);
$this->addRequirement(
function_exists('ctype_alpha'),
'ctype_alpha() must be available',
'Install and enable the <strong>ctype</strong> extension.'
);
$this->addRequirement(
function_exists('token_get_all'),
'token_get_all() must be available',
'Install and enable the <strong>Tokenizer</strong> extension.'
);
$this->addRequirement(
function_exists('simplexml_import_dom'),
'simplexml_import_dom() must be available',
'Install and enable the <strong>SimpleXML</strong> extension.'
);
if (function_exists('apc_store') && ini_get('apc.enabled')) {
if (version_compare($installedPhpVersion, '5.4.0', '>=')) {
$this->addRequirement(
version_compare(phpversion('apc'), '3.1.13', '>='),
'APC version must be at least 3.1.13 when using PHP 5.4',
'Upgrade your <strong>APC</strong> extension (3.1.13+).'
);
} else {
$this->addRequirement(
version_compare(phpversion('apc'), '3.0.17', '>='),
'APC version must be at least 3.0.17',
'Upgrade your <strong>APC</strong> extension (3.0.17+).'
);
}
}
$this->addPhpIniRequirement('detect_unicode', false);
if (extension_loaded('suhosin')) {
$this->addPhpIniRequirement(
'suhosin.executor.include.whitelist',
create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
false,
'suhosin.executor.include.whitelist must be configured correctly in php.ini',
'Add "<strong>phar</strong>" to <strong>suhosin.executor.include.whitelist</strong> in php.ini<a href="#phpini">*</a>.'
);
}
if (extension_loaded('xdebug')) {
$this->addPhpIniRequirement(
'xdebug.show_exception_trace', false, true
);
$this->addPhpIniRequirement(
'xdebug.scream', false, true
);
$this->addPhpIniRecommendation(
'xdebug.max_nesting_level',
create_function('$cfgValue', 'return $cfgValue > 100;'),
true,
'xdebug.max_nesting_level should be above 100 in php.ini',
'Set "<strong>xdebug.max_nesting_level</strong>" to e.g. "<strong>250</strong>" in php.ini<a href="#phpini">*</a> to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
);
}
$pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null;
$this->addRequirement(
null !== $pcreVersion,
'PCRE extension must be available',
'Install the <strong>PCRE</strong> extension (version 8.0+).'
);
if (extension_loaded('mbstring')) {
$this->addPhpIniRequirement(
'mbstring.func_overload',
create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
true,
'string functions should not be overloaded',
'Set "<strong>mbstring.func_overload</strong>" to <strong>0</strong> in php.ini<a href="#phpini">*</a> to disable function overloading by the mbstring extension.'
);
}
/* optional recommendations follow */
if (file_exists(__DIR__.'/../vendor/composer')) {
require_once __DIR__.'/../vendor/autoload.php';
try {
$r = new \ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle');
$contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php');
} catch (\ReflectionException $e) {
$contents = '';
}
$this->addRecommendation(
file_get_contents(__FILE__) === $contents,
'Requirements file should be up-to-date',
'Your requirements file is outdated. Run composer install and re-check your configuration.'
);
}
$this->addRecommendation(
version_compare($installedPhpVersion, '5.3.4', '>='),
'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions',
'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.3.8', '>='),
'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
'Install PHP 5.3.8 or newer if your project uses annotations.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.4.0', '!='),
'You should not use PHP 5.4.0 due to the PHP bug #61453',
'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.4.11', '>='),
'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)',
'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.'
);
$this->addRecommendation(
(version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<'))
||
version_compare($installedPhpVersion, '5.4.8', '>='),
'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909',
'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.'
);
if (null !== $pcreVersion) {
$this->addRecommendation(
$pcreVersion >= 8.0,
sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion),
'<strong>PCRE 8.0+</strong> is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.'
);
}
$this->addRecommendation(
class_exists('DomDocument'),
'PHP-DOM and PHP-XML modules should be installed',
'Install and enable the <strong>PHP-DOM</strong> and the <strong>PHP-XML</strong> modules.'
);
$this->addRecommendation(
function_exists('mb_strlen'),
'mb_strlen() should be available',
'Install and enable the <strong>mbstring</strong> extension.'
);
$this->addRecommendation(
function_exists('iconv'),
'iconv() should be available',
'Install and enable the <strong>iconv</strong> extension.'
);
$this->addRecommendation(
function_exists('utf8_decode'),
'utf8_decode() should be available',
'Install and enable the <strong>XML</strong> extension.'
);
$this->addRecommendation(
function_exists('filter_var'),
'filter_var() should be available',
'Install and enable the <strong>filter</strong> extension.'
);
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->addRecommendation(
function_exists('posix_isatty'),
'posix_isatty() should be available',
'Install and enable the <strong>php_posix</strong> extension (used to colorize the CLI output).'
);
}
$this->addRecommendation(
extension_loaded('intl'),
'intl extension should be available',
'Install and enable the <strong>intl</strong> extension (used for validators).'
);
if (extension_loaded('intl')) {
// in some WAMP server installations, new Collator() returns null
$this->addRecommendation(
null !== new Collator('fr_FR'),
'intl extension should be correctly configured',
'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.'
);
// check for compatible ICU versions (only done when you have the intl extension)
if (defined('INTL_ICU_VERSION')) {
$version = INTL_ICU_VERSION;
} else {
$reflector = new ReflectionExtension('intl');
ob_start();
$reflector->info();
$output = strip_tags(ob_get_clean());
preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches);
$version = $matches[1];
}
$this->addRecommendation(
version_compare($version, '4.0', '>='),
'intl ICU version should be at least 4+',
'Upgrade your <strong>intl</strong> extension with a newer ICU version (4+).'
);
$this->addPhpIniRecommendation(
'intl.error_level',
create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
true,
'intl.error_level should be 0 in php.ini',
'Set "<strong>intl.error_level</strong>" to "<strong>0</strong>" in php.ini<a href="#phpini">*</a> to inhibit the messages when an error occurs in ICU functions.'
);
}
$accelerator =
(extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'))
||
(extension_loaded('apc') && ini_get('apc.enabled'))
||
(extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable'))
||
(extension_loaded('Zend OPcache') && ini_get('opcache.enable'))
||
(extension_loaded('xcache') && ini_get('xcache.cacher'))
||
(extension_loaded('wincache') && ini_get('wincache.ocenabled'))
;
$this->addRecommendation(
$accelerator,
'a PHP accelerator should be installed',
'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
);
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$this->addRecommendation(
$this->getRealpathCacheSize() > 1000,
'realpath_cache_size should be above 1024 in php.ini',
'Set "<strong>realpath_cache_size</strong>" to e.g. "<strong>1024</strong>" in php.ini<a href="#phpini">*</a> to improve performance on windows.'
);
}
$this->addPhpIniRecommendation('short_open_tag', false);
$this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
$this->addPhpIniRecommendation('register_globals', false, true);
$this->addPhpIniRecommendation('session.auto_start', false);
$this->addRecommendation(
class_exists('PDO'),
'PDO should be installed',
'Install <strong>PDO</strong> (mandatory for Doctrine).'
);
if (class_exists('PDO')) {
$drivers = PDO::getAvailableDrivers();
$this->addRecommendation(
count($drivers) > 0,
sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
'Install <strong>PDO drivers</strong> (mandatory for Doctrine).'
);
}
}
/**
* Loads realpath_cache_size from php.ini and converts it to int.
*
* (e.g. 16k is converted to 16384 int)
*
* @return int
*/
protected function getRealpathCacheSize()
{
$size = ini_get('realpath_cache_size');
$size = trim($size);
$unit = strtolower(substr($size, -1, 1));
switch ($unit) {
case 'g':
return $size * 1024 * 1024 * 1024;
case 'm':
return $size * 1024 * 1024;
case 'k':
return $size * 1024;
default:
return (int) $size;
}
}
}

13
app/autoload.php Normal file
View File

@ -0,0 +1,13 @@
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
/**
* @var ClassLoader $loader
*/
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;

142
app/check.php Normal file
View File

@ -0,0 +1,142 @@
<?php
require_once dirname(__FILE__).'/SymfonyRequirements.php';
$lineSize = 70;
$symfonyRequirements = new SymfonyRequirements();
$iniPath = $symfonyRequirements->getPhpIniConfigPath();
echo_title('Symfony2 Requirements Checker');
echo '> PHP is using the following php.ini file:'.PHP_EOL;
if ($iniPath) {
echo_style('green', ' '.$iniPath);
} else {
echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!');
}
echo PHP_EOL.PHP_EOL;
echo '> Checking Symfony requirements:'.PHP_EOL.' ';
$messages = array();
foreach ($symfonyRequirements->getRequirements() as $req) {
/** @var $req Requirement */
if ($helpText = get_error_message($req, $lineSize)) {
echo_style('red', 'E');
$messages['error'][] = $helpText;
} else {
echo_style('green', '.');
}
}
$checkPassed = empty($messages['error']);
foreach ($symfonyRequirements->getRecommendations() as $req) {
if ($helpText = get_error_message($req, $lineSize)) {
echo_style('yellow', 'W');
$messages['warning'][] = $helpText;
} else {
echo_style('green', '.');
}
}
if ($checkPassed) {
echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects');
} else {
echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects');
echo_title('Fix the following mandatory requirements', 'red');
foreach ($messages['error'] as $helpText) {
echo ' * '.$helpText.PHP_EOL;
}
}
if (!empty($messages['warning'])) {
echo_title('Optional recommendations to improve your setup', 'yellow');
foreach ($messages['warning'] as $helpText) {
echo ' * '.$helpText.PHP_EOL;
}
}
echo PHP_EOL;
echo_style('title', 'Note');
echo ' The command console could use a different php.ini file'.PHP_EOL;
echo_style('title', '~~~~');
echo ' than the one used with your web server. To be on the'.PHP_EOL;
echo ' safe side, please check the requirements from your web'.PHP_EOL;
echo ' server using the ';
echo_style('yellow', 'web/config.php');
echo ' script.'.PHP_EOL;
echo PHP_EOL;
exit($checkPassed ? 0 : 1);
function get_error_message(Requirement $requirement, $lineSize)
{
if ($requirement->isFulfilled()) {
return;
}
$errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL;
$errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL;
return $errorMessage;
}
function echo_title($title, $style = null)
{
$style = $style ?: 'title';
echo PHP_EOL;
echo_style($style, $title.PHP_EOL);
echo_style($style, str_repeat('~', strlen($title)).PHP_EOL);
echo PHP_EOL;
}
function echo_style($style, $message)
{
// ANSI color codes
$styles = array(
'reset' => "\033[0m",
'red' => "\033[31m",
'green' => "\033[32m",
'yellow' => "\033[33m",
'error' => "\033[37;41m",
'success' => "\033[37;42m",
'title' => "\033[34m",
);
$supports = has_color_support();
echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : '');
}
function echo_block($style, $title, $message)
{
$message = ' '.trim($message).' ';
$width = strlen($message);
echo PHP_EOL.PHP_EOL;
echo_style($style, str_repeat(' ', $width).PHP_EOL);
echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL);
echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL);
echo_style($style, str_repeat(' ', $width).PHP_EOL);
}
function has_color_support()
{
static $support;
if (null === $support) {
if (DIRECTORY_SEPARATOR == '\\') {
$support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
} else {
$support = function_exists('posix_isatty') && @posix_isatty(STDOUT);
}
}
return $support;
}

159
app/config/config.yml Normal file
View File

@ -0,0 +1,159 @@
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
framework:
#esi: ~
translator: { fallback: "%locale%" }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
share_twitter: %share_twitter%
share_mail: %share_mail%
share_shaarli: %share_shaarli%
shaarli_url: %shaarli_url%
share_diaspora: %share_diaspora%
diaspora_url: %diaspora_url%
flattr: %flattr%
flattrable: 1
flattred: 2
carrot: %carrot%
show_printlink: %show_printlink%
export_epub: %export_epub%
export_mobi: %export_mobi%
export_pdf: %export_pdf%
version: %app.version%
warning_message: %warning_message%
paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb"
flattr_url: "https://flattr.com/thing/1265480"
form:
resources:
- LexikFormFilterBundle:Form:form_div_layout.html.twig
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
bundles: [ ]
#java: /usr/bin/java
filters:
cssrewrite: ~
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
naming_strategy: wallabag_core.doctrine.prefixed_naming_strategy
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener: true
view:
view_response_listener: 'force'
formats:
xml: true
json : true
templating_formats:
html: true
force_redirects:
html: true
failed_validation: HTTP_BAD_REQUEST
default_engine: twig
routing_loader:
default_format: json
nelmio_api_doc: ~
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: []
allow_headers: []
allow_methods: []
expose_headers: []
max_age: 0
hosts: []
#origin_regex: false
paths:
'^/api/':
allow_origin: ['*']
allow_headers: ['X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
max_age: 3600
'^/':
#origin_regex: true
allow_origin: ['^http://localhost:[0-9]+']
allow_headers: ['X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
max_age: 3600
hosts: ['^api\.']
liip_theme:
load_controllers: false
themes:
- baggy
- material
autodetect_theme: wallabag_core.helper.detect_active_theme
path_patterns:
# app_resource:
# - %%app_path%%/views/themes/%%current_theme%%/%%template%%
# - %%app_path%%/views/%%template%%
bundle_resource:
- %%bundle_path%%/Resources/views/themes/%%current_theme%%/%%template%%
# bundle_resource_dir:
# - %%dir%%/views/themes/%%current_theme%%/%%bundle_name%%/%%template%%
# - %%dir%%/views/%%bundle_name%%/%%override_path%%
fos_user:
db_driver: orm
firewall_name: main
user_class: Wallabag\CoreBundle\Entity\User

54
app/config/config_dev.yml Normal file
View File

@ -0,0 +1,54 @@
imports:
- { resource: config.yml }
framework:
router:
resource: "%kernel.root_dir%/config/routing_dev.yml"
strict_requirements: true
profiler: { only_exceptions: false }
web_profiler:
toolbar: true
intercept_redirects: false
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
bubble: false
verbosity_levels:
VERBOSITY_VERBOSE: INFO
VERBOSITY_VERY_VERBOSE: DEBUG
channels: ["!doctrine"]
console_very_verbose:
type: console
bubble: false
verbosity_levels:
VERBOSITY_VERBOSE: NOTICE
VERBOSITY_VERY_VERBOSE: NOTICE
VERBOSITY_DEBUG: DEBUG
channels: ["doctrine"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
assetic:
use_controller: true
swiftmailer:
# see http://mailcatcher.me/
transport: smtp
host: 'localhost'
port: 1025
username: null
password: null

View File

@ -0,0 +1,30 @@
imports:
- { resource: config.yml }
#framework:
# validation:
# cache: apc
#doctrine:
# orm:
# metadata_cache_driver: apc
# result_cache_driver: apc
# query_cache_driver: apc
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
wsse:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.wsse.log
level: error
channels: [wsse]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console

View File

@ -0,0 +1,31 @@
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
# to be able to read emails sent
spool:
type: file
doctrine:
dbal:
driver: pdo_sqlite
path: %kernel.root_dir%/../data/db/wallabag_test.sqlite
host: localhost
orm:
metadata_cache_driver:
type: service
id: filesystem_cache
query_cache_driver:
type: service
id: filesystem_cache

View File

@ -0,0 +1,50 @@
# This file is a "template" of what your parameters.yml file should look like
parameters:
database_driver: pdo_sqlite
database_host: 127.0.0.1
database_port: ~
database_name: symfony
database_user: root
database_password: ~
database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite"
database_table_prefix: wallabag_
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: ~
mailer_password: ~
locale: en
# A secret key that's used to generate certain security-related tokens
secret: ThisTokenIsNotSoSecretChangeIt
# wallabag misc
app.version: 2.0.0-alpha
# message to display at the bottom of the page
warning_message: >
You're trying wallabag v2, which is in alpha version. If you find a bug, please have a look to <a href="https://github.com/wallabag/wallabag/issues">our issues list</a> and <a href="https://github.com/wallabag/wallabag/issues/new">open a new if necessary</a>
download_pictures: false # if true, pictures will be stored into data/assets for each article
# Entry view
share_twitter: true
share_mail: true
share_shaarli: true
shaarli_url: http://myshaarli.com
share_diaspora: true
diaspora_url: http://diasporapod.com
flattr: true
carrot: true
show_printlink: true
export_epub: true
export_mobi: true
export_pdf: true
# default user config
items_on_page: 12
theme: material
language: en_US
from_email: no-reply@wallabag.org
rss_limit: 50

32
app/config/routing.yml Normal file
View File

@ -0,0 +1,32 @@
wallabag_api:
resource: "@WallabagApiBundle/Resources/config/routing.yml"
prefix: /
app:
resource: @WallabagCoreBundle/Controller/
type: annotation
doc-api:
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
prefix: /api/doc
login:
pattern: /login
defaults: { _controller: WallabagCoreBundle:Security:login }
login_check:
pattern: /login_check
logout:
path: /logout
rest :
type : rest
resource : "routing_rest.yml"
prefix : /api
homepage:
pattern: "/{page}"
defaults: { _controller: WallabagCoreBundle:Entry:showUnread, page : 1 }
requirements:
page: \d+

View File

@ -0,0 +1,18 @@
_wdt:
resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
prefix: /_wdt
_profiler:
resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
prefix: /_profiler
_configurator:
resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml"
prefix: /_configurator
_errors:
resource: "@TwigBundle/Resources/config/routing/errors.xml"
prefix: /_error
_main:
resource: routing.yml

View File

@ -0,0 +1,3 @@
Rest_Wallabag:
type : rest
resource: "@WallabagApiBundle/Resources/config/routing_rest.yml"

53
app/config/security.yml Normal file
View File

@ -0,0 +1,53 @@
security:
encoders:
Wallabag\CoreBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
providers:
administrators:
entity: { class: WallabagCoreBundle:User, property: username }
fos_userbundle:
id: fos_user.user_provider.username
# the main part of the security, where you can set up firewalls
# for specific sections of your app
firewalls:
wsse_secured:
pattern: /api/.*
wsse: true
stateless: true
anonymous: true
login_firewall:
pattern: ^/login$
anonymous: ~
secured_area:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
anonymous: true
remember_me:
key: "%secret%"
lifetime: 31536000
path: /
domain: ~
logout:
path: /logout
target: /
access_control:
- { path: ^/api/salt, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }

19
app/config/services.yml Normal file
View File

@ -0,0 +1,19 @@
# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/book/service_container.html
parameters:
security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider
security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder
security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator
lexik_form_filter.get_filter.doctrine_orm.class: Wallabag\CoreBundle\Event\Subscriber\CustomDoctrineORMSubscriber
services:
# used for tests
filesystem_cache:
class: Doctrine\Common\Cache\FilesystemCache
arguments:
- %kernel.cache_dir%/doctrine/metadata
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags:
- { name: twig.extension }

27
app/console Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env php
<?php
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);
set_time_limit(0);
require_once __DIR__.'/bootstrap.php.cache';
require_once __DIR__.'/AppKernel.php';
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
if ($debug) {
Debug::enable();
}
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

1
bin/phpunit Symbolic link
View File

@ -0,0 +1 @@
../vendor/phpunit/phpunit/phpunit

50
build.xml Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="wallabag" default="build">
<target name="build" depends="prepare"/>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/app/cache"/>
</target>
<target name="prepare" depends="clean" description="Prepare for build">
<exec executable="composer">
<arg value="install"/>
<arg value="--no-interaction"/>
<arg value="--no-progress"/>
</exec>
<exec executable="php">
<arg value="${basedir}/app/console"/>
<arg value="doctrine:database:drop"/>
<arg value="--force"/>
<arg value="--env=test"/>
</exec>
<exec executable="php">
<arg value="${basedir}/app/console"/>
<arg value="doctrine:database:create"/>
<arg value="--env=test"/>
</exec>
<exec executable="php">
<arg value="${basedir}/app/console"/>
<arg value="doctrine:schema:create"/>
<arg value="--env=test"/>
</exec>
<exec executable="php">
<arg value="${basedir}/app/console"/>
<arg value="cache:clear"/>
<arg value="--env=test"/>
</exec>
<exec executable="php">
<arg value="${basedir}/app/console"/>
<arg value="doctrine:fixtures:load"/>
<arg value="--no-interaction"/>
<arg value="--env=test"/>
</exec>
</target>
<target name="phpunit" description="Run unit tests with PHPUnit + HTML Coverage">
<exec executable="phpunit" failonerror="true">
<arg value="--coverage-html"/>
<arg value="build/coverage"/>
</exec>
</target>
</project>

1
cache/.gitignore vendored
View File

@ -1 +0,0 @@
!.htaccess

2
cache/.htaccess vendored
View File

@ -1,2 +0,0 @@
Order deny,allow
Deny from all

View File

@ -1,14 +0,0 @@
<?php
// PHP 5.3 minimum
if (version_compare(PHP_VERSION, '5.3.3', '<')) {
die('This software require PHP 5.3.3 minimum');
}
// Short tags must be enabled for PHP < 5.4
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
if (! ini_get('short_open_tag')) {
die('This software require to have short tags enabled, check your php.ini => "short_open_tag = On"');
}
}

View File

@ -1,12 +0,0 @@
<?php
// Check if /cache is writeable
if (! is_writable('cache')) {
die('The directory "cache" must be writeable by your web server user');
}
// install folder still present, need to install wallabag
if (is_dir('install')) {
require('install/index.php');
exit;
}

View File

@ -1,7 +1,95 @@
{
"name": "wallabag/wallabag",
"type": "project",
"description": "open source self hostable read-it-later web application",
"keywords": ["read-it-later","read it later"],
"homepage": "https://github.com/wallabag/wallabag",
"license": "MIT",
"authors": [
{
"name": "Nicolas Lœuillet",
"email": "nicolas@loeuillet.org",
"homepage": "http://www.cdetc.fr",
"role": "Developer"
},
{
"name": "Thomas Citharel",
"homepage": "http://tcit.fr",
"role": "Developer"
},
{
"name": "Jérémy Benoist",
"homepage": "http://www.j0k3r.net",
"role": "Developer"
}
],
"support": {
"email": "hello@wallabag.org",
"issues": "https://github.com/wallabag/wallabag/issues"
},
"require": {
"twig/twig": "1.*",
"twig/extensions": "1.0.*",
"umpirsky/twig-gettext-extractor": "1.1.*"
}
}
"php": ">=5.3.3",
"symfony/symfony": "~2.7.0",
"doctrine/orm": "~2.3",
"doctrine/doctrine-bundle": "~1.2",
"twig/extensions": "~1.0",
"symfony/assetic-bundle": "~2.3",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~3.0.12",
"sensio/framework-extra-bundle": "~3.0",
"incenteev/composer-parameter-handler": "~2.0",
"nelmio/cors-bundle": "~1.4.0",
"friendsofsymfony/rest-bundle": "~1.4",
"jms/serializer-bundle": "~0.13",
"nelmio/api-doc-bundle": "~2.7",
"ezyang/htmlpurifier": "~4.6",
"mgargano/simplehtmldom": "~1.5",
"tecnick.com/tcpdf": "~6.2",
"simplepie/simplepie": "~1.3.1",
"willdurand/hateoas-bundle": "~0.5.0",
"htmlawed/htmlawed": "~1.1.19",
"liip/theme-bundle": "~1.1.3",
"pagerfanta/pagerfanta": "~1.0.3",
"lexik/form-filter-bundle": "~4.0",
"j0k3r/graby": "~1.0",
"friendsofsymfony/user-bundle": "dev-master"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "~2.2.0",
"sensio/generator-bundle": "~2.5",
"phpunit/phpunit": "~4.4"
},
"scripts": {
"post-install-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
],
"post-update-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
]
},
"extra": {
"symfony-app-dir": "app",
"symfony-web-dir": "web",
"symfony-assets-install": "relative",
"incenteev-parameters": {
"file": "app/config/parameters.yml"
}
},
"autoload": {
"psr-0": { "": "src/" }
},
"config": {
"bin-dir": "bin"
},
"minimum-stability": "dev",
"prefer-stable": true
}

4643
composer.lock generated

File diff suppressed because it is too large Load Diff

66
config/deploy.rb Normal file
View File

@ -0,0 +1,66 @@
# config valid only for current version of Capistrano
lock '3.4.0'
set :application, 'wallabag'
set :repo_url, 'git@github.com:wallabag/wallabag.git'
set :ssh_user, 'ssh_user'
server 'server_ip', user: fetch(:ssh_user), roles: %w{web app db}
set :scm, :git
set :format, :pretty
set :log_level, :info
# set :log_level, :debug
set :composer_install_flags, '--no-dev --prefer-dist --no-interaction --optimize-autoloader'
set :linked_files, %w{app/config/parameters.yml}
set :linked_dirs, %w{app/logs web/uploads}
set :keep_releases, 3
after 'deploy:finishing', 'deploy:cleanup'
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, '/var/www/my_app_name'
# Default value for :scm is :git
# set :scm, :git
# Default value for :format is :pretty
# set :format, :pretty
# Default value for :log_level is :debug
# set :log_level, :debug
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
# Default value for linked_dirs is []
# set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system')
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for keep_releases is 5
# set :keep_releases, 5
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end

View File

@ -0,0 +1,61 @@
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
# server 'db.example.com', user: 'deploy', roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server 'example.com',
# user: 'user_name',
# roles: %w{web app},
# ssh_options: {
# user: 'user_name', # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: 'please use keys'
# }

64
config/deploy/staging.rb Normal file
View File

@ -0,0 +1,64 @@
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
set :branch, 'v2'
set :deploy_to, '/var/www/'
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
# server 'db.example.com', user: 'deploy', roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server 'example.com',
# user: 'user_name',
# roles: %w{web app},
# ssh_options: {
# user: 'user_name', # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: 'please use keys'
# }

0
themes/courgette/css/knacss.css → data/assets/.gitignore vendored Executable file → Normal file
View File

0
data/db/.gitignore vendored Normal file
View File

View File

@ -1,2 +0,0 @@
Order deny,allow
Deny from all

View File

@ -1,57 +0,0 @@
<?php
/**
* wallabag, self hostable application allowing you to not miss any content anymore
*
* @category wallabag
* @author Nicolas Lœuillet <nicolas@loeuillet.org>
* @copyright 2013
* @license http://opensource.org/licenses/MIT see COPYING file
*/
class FlattrItem
{
public $status;
public $urlToFlattr;
public $flattrItemURL;
public $numFlattrs;
public function checkItem($urlToFlattr, $id)
{
$this->_cacheFlattrFile($urlToFlattr, $id);
$flattrResponse = file_get_contents(CACHE . "/flattr/".$id.".cache");
if($flattrResponse != FALSE) {
$result = json_decode($flattrResponse);
if (isset($result->message)) {
if ($result->message == "flattrable") {
$this->status = FLATTRABLE;
}
}
elseif (is_object($result) && $result->link) {
$this->status = FLATTRED;
$this->flattrItemURL = $result->link;
$this->numFlattrs = $result->flattrs;
}
else {
$this->status = NOT_FLATTRABLE;
}
}
else {
$this->status = "FLATTR_ERR_CONNECTION";
}
}
private function _cacheFlattrFile($urlToFlattr, $id)
{
if (!is_dir(CACHE . '/flattr')) {
mkdir(CACHE . '/flattr', 0777);
}
// if a cache flattr file for this url already exists and it's been less than one day than it have been updated, see in /cache
if ((!file_exists(CACHE . "/flattr/".$id.".cache")) || (time() - filemtime(CACHE . "/flattr/".$id.".cache") > 86400)) {
$askForFlattr = Tools::getFile(FLATTR_API . $urlToFlattr);
$flattrCacheFile = fopen(CACHE . "/flattr/".$id.".cache", 'w+');
fwrite($flattrCacheFile, $askForFlattr);
fclose($flattrCacheFile);
}
}
}

View File

@ -1,346 +0,0 @@
<?php
/**
* Session management class
*
* http://www.developpez.net/forums/d51943/php/langage/sessions/
* http://sebsauvage.net/wiki/doku.php?id=php:session
* http://sebsauvage.net/wiki/doku.php?id=php:shaarli
*
* Features:
* - Everything is stored on server-side (we do not trust client-side data,
* such as cookie expiration)
* - IP addresses are checked on each access to prevent session cookie hijacking
* (such as Firesheep)
* - Session expires on user inactivity (Session expiration date is
* automatically updated everytime the user accesses a page.)
* - A unique secret key is generated on server-side for this session
* (and never sent over the wire) which can be used to sign forms (HMAC)
* (See $_SESSION['uid'])
* - Token management to prevent XSRF attacks
* - Brute force protection with ban management
*
* TODOs
* - Replace globals with variables in Session class
*
* How to use:
* - http://tontof.net/kriss/php5/session
*/
class Session
{
// Personnalize PHP session name
public static $sessionName = '';
// If the user does not access any page within this time,
// his/her session is considered expired (3600 sec. = 1 hour)
public static $inactivityTimeout = 3600;
// Extra timeout for long sessions (if enabled) (82800 sec. = 23 hours)
public static $longSessionTimeout = 7776000; // 7776000 = 90 days
// If you get disconnected often or if your IP address changes often.
// Let you disable session cookie hijacking protection
public static $disableSessionProtection = false;
// Ban IP after this many failures.
public static $banAfter = 4;
// Ban duration for IP address after login failures (in seconds).
// (1800 sec. = 30 minutes)
public static $banDuration = 1800;
// File storage for failures and bans. If empty, no ban management.
public static $banFile = '';
/**
* Initialize session
*/
public static function init($longlastingsession = false)
{
//check if session name is correct
if ( (session_id() && !empty(self::$sessionName) && session_name()!=self::$sessionName) || $longlastingsession ) {
session_destroy();
}
// Force cookie path (but do not change lifetime)
$cookie = session_get_cookie_params();
// Default cookie expiration and path.
$cookiedir = '';
if (dirname($_SERVER['SCRIPT_NAME'])!='/') {
$cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/';
}
$ssl = false;
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
$ssl = true;
}
if ( $longlastingsession ) {
session_set_cookie_params(self::$longSessionTimeout, $cookiedir, null, $ssl, true);
}
else {
session_set_cookie_params(0, $cookiedir, null, $ssl, true);
}
//set server side valid session timeout
//WARNING! this may not work in shared session environment. See http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime about min value: it can be set in any application
ini_set('session.gc_maxlifetime', self::$longSessionTimeout);
// Use cookies to store session.
ini_set('session.use_cookies', 1);
// Force cookies for session (phpsessionID forbidden in URL)
ini_set('session.use_only_cookies', 1);
if ( !session_id() ) {
// Prevent php to use sessionID in URL if cookies are disabled.
ini_set('session.use_trans_sid', false);
if (!empty(self::$sessionName)) {
session_name(self::$sessionName);
}
session_start();
}
}
/**
* Returns the IP address
* (Used to prevent session cookie hijacking.)
*
* @return string IP addresses
*/
private static function _allIPs()
{
$ip = $_SERVER["REMOTE_ADDR"];
$ip.= isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? '_'.$_SERVER['HTTP_X_FORWARDED_FOR'] : '';
$ip.= isset($_SERVER['HTTP_CLIENT_IP']) ? '_'.$_SERVER['HTTP_CLIENT_IP'] : '';
return $ip;
}
/**
* Check that user/password is correct and then init some SESSION variables.
*
* @param string $login Login reference
* @param string $password Password reference
* @param string $loginTest Login to compare with login reference
* @param string $passwordTest Password to compare with password reference
* @param array $pValues Array of variables to store in SESSION
*
* @return true|false True if login and password are correct, false
* otherwise
*/
public static function login (
$login,
$password,
$loginTest,
$passwordTest,
$longlastingsession,
$pValues = array())
{
self::banInit();
if (self::banCanLogin()) {
if ($login === $loginTest && $password === $passwordTest) {
self::banLoginOk();
self::init($longlastingsession);
// Generate unique random number to sign forms (HMAC)
$_SESSION['uid'] = sha1(uniqid('', true).'_'.mt_rand());
$_SESSION['ip'] = self::_allIPs();
$_SESSION['username'] = $login;
// Set session expiration.
$_SESSION['expires_on'] = time() + self::$inactivityTimeout;
if ($longlastingsession) {
$_SESSION['longlastingsession'] = self::$longSessionTimeout;
$_SESSION['expires_on'] += $_SESSION['longlastingsession'];
}
foreach ($pValues as $key => $value) {
$_SESSION[$key] = $value;
}
return true;
}
self::banLoginFailed();
}
self::init();
return false;
}
/**
* Unset SESSION variable to force logout
*/
public static function logout()
{
// unset($_SESSION['uid'],$_SESSION['ip'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass'], $_SESSION['longlastingsession'], $_SESSION['poche_user']);
// Destruction du cookie (le code peut paraître complexe mais c'est pour être certain de reprendre les mêmes paramètres)
$args = array_merge(array(session_name(), ''), array_values(session_get_cookie_params()));
$args[2] = time() - 3600;
call_user_func_array('setcookie', $args);
// Suppression physique de la session
session_destroy();
}
/**
* Make sure user is logged in.
*
* @return true|false True if user is logged in, false otherwise
*/
public static function isLogged()
{
if (!isset ($_SESSION['uid'])
|| (self::$disableSessionProtection === false
&& $_SESSION['ip'] !== self::_allIPs())
|| time() >= $_SESSION['expires_on']) {
//self::logout();
return false;
}
// User accessed a page : Update his/her session expiration date.
$_SESSION['expires_on'] = time() + self::$inactivityTimeout;
if (!empty($_SESSION['longlastingsession'])) {
$_SESSION['expires_on'] += $_SESSION['longlastingsession'];
}
return true;
}
/**
* Create a token, store it in SESSION and return it
*
* @param string $salt to prevent birthday attack
*
* @return string Token created
*/
public static function getToken($salt = '')
{
if (!isset($_SESSION['tokens'])) {
$_SESSION['tokens']=array();
}
// We generate a random string and store it on the server side.
$rnd = sha1(uniqid('', true).'_'.mt_rand().$salt);
$_SESSION['tokens'][$rnd]=1;
return $rnd;
}
/**
* Tells if a token is ok. Using this function will destroy the token.
*
* @param string $token Token to test
*
* @return true|false True if token is correct, false otherwise
*/
public static function isToken($token)
{
if (isset($_SESSION['tokens'][$token])) {
unset($_SESSION['tokens'][$token]); // Token is used: destroy it.
return true; // Token is ok.
}
return false; // Wrong token, or already used.
}
/**
* Signal a failed login. Will ban the IP if too many failures:
*/
public static function banLoginFailed()
{
if (self::$banFile !== '') {
$ip = $_SERVER["REMOTE_ADDR"];
$gb = $GLOBALS['IPBANS'];
if (!isset($gb['FAILURES'][$ip])) {
$gb['FAILURES'][$ip] = 0;
}
$gb['FAILURES'][$ip]++;
if ($gb['FAILURES'][$ip] > (self::$banAfter - 1)) {
$gb['BANS'][$ip]= time() + self::$banDuration;
}
$GLOBALS['IPBANS'] = $gb;
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
}
}
/**
* Signals a successful login. Resets failed login counter.
*/
public static function banLoginOk()
{
if (self::$banFile !== '') {
$ip = $_SERVER["REMOTE_ADDR"];
$gb = $GLOBALS['IPBANS'];
unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]);
$GLOBALS['IPBANS'] = $gb;
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
}
}
/**
* Ban init
*/
public static function banInit()
{
if (self::$banFile !== '') {
if (!is_file(self::$banFile)) {
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export(array('FAILURES'=>array(), 'BANS'=>array()), true).";\n?>");
}
include self::$banFile;
}
}
/**
* Checks if the user CAN login. If 'true', the user can try to login.
*
* @return boolean true if user is banned, false otherwise
*/
public static function banCanLogin()
{
if (self::$banFile !== '') {
$ip = $_SERVER["REMOTE_ADDR"];
$gb = $GLOBALS['IPBANS'];
if (isset($gb['BANS'][$ip])) {
// User is banned. Check if the ban has expired:
if ($gb['BANS'][$ip] <= time()) {
// Ban expired, user can try to login again.
unset($gb['FAILURES'][$ip]);
unset($gb['BANS'][$ip]);
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
return true; // Ban has expired, user can login.
}
return false; // User is banned.
}
}
return true; // User is not banned.
}
/**
* Tells if a param exists in session
*
* @param $name name of the param to test
* @return bool
*/
public static function isInSession($name)
{
return (isset($_SESSION[$name]) ? : FALSE);
}
/**
* Returns param in session
*
* @param $name name of the param to return
* @return mixed param or null
*/
public static function getParam($name)
{
return (self::isInSession($name) ? $_SESSION[$name] : NULL);
}
/**
* Store value in session
*
* @param $name name of the variable to store
* @param $value value to store
*/
public static function setParam($name, $value)
{
$_SESSION[$name] = $value;
}
}

View File

@ -1,232 +0,0 @@
<?php
//--------------------------------------------------------------------------------------------------
// Session-Based Flash Messages v1.0
// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------
// Description:
//------------------------------------------------------------------------------
//
// Stores messages in Session data to be easily retrieved later on.
// This class includes four different types of messages:
// - Success
// - Error
// - Warning
// - Information
//
// See README for basic usage instructions, or see samples/index.php for more advanced samples
//
//--------------------------------------------------------------------------------------------------
// Changelog
//--------------------------------------------------------------------------------------------------
//
// 2011-05-15 - v1.0 - Initial Version
//
//--------------------------------------------------------------------------------------------------
class Messages {
//-----------------------------------------------------------------------------------------------
// Class Variables
//-----------------------------------------------------------------------------------------------
var $msgId;
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
var $msgClass = 'messages';
var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'>&times;</a>\n%s</div>\n";
var $msgBefore = '<p>';
var $msgAfter = "</p>\n";
/**
* Constructor
* @author Mike Everhart
*/
public function __construct() {
// Generate a unique ID for this user and session
$this->msgId = md5(uniqid());
// Create the session array if it doesnt already exist
settype($_SESSION, 'array');
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
}
/**
* Add a message to the queue
*
* @author Mike Everhart
*
* @param string $type The type of message to add
* @param string $message The message
* @param string $redirect_to (optional) If set, the user will be redirected to this URL
* @return bool
*
*/
public function add($type, $message, $redirect_to=null) {
if( !isset($_SESSION['flash_messages']) ) return false;
if( !isset($type) || !isset($message[0]) ) return false;
// Replace any shorthand codes with their full version
if( strlen(trim($type)) == 1 ) {
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
// Backwards compatibility...
} elseif( $type == 'information' ) {
$type = 'info';
}
// Make sure it's a valid message type
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
// If the session array doesn't exist, create it
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
$_SESSION['flash_messages'][$type][] = $message;
if( !is_null($redirect_to) ) {
header("Location: $redirect_to");
exit();
}
return true;
}
//-----------------------------------------------------------------------------------------------
// display()
// print queued messages to the screen
//-----------------------------------------------------------------------------------------------
/**
* Display the queued messages
*
* @author Mike Everhart
*
* @param string $type Which messages to display
* @param bool $print True = print the messages on the screen
* @return mixed
*
*/
public function display($type='all', $print=true) {
$messages = '';
$data = '';
if( !isset($_SESSION['flash_messages']) ) return false;
if( $type == 'g' || $type == 'growl' ) {
$this->displayGrowlMessages();
return true;
}
// Print a certain type of message?
if( in_array($type, $this->msgTypes) ) {
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
// Clear the viewed messages
$this->clear($type);
// Print ALL queued messages
} elseif( $type == 'all' ) {
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
$messages = '';
foreach( $msgArray as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
}
// Clear ALL of the messages
$this->clear();
// Invalid Message Type?
} else {
return false;
}
// Print everything to the screen or return the data
if( $print ) {
echo $data;
} else {
return $data;
}
}
/**
* Check to see if there are any queued error messages
*
* @author Mike Everhart
*
* @return bool true = There ARE error messages
* false = There are NOT any error messages
*
*/
public function hasErrors() {
return empty($_SESSION['flash_messages']['error']) ? false : true;
}
/**
* Check to see if there are any ($type) messages queued
*
* @author Mike Everhart
*
* @param string $type The type of messages to check for
* @return bool
*
*/
public function hasMessages($type=null) {
if( !is_null($type) ) {
if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
} else {
foreach( $this->msgTypes as $type ) {
if( !empty($_SESSION['flash_messages']) ) return true;
}
}
return false;
}
/**
* Clear messages from the session data
*
* @author Mike Everhart
*
* @param string $type The type of messages to clear
* @return bool
*
*/
public function clear($type='all') {
if( $type == 'all' ) {
unset($_SESSION['flash_messages']);
} else {
unset($_SESSION['flash_messages'][$type]);
}
return true;
}
public function __toString() { return $this->hasMessages(); }
public function __destruct() {
//$this->clear();
}
} // end class
?>

View File

@ -1,461 +0,0 @@
<?php
/* Full-Text RSS config */
// ......IMPORTANT......................................
// .....................................................
// Please do not change this file (config.php) directly.
// Save a copy as custom_config.php and make your
// changes to that instead. It will automatically
// override anything in config.php. Because config.php
// always gets loaded anyway, you can simply specify
// options you'd like to override in custom_config.php.
// .....................................................
global $options;
// Create config object
if (!isset($options)) $options = new stdClass();
// Enable service
// ----------------------
// Set this to false if you want to disable the service.
// If set to false, no feed is produced and users will
// be told that the service is disabled.
$options->enabled = true;
// Debug mode
// ----------------------
// Enable or disable debugging. When enabled debugging works by passing
// &debug to the makefulltextfeed.php querystring.
// Valid values:
// true or 'user' (default) - let user decide
// 'admin' - debug works only for logged in admin users
// false - disabled
$options->debug = true;
// Default entries (without access key)
// ----------------------
// The number of feed items to process when no API key is supplied
// and no &max=x value is supplied in the querystring.
$options->default_entries = 5;
// Max entries (without access key)
// ----------------------
// The maximum number of feed items to process when no access key is supplied.
// This limits the user-supplied &max=x value. For example, if the user
// asks for 20 items to be processed (&max=20), if max_entries is set to
// 10, only 10 will be processed.
$options->max_entries = 10;
// Full content
// ----------------------
// By default Full-Text RSS includes the extracted content in the output.
// You can exclude this from the output by passing '&content=0' in the querystring.
//
// Possible values...
// Always include: true
// Never include: false
// Include unless user overrides (&content=0): 'user' (default)
//
// Note: currently this does not disable full content extraction. It simply omits it
// from the output.
$options->content = 'user';
// Excerpts
// ----------------------
// By default Full-Text RSS does not include excerpts in the output.
// You can enable this by passing '&summary=1' in the querystring.
// This will include a plain text excerpt from the extracted content.
//
// Possible values...
// Always include: true (recommended for new users)
// Never include: false
// Don't include unless user overrides (&summary=1): 'user' (default)
//
// Important: if both content and excerpts are requested, the excerpt will be
// placed in the description element and the full content inside content:encoded.
// If excerpts are not requested, the full content will go inside the description element.
//
// Why are we not returning both excerpts and content by default?
// Mainly for backward compatibility.
// Excerpts should appear in the feed item's description element. Previous versions
// of Full-Text RSS did not return excerpts, so the description element was always
// used for the full content (as recommended by the RSS advisory). When returning both,
// we need somewhere else to place the content (content:encoded).
// Having both enabled should not create any problems for news readers, but it may create
// problems for developers upgrading from one of our earlier versions who may now find
// their applications are returning excerpts instead of the full content they were
// expecting. To avoid such surprises for users who are upgrading Full-Text RSS,
// excerpts must be explicitly requested in the querystring by default.
//
// Why not use a different element name for excerpts?
// According to the RSS advisory:
// "Publishers who employ summaries should store the summary in description and
// the full content in content:encoded, ordering description first within the item.
// On items with no summary, the full content should be stored in description."
// See: http://www.rssboard.org/rss-profile#namespace-elements-content-encoded
//
// For more consistent element naming, we recommend new users set this option to true.
// The full content can still be excluded via the querystring, but the element names
// will not change: when $options->summary = true, the description element will always
// be reserved for the excerpt and content:encoded always for full content.
$options->summary = 'user';
// Rewrite relative URLs
// ----------------------
// With this enabled relative URLs found in the extracted content
// block are automatically rewritten as absolute URLs.
$options->rewrite_relative_urls = true;
// Exclude items if extraction fails
// ---------------------------------
// Excludes items from the resulting feed
// if we cannot extract any content from the
// item URL.
// Possible values...
// Enable: true
// Disable: false (default)
// User decides: 'user' (this option will appear on the form)
$options->exclude_items_on_fail = 'user';
// Enable multi-page support
// -------------------------
// If enabled, we will try to follow next page links on multi-page articles.
// Currently this only happens for sites where next_page_link has been defined
// in a site config file.
$options->multipage = true;
// Enable caching
// ----------------------
// Enable this if you'd like to cache results
// for 10 minutes. Cache files are written to disk (in cache/ subfolders
// - which must be writable).
// Initially it's best to keep this disabled to make sure everything works
// as expected. If you have APC enabled, please also see smart_cache in the
// advanced section.
$options->caching = false;
// Cache directory
// ----------------------
// Only used if caching is true
$options->cache_dir = dirname(__FILE__).'/cache';
// Message to prepend (without access key)
// ----------------------
// HTML to insert at the beginning of each feed item when no access key is supplied.
// Substitution tags:
// {url} - Feed item URL
// {effective-url} - Feed item URL after we've followed all redirects
$options->message_to_prepend = '';
// Message to append (without access key)
// ----------------------
// HTML to insert at the end of each feed item when no access key is supplied.
// Substitution tags:
// {url} - Feed item URL
// {effective-url} - Feed item URL after we've followed all redirects
$options->message_to_append = '';
// Error message when content extraction fails (without access key)
// ----------------------
$options->error_message = '[unable to retrieve full-text content]';
// Keep enclosure in feed items
// If enabled, we will try to preserve enclosures if present.
// ----------------------
$options->keep_enclosures = true;
// Detect language
// ---------------
// Should we try and find/guess the language of the article being processed?
// Values will be placed inside the <dc:language> element inside each <item> element
// Possible values:
// * Ignore language: 0
// * Use article/feed metadata (e.g. HTML lang attribute): 1 (default)
// * As above, but guess if not present: 2
// * Always guess: 3
// * User decides: 'user' (value of 0-3 can be passed in querystring: e.g. &l=2)
$options->detect_language = 1;
// Registration key
// ---------------
// The registration key is optional. It is not required to use Full-Text RSS,
// and does not affect the normal operation of Full-Text RSS. It is currently
// only used on admin pages which help you update site patterns with the
// latest version offered by FiveFilters.org. For these admin-related
// tasks to complete, we will require a valid registration key.
// If you would like one, you can purchase the latest version of Full-Text RSS
// at http://fivefilters.org/content-only/
// Your registration key will automatically be sent in the confirmation email.
// Once you have it, simply copy and paste it here.
$options->registration_key = '';
/////////////////////////////////////////////////
/// RESTRICT ACCESS /////////////////////////////
/////////////////////////////////////////////////
// Admin credentials
// ----------------------
// Certain pages/actions, e.g. updating site patterns with our online tool, will require admin credentials.
// To use these pages, enter a password here and you'll be prompted for it when you try to access those pages.
// If no password or username is set, pages requiring admin privelages will be inaccessible.
// The default username is 'admin'.
// If overriding with an environment variable, separate username and password with a colon, e.g.:
// ftr_admin_credentials: admin:my-secret-password
// Example: $options->admin_credentials = array('username'=>'admin', 'password'=>'my-secret-password');
$options->admin_credentials = array('username'=>'admin', 'password'=>'');
// URLs to allow
// ----------------------
// List of URLs (or parts of a URL) which the service will accept.
// If the list is empty, all URLs (except those specified in the blocked list below)
// will be permitted.
// Empty: array();
// Non-empty example: array('example.com', 'anothersite.org');
$options->allowed_urls = array();
// URLs to block
// ----------------------
// List of URLs (or parts of a URL) which the service will not accept.
// Note: this list is ignored if allowed_urls is not empty
$options->blocked_urls = array();
// Key holder(s) only?
// ----------------------
// Set this to true if you want to restrict access only to
// those with a key (see below to specify key(s)).
// If set to true, no feed is produced unless a valid
// key is provided.
$options->key_required = false;
// Favour item titles in feed
// ----------------------
// By default, when processing feeds, we assume item titles in the feed
// have not been truncated. So after processing web pages, the extracted titles
// are not used in the generated feed. If you prefer to have extracted titles in
// the feed you can either set this to false, in which case we will always favour
// extracted titles. Alternatively, if set to 'user' (default) we'll use the
// extracted title if you pass '&use_extracted_title' in the querystring.
// Possible values:
// * Favour feed titles: true
// * Favour extracted titles: false
// * Favour feed titles with user override: 'user' (default)
// Note: this has no effect when the input URL is to a web page - in these cases
// we always use the extracted title in the generated feed.
$options->favour_feed_titles = 'user';
// Access keys (password protected access)
// ------------------------------------
// NOTE: You do not need an API key from fivefilters.org to run your own
// copy of the code. This is here if you'd like to restrict access to
// _your_ copy.
// Keys let you group users - those with a key and those without - and
// restrict access to the service to those without a key.
// If you want everyone to access the service in the same way, you can
// leave the array below empty and ignore the access key options further down.
// The options further down let you control how the service should behave
// in each mode.
// Note: Explicitly including the index number (1 and 2 in the examples below)
// is highly recommended (when generating feeds, we encode the key and
// refer to it by index number and hash).
$options->api_keys = array();
// Example:
// $options->api_keys[1] = 'secret-key-1';
// $options->api_keys[2] = 'secret-key-2';
// Default entries (with access key)
// ----------------------
// The number of feed items to process when a valid access key is supplied.
$options->default_entries_with_key = 5;
// Max entries (with access key)
// ----------------------
// The maximum number of feed items to process when a valid access key is supplied.
$options->max_entries_with_key = 10;
/////////////////////////////////////////////////
/// ADVANCED OPTIONS ////////////////////////////
/////////////////////////////////////////////////
// Enable XSS filter?
// ----------------------
// We have not enabled this by default because we assume the majority of
// our users do not display the HTML retrieved by Full-Text RSS
// in a web page without further processing. If you subscribe to our generated
// feeds in your news reader application, it should, if it's good software, already
// filter the resulting HTML for XSS attacks, making it redundant for
// Full-Text RSS do the same. Similarly with frameworks/CMS which display
// feed content - the content should be treated like any other user-submitted content.
//
// If you are writing an application yourself which is processing feeds generated by
// Full-Text RSS, you can either filter the HTML yourself to remove potential XSS attacks
// or enable this option. This might be useful if you are processing our generated
// feeds with JavaScript on the client side - although there's client side xss
// filtering available too, e.g. https://code.google.com/p/google-caja/wiki/JsHtmlSanitizer
//
// If enabled, we'll pass retrieved HTML content through htmLawed with
// safe flag on and style attributes denied, see
// http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htmLawed_README.htm#s3.6
// Note: if enabled this will also remove certain elements you may want to preserve, such as iframes.
//
// Valid values:
// true - enabled, all content will be filtered
// 'user' (default) - user must pass &xss in makefulltextfeed.php querystring to enable
// false - disabled
$options->xss_filter = 'user';
// Allowed parsers
// ----------------------
// Full-Text RSS attempts to use PHP's libxml extension to process HTML.
// While fast, on some sites it may not always produce good results.
// For these sites, you can specify an alternative HTML parser:
// parser: html5lib
// The html5lib parser is bundled with Full-Text RSS.
// see http://code.google.com/p/html5lib/
//
// To disable HTML parsing with html5lib, you can remove it from this list.
// By default we allow both: libxml and html5lib.
$options->allowed_parsers = array('libxml', 'html5lib');
//$options->allowed_parsers = array('libxml'); //disable html5lib - forcing libxml in all cases
// Enable Cross-Origin Resource Sharing (CORS)
// ----------------------
// If enabled we'll send the following HTTP header
// Access-Control-Allow-Origin: *
// see http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
$options->cors = false;
// Use APC user cache?
// ----------------------
// If enabled we will store site config files (when requested
// for the first time) in APC's user cache. Keys prefixed with 'sc.'
// This improves performance by reducing disk access.
// Note: this has no effect if APC is unavailable on your server.
$options->apc = true;
// Smart cache (experimental)
// ----------------------
// With this option enabled we will not cache to disk immediately.
// We will store the cache key in APC and if it's requested again
// we will cache results to disk. Keys prefixed with 'cache.'
// This improves performance by reducing disk access.
// Note: this has no effect if APC is disabled or unavailable on your server,
// or if you have caching disabled.
$options->smart_cache = true;
// Fingerprints
// ----------------------
// key is fingerprint (fragment to find in HTML)
// value is host name to use for site config lookup if fingerprint matches
$options->fingerprints = array(
// Posterous
'<meta name="generator" content="Posterous"' => array('hostname'=>'fingerprint.posterous.com', 'head'=>true),
// Blogger
'<meta content=\'blogger\' name=\'generator\'' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
'<meta name="generator" content="Blogger"' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
// WordPress (hosted)
// '<meta name="generator" content="WordPress.com"' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true),
// WordPress (self-hosted and hosted)
'<meta name="generator" content="WordPress' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true)
);
// User Agent strings - mapping domain names
// ----------------------
// e.g. $options->user_agents = array('example.org' => 'PHP/5.2');
$options->user_agents = array( 'lifehacker.com' => 'PHP/5.2',
'gawker.com' => 'PHP/5.2',
'deadspin.com' => 'PHP/5.2',
'kotaku.com' => 'PHP/5.2',
'jezebel.com' => 'PHP/5.2',
'io9.com' => 'PHP/5.2',
'jalopnik.com' => 'PHP/5.2',
'gizmodo.com' => 'PHP/5.2',
'.wikipedia.org' => 'Mozilla/5.2',
'.fok.nl' => 'Googlebot/2.1',
'getpocket.com' => 'PHP/5.2'
);
// URL Rewriting
// ----------------------
// Currently allows simple string replace of URLs.
// Useful for rewriting certain URLs to point to a single page
// or HTML view. Although using the single_page_link site config
// instruction is the preferred way to do this, sometimes, as
// with Google Docs URLs, it's not possible.
// Note: this might move to the site config file at some point.
$options->rewrite_url = array(
// Rewrite public Google Docs URLs to point to HTML view:
// if a URL contains docs.google.com, replace /Doc? with /View?
'docs.google.com' => array('/Doc?' => '/View?'),
'tnr.com' => array('tnr.com/article/' => 'tnr.com/print/article/'),
'.m.wikipedia.org' => array('.m.wikipedia.org' => '.wikipedia.org'),
'm.vanityfair.com' => array('m.vanityfair.com' => 'www.vanityfair.com')
);
// Content-Type exceptions
// -----------------------
// Here you can define different actions based
// on the Content-Type header returned by server.
// MIME type as key, action as value.
// Valid actions:
// * 'exclude' - exclude this item from the result
// * 'link' - create HTML link to the item
$options->content_type_exc = array(
'application/pdf' => array('action'=>'link', 'name'=>'PDF'),
'image' => array('action'=>'link', 'name'=>'Image'),
'audio' => array('action'=>'link', 'name'=>'Audio'),
'video' => array('action'=>'link', 'name'=>'Video')
);
// Cache directory level
// ----------------------
// Spread cache files over different directories (only used if caching is enabled).
// Used to prevent large number of files in one directory.
// This corresponds to Zend_Cache's hashed_directory_level
// see http://framework.zend.com/manual/en/zend.cache.backends.html
// It's best not to change this if you're unsure.
$options->cache_directory_level = 0;
// Cache cleanup
// -------------
// 0 = script will not clean cache (rename cachecleanup.php and use it for scheduled (e.g. cron) cache cleanup)
// 1 = clean cache everytime the script runs (not recommended)
// 100 = clean cache roughly once every 100 script runs
// x = clean cache roughly once every x script runs
// ...you get the idea :)
$options->cache_cleanup = 100;
/////////////////////////////////////////////////
/// DO NOT CHANGE ANYTHING BELOW THIS ///////////
/////////////////////////////////////////////////
if (!defined('_FF_FTR_VERSION')) define('_FF_FTR_VERSION', '3.2');
if (basename(__FILE__) == 'config.php') {
if (file_exists(dirname(__FILE__).'/custom_config.php')) {
require_once dirname(__FILE__).'/custom_config.php';
}
// check for environment variables - often used on cloud platforms
// environment variables should be prefixed with 'ftr_', e.g.
// ftr_max_entries: 1
// will set the max_entries value to 1.
foreach ($options as $_key=>&$_val) {
$_key = "ftr_$_key";
if (($_env = getenv($_key)) !== false) {
if (is_array($_val)) {
if ($_key === 'ftr_admin_credentials') {
$_val = array_combine(array('username', 'password'), array_map('trim', explode(':', $_env, 2)));
if ($_val === false) $_val = array('username'=>'admin', 'password'=>'');
}
} elseif ($_env === 'true' || $_env === 'false') {
$_val = ($_env === 'true');
} elseif (is_numeric($_env)) {
$_val = (int)$_env;
} else { // string
$_val = $_env;
}
}
}
unset($_key, $_val, $_env);
}

View File

@ -1,11 +0,0 @@
<?php
/**
* This is a stub include that automatically configures the include path.
*/
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
require_once 'HTMLPurifier/Bootstrap.php';
require_once 'HTMLPurifier.autoload.php';
// vim: et sw=4 sts=4

View File

@ -1,27 +0,0 @@
<?php
/**
* @file
* Convenience file that registers autoload handler for HTML Purifier.
* It also does some sanity checks.
*/
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
// We need unregister for our pre-registering functionality
HTMLPurifier_Bootstrap::registerAutoload();
if (function_exists('__autoload')) {
// Be polite and ensure that userland autoload gets retained
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class)
{
return HTMLPurifier_Bootstrap::autoload($class);
}
}
if (ini_get('zend.ze1_compatibility_mode')) {
trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR);
}
// vim: et sw=4 sts=4

View File

@ -1,4 +0,0 @@
<?php
if (!defined('HTMLPURIFIER_PREFIX')) {
define('HTMLPURIFIER_PREFIX', __DIR__);
}

View File

@ -1,25 +0,0 @@
<?php
/**
* @file
* Defines a function wrapper for HTML Purifier for quick use.
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
*/
/**
* Purify HTML.
* @param string $html String HTML to purify
* @param mixed $config Configuration to use, can be any value accepted by
* HTMLPurifier_Config::create()
* @return string
*/
function HTMLPurifier($html, $config = null)
{
static $purifier = false;
if (!$purifier) {
$purifier = new HTMLPurifier();
}
return $purifier->purify($html, $config);
}
// vim: et sw=4 sts=4

View File

@ -1,229 +0,0 @@
<?php
/**
* @file
* This file was auto-generated by generate-includes.php and includes all of
* the core files required by HTML Purifier. Use this if performance is a
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.6.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
* because 'require' not 'require_once' is used.
*
* @warning
* This file requires that the include path contains the HTML Purifier
* library directory; this is not auto-set.
*/
require 'HTMLPurifier.php';
require 'HTMLPurifier/Arborize.php';
require 'HTMLPurifier/AttrCollections.php';
require 'HTMLPurifier/AttrDef.php';
require 'HTMLPurifier/AttrTransform.php';
require 'HTMLPurifier/AttrTypes.php';
require 'HTMLPurifier/AttrValidator.php';
require 'HTMLPurifier/Bootstrap.php';
require 'HTMLPurifier/Definition.php';
require 'HTMLPurifier/CSSDefinition.php';
require 'HTMLPurifier/ChildDef.php';
require 'HTMLPurifier/Config.php';
require 'HTMLPurifier/ConfigSchema.php';
require 'HTMLPurifier/ContentSets.php';
require 'HTMLPurifier/Context.php';
require 'HTMLPurifier/DefinitionCache.php';
require 'HTMLPurifier/DefinitionCacheFactory.php';
require 'HTMLPurifier/Doctype.php';
require 'HTMLPurifier/DoctypeRegistry.php';
require 'HTMLPurifier/ElementDef.php';
require 'HTMLPurifier/Encoder.php';
require 'HTMLPurifier/EntityLookup.php';
require 'HTMLPurifier/EntityParser.php';
require 'HTMLPurifier/ErrorCollector.php';
require 'HTMLPurifier/ErrorStruct.php';
require 'HTMLPurifier/Exception.php';
require 'HTMLPurifier/Filter.php';
require 'HTMLPurifier/Generator.php';
require 'HTMLPurifier/HTMLDefinition.php';
require 'HTMLPurifier/HTMLModule.php';
require 'HTMLPurifier/HTMLModuleManager.php';
require 'HTMLPurifier/IDAccumulator.php';
require 'HTMLPurifier/Injector.php';
require 'HTMLPurifier/Language.php';
require 'HTMLPurifier/LanguageFactory.php';
require 'HTMLPurifier/Length.php';
require 'HTMLPurifier/Lexer.php';
require 'HTMLPurifier/Node.php';
require 'HTMLPurifier/PercentEncoder.php';
require 'HTMLPurifier/PropertyList.php';
require 'HTMLPurifier/PropertyListIterator.php';
require 'HTMLPurifier/Queue.php';
require 'HTMLPurifier/Strategy.php';
require 'HTMLPurifier/StringHash.php';
require 'HTMLPurifier/StringHashParser.php';
require 'HTMLPurifier/TagTransform.php';
require 'HTMLPurifier/Token.php';
require 'HTMLPurifier/TokenFactory.php';
require 'HTMLPurifier/URI.php';
require 'HTMLPurifier/URIDefinition.php';
require 'HTMLPurifier/URIFilter.php';
require 'HTMLPurifier/URIParser.php';
require 'HTMLPurifier/URIScheme.php';
require 'HTMLPurifier/URISchemeRegistry.php';
require 'HTMLPurifier/UnitConverter.php';
require 'HTMLPurifier/VarParser.php';
require 'HTMLPurifier/VarParserException.php';
require 'HTMLPurifier/Zipper.php';
require 'HTMLPurifier/AttrDef/CSS.php';
require 'HTMLPurifier/AttrDef/Clone.php';
require 'HTMLPurifier/AttrDef/Enum.php';
require 'HTMLPurifier/AttrDef/Integer.php';
require 'HTMLPurifier/AttrDef/Lang.php';
require 'HTMLPurifier/AttrDef/Switch.php';
require 'HTMLPurifier/AttrDef/Text.php';
require 'HTMLPurifier/AttrDef/URI.php';
require 'HTMLPurifier/AttrDef/CSS/Number.php';
require 'HTMLPurifier/AttrDef/CSS/AlphaValue.php';
require 'HTMLPurifier/AttrDef/CSS/Background.php';
require 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
require 'HTMLPurifier/AttrDef/CSS/Border.php';
require 'HTMLPurifier/AttrDef/CSS/Color.php';
require 'HTMLPurifier/AttrDef/CSS/Composite.php';
require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
require 'HTMLPurifier/AttrDef/CSS/Font.php';
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
require 'HTMLPurifier/AttrDef/CSS/Ident.php';
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require 'HTMLPurifier/AttrDef/HTML/Class.php';
require 'HTMLPurifier/AttrDef/HTML/Color.php';
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require 'HTMLPurifier/AttrDef/HTML/ID.php';
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
require 'HTMLPurifier/AttrDef/HTML/Length.php';
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
require 'HTMLPurifier/AttrDef/URI/Email.php';
require 'HTMLPurifier/AttrDef/URI/Host.php';
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
require 'HTMLPurifier/AttrTransform/Background.php';
require 'HTMLPurifier/AttrTransform/BdoDir.php';
require 'HTMLPurifier/AttrTransform/BgColor.php';
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
require 'HTMLPurifier/AttrTransform/Border.php';
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
require 'HTMLPurifier/AttrTransform/Input.php';
require 'HTMLPurifier/AttrTransform/Lang.php';
require 'HTMLPurifier/AttrTransform/Length.php';
require 'HTMLPurifier/AttrTransform/Name.php';
require 'HTMLPurifier/AttrTransform/NameSync.php';
require 'HTMLPurifier/AttrTransform/Nofollow.php';
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
require 'HTMLPurifier/AttrTransform/SafeObject.php';
require 'HTMLPurifier/AttrTransform/SafeParam.php';
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
require 'HTMLPurifier/AttrTransform/TargetBlank.php';
require 'HTMLPurifier/AttrTransform/Textarea.php';
require 'HTMLPurifier/ChildDef/Chameleon.php';
require 'HTMLPurifier/ChildDef/Custom.php';
require 'HTMLPurifier/ChildDef/Empty.php';
require 'HTMLPurifier/ChildDef/List.php';
require 'HTMLPurifier/ChildDef/Required.php';
require 'HTMLPurifier/ChildDef/Optional.php';
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
require 'HTMLPurifier/ChildDef/Table.php';
require 'HTMLPurifier/DefinitionCache/Decorator.php';
require 'HTMLPurifier/DefinitionCache/Null.php';
require 'HTMLPurifier/DefinitionCache/Serializer.php';
require 'HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
require 'HTMLPurifier/HTMLModule/Bdo.php';
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Edit.php';
require 'HTMLPurifier/HTMLModule/Forms.php';
require 'HTMLPurifier/HTMLModule/Hypertext.php';
require 'HTMLPurifier/HTMLModule/Iframe.php';
require 'HTMLPurifier/HTMLModule/Image.php';
require 'HTMLPurifier/HTMLModule/Legacy.php';
require 'HTMLPurifier/HTMLModule/List.php';
require 'HTMLPurifier/HTMLModule/Name.php';
require 'HTMLPurifier/HTMLModule/Nofollow.php';
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Object.php';
require 'HTMLPurifier/HTMLModule/Presentation.php';
require 'HTMLPurifier/HTMLModule/Proprietary.php';
require 'HTMLPurifier/HTMLModule/Ruby.php';
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
require 'HTMLPurifier/HTMLModule/SafeObject.php';
require 'HTMLPurifier/HTMLModule/SafeScripting.php';
require 'HTMLPurifier/HTMLModule/Scripting.php';
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
require 'HTMLPurifier/HTMLModule/Tables.php';
require 'HTMLPurifier/HTMLModule/Target.php';
require 'HTMLPurifier/HTMLModule/TargetBlank.php';
require 'HTMLPurifier/HTMLModule/Text.php';
require 'HTMLPurifier/HTMLModule/Tidy.php';
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
require 'HTMLPurifier/Injector/AutoParagraph.php';
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
require 'HTMLPurifier/Injector/Linkify.php';
require 'HTMLPurifier/Injector/PurifierLinkify.php';
require 'HTMLPurifier/Injector/RemoveEmpty.php';
require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
require 'HTMLPurifier/Injector/SafeObject.php';
require 'HTMLPurifier/Lexer/DOMLex.php';
require 'HTMLPurifier/Lexer/DirectLex.php';
require 'HTMLPurifier/Node/Comment.php';
require 'HTMLPurifier/Node/Element.php';
require 'HTMLPurifier/Node/Text.php';
require 'HTMLPurifier/Strategy/Composite.php';
require 'HTMLPurifier/Strategy/Core.php';
require 'HTMLPurifier/Strategy/FixNesting.php';
require 'HTMLPurifier/Strategy/MakeWellFormed.php';
require 'HTMLPurifier/Strategy/RemoveForeignElements.php';
require 'HTMLPurifier/Strategy/ValidateAttributes.php';
require 'HTMLPurifier/TagTransform/Font.php';
require 'HTMLPurifier/TagTransform/Simple.php';
require 'HTMLPurifier/Token/Comment.php';
require 'HTMLPurifier/Token/Tag.php';
require 'HTMLPurifier/Token/Empty.php';
require 'HTMLPurifier/Token/End.php';
require 'HTMLPurifier/Token/Start.php';
require 'HTMLPurifier/Token/Text.php';
require 'HTMLPurifier/URIFilter/DisableExternal.php';
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
require 'HTMLPurifier/URIFilter/DisableResources.php';
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
require 'HTMLPurifier/URIFilter/Munge.php';
require 'HTMLPurifier/URIFilter/SafeIframe.php';
require 'HTMLPurifier/URIScheme/data.php';
require 'HTMLPurifier/URIScheme/file.php';
require 'HTMLPurifier/URIScheme/ftp.php';
require 'HTMLPurifier/URIScheme/http.php';
require 'HTMLPurifier/URIScheme/https.php';
require 'HTMLPurifier/URIScheme/mailto.php';
require 'HTMLPurifier/URIScheme/news.php';
require 'HTMLPurifier/URIScheme/nntp.php';
require 'HTMLPurifier/VarParser/Flexible.php';
require 'HTMLPurifier/VarParser/Native.php';

View File

@ -1,30 +0,0 @@
<?php
/**
* @file
* Emulation layer for code that used kses(), substituting in HTML Purifier.
*/
require_once dirname(__FILE__) . '/HTMLPurifier.auto.php';
function kses($string, $allowed_html, $allowed_protocols = null)
{
$config = HTMLPurifier_Config::createDefault();
$allowed_elements = array();
$allowed_attributes = array();
foreach ($allowed_html as $element => $attributes) {
$allowed_elements[$element] = true;
foreach ($attributes as $attribute => $x) {
$allowed_attributes["$element.$attribute"] = true;
}
}
$config->set('HTML.AllowedElements', $allowed_elements);
$config->set('HTML.AllowedAttributes', $allowed_attributes);
if ($allowed_protocols !== null) {
$config->set('URI.AllowedSchemes', $allowed_protocols);
}
$purifier = new HTMLPurifier($config);
return $purifier->purify($string);
}
// vim: et sw=4 sts=4

View File

@ -1,11 +0,0 @@
<?php
/**
* @file
* Convenience stub file that adds HTML Purifier's library file to the path
* without any other side-effects.
*/
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
// vim: et sw=4 sts=4

View File

@ -1,292 +0,0 @@
<?php
/*! @mainpage
*
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
* HTML and rigorously test, validate and filter it into a version that
* is safe for output onto webpages. It achieves this by:
*
* -# Lexing (parsing into tokens) the document,
* -# Executing various strategies on the tokens:
* -# Removing all elements not in the whitelist,
* -# Making the tokens well-formed,
* -# Fixing the nesting of the nodes, and
* -# Validating attributes of the nodes; and
* -# Generating HTML from the purified tokens.
*
* However, most users will only need to interface with the HTMLPurifier
* and HTMLPurifier_Config.
*/
/*
HTML Purifier 4.6.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
*
* @note There are several points in which configuration can be specified
* for HTML Purifier. The precedence of these (from lowest to
* highest) is as follows:
* -# Instance: new HTMLPurifier($config)
* -# Invocation: purify($html, $config)
* These configurations are entirely independent of each other and
* are *not* merged (this behavior may change in the future).
*
* @todo We need an easier way to inject strategies using the configuration
* object.
*/
class HTMLPurifier
{
/**
* Version of HTML Purifier.
* @type string
*/
public $version = '4.6.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.6.0';
/**
* Global configuration object.
* @type HTMLPurifier_Config
*/
public $config;
/**
* Array of extra filter objects to run on HTML,
* for backwards compatibility.
* @type HTMLPurifier_Filter[]
*/
private $filters = array();
/**
* Single instance of HTML Purifier.
* @type HTMLPurifier
*/
private static $instance;
/**
* @type HTMLPurifier_Strategy_Core
*/
protected $strategy;
/**
* @type HTMLPurifier_Generator
*/
protected $generator;
/**
* Resultant context of last run purification.
* Is an array of contexts if the last called method was purifyArray().
* @type HTMLPurifier_Context
*/
public $context;
/**
* Initializes the purifier.
*
* @param HTMLPurifier_Config $config Optional HTMLPurifier_Config object
* for all instances of the purifier, if omitted, a default
* configuration is supplied (which can be overridden on a
* per-use basis).
* The parameter can also be any type that
* HTMLPurifier_Config::create() supports.
*/
public function __construct($config = null)
{
$this->config = HTMLPurifier_Config::create($config);
$this->strategy = new HTMLPurifier_Strategy_Core();
}
/**
* Adds a filter to process the output. First come first serve
*
* @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object
*/
public function addFilter($filter)
{
trigger_error(
'HTMLPurifier->addFilter() is deprecated, use configuration directives' .
' in the Filter namespace or Filter.Custom',
E_USER_WARNING
);
$this->filters[] = $filter;
}
/**
* Filters an HTML snippet/document to be XSS-free and standards-compliant.
*
* @param string $html String of HTML to purify
* @param HTMLPurifier_Config $config Config object for this operation,
* if omitted, defaults to the config object specified during this
* object's construction. The parameter can also be any type
* that HTMLPurifier_Config::create() supports.
*
* @return string Purified HTML
*/
public function purify($html, $config = null)
{
// :TODO: make the config merge in, instead of replace
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
// implementation is partially environment dependant, partially
// configuration dependant
$lexer = HTMLPurifier_Lexer::create($config);
$context = new HTMLPurifier_Context();
// setup HTML generator
$this->generator = new HTMLPurifier_Generator($config, $context);
$context->register('Generator', $this->generator);
// set up global context variables
if ($config->get('Core.CollectErrors')) {
// may get moved out if other facilities use it
$language_factory = HTMLPurifier_LanguageFactory::instance();
$language = $language_factory->create($config, $context);
$context->register('Locale', $language);
$error_collector = new HTMLPurifier_ErrorCollector($context);
$context->register('ErrorCollector', $error_collector);
}
// setup id_accumulator context, necessary due to the fact that
// AttrValidator can be called from many places
$id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
$context->register('IDAccumulator', $id_accumulator);
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
// setup filters
$filter_flags = $config->getBatch('Filter');
$custom_filters = $filter_flags['Custom'];
unset($filter_flags['Custom']);
$filters = array();
foreach ($filter_flags as $filter => $flag) {
if (!$flag) {
continue;
}
if (strpos($filter, '.') !== false) {
continue;
}
$class = "HTMLPurifier_Filter_$filter";
$filters[] = new $class;
}
foreach ($custom_filters as $filter) {
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
$filters[] = $filter;
}
$filters = array_merge($filters, $this->filters);
// maybe prepare(), but later
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
$html = $filters[$i]->preFilter($html, $config, $context);
}
// purified HTML
$html =
$this->generator->generateFromTokens(
// list of tokens
$this->strategy->execute(
// list of un-purified tokens
$lexer->tokenizeHTML(
// un-purified HTML
$html,
$config,
$context
),
$config,
$context
)
);
for ($i = $filter_size - 1; $i >= 0; $i--) {
$html = $filters[$i]->postFilter($html, $config, $context);
}
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
$this->context =& $context;
return $html;
}
/**
* Filters an array of HTML snippets
*
* @param string[] $array_of_html Array of html snippets
* @param HTMLPurifier_Config $config Optional config object for this operation.
* See HTMLPurifier::purify() for more details.
*
* @return string[] Array of purified HTML
*/
public function purifyArray($array_of_html, $config = null)
{
$context_array = array();
foreach ($array_of_html as $key => $html) {
$array_of_html[$key] = $this->purify($html, $config);
$context_array[$key] = $this->context;
}
$this->context = $context_array;
return $array_of_html;
}
/**
* Singleton for enforcing just one HTML Purifier in your system
*
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
* HTMLPurifier instance to overload singleton with,
* or HTMLPurifier_Config instance to configure the
* generated version with.
*
* @return HTMLPurifier
*/
public static function instance($prototype = null)
{
if (!self::$instance || $prototype) {
if ($prototype instanceof HTMLPurifier) {
self::$instance = $prototype;
} elseif ($prototype) {
self::$instance = new HTMLPurifier($prototype);
} else {
self::$instance = new HTMLPurifier();
}
}
return self::$instance;
}
/**
* Singleton for enforcing just one HTML Purifier in your system
*
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
* HTMLPurifier instance to overload singleton with,
* or HTMLPurifier_Config instance to configure the
* generated version with.
*
* @return HTMLPurifier
* @note Backwards compatibility, see instance()
*/
public static function getInstance($prototype = null)
{
return HTMLPurifier::instance($prototype);
}
}
// vim: et sw=4 sts=4

View File

@ -1,223 +0,0 @@
<?php
/**
* @file
* This file was auto-generated by generate-includes.php and includes all of
* the core files required by HTML Purifier. This is a convenience stub that
* includes all files using dirname(__FILE__) and require_once. PLEASE DO NOT
* EDIT THIS FILE, changes will be overwritten the next time the script is run.
*
* Changes to include_path are not necessary.
*/
$__dir = dirname(__FILE__);
require_once $__dir . '/HTMLPurifier.php';
require_once $__dir . '/HTMLPurifier/Arborize.php';
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
require_once $__dir . '/HTMLPurifier/AttrDef.php';
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
require_once $__dir . '/HTMLPurifier/AttrTypes.php';
require_once $__dir . '/HTMLPurifier/AttrValidator.php';
require_once $__dir . '/HTMLPurifier/Bootstrap.php';
require_once $__dir . '/HTMLPurifier/Definition.php';
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
require_once $__dir . '/HTMLPurifier/ChildDef.php';
require_once $__dir . '/HTMLPurifier/Config.php';
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
require_once $__dir . '/HTMLPurifier/ContentSets.php';
require_once $__dir . '/HTMLPurifier/Context.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache.php';
require_once $__dir . '/HTMLPurifier/DefinitionCacheFactory.php';
require_once $__dir . '/HTMLPurifier/Doctype.php';
require_once $__dir . '/HTMLPurifier/DoctypeRegistry.php';
require_once $__dir . '/HTMLPurifier/ElementDef.php';
require_once $__dir . '/HTMLPurifier/Encoder.php';
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
require_once $__dir . '/HTMLPurifier/EntityParser.php';
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
require_once $__dir . '/HTMLPurifier/Exception.php';
require_once $__dir . '/HTMLPurifier/Filter.php';
require_once $__dir . '/HTMLPurifier/Generator.php';
require_once $__dir . '/HTMLPurifier/HTMLDefinition.php';
require_once $__dir . '/HTMLPurifier/HTMLModule.php';
require_once $__dir . '/HTMLPurifier/HTMLModuleManager.php';
require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
require_once $__dir . '/HTMLPurifier/Injector.php';
require_once $__dir . '/HTMLPurifier/Language.php';
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
require_once $__dir . '/HTMLPurifier/Length.php';
require_once $__dir . '/HTMLPurifier/Lexer.php';
require_once $__dir . '/HTMLPurifier/Node.php';
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
require_once $__dir . '/HTMLPurifier/PropertyList.php';
require_once $__dir . '/HTMLPurifier/PropertyListIterator.php';
require_once $__dir . '/HTMLPurifier/Queue.php';
require_once $__dir . '/HTMLPurifier/Strategy.php';
require_once $__dir . '/HTMLPurifier/StringHash.php';
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
require_once $__dir . '/HTMLPurifier/TagTransform.php';
require_once $__dir . '/HTMLPurifier/Token.php';
require_once $__dir . '/HTMLPurifier/TokenFactory.php';
require_once $__dir . '/HTMLPurifier/URI.php';
require_once $__dir . '/HTMLPurifier/URIDefinition.php';
require_once $__dir . '/HTMLPurifier/URIFilter.php';
require_once $__dir . '/HTMLPurifier/URIParser.php';
require_once $__dir . '/HTMLPurifier/URIScheme.php';
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
require_once $__dir . '/HTMLPurifier/VarParser.php';
require_once $__dir . '/HTMLPurifier/VarParserException.php';
require_once $__dir . '/HTMLPurifier/Zipper.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Clone.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Switch.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/AlphaValue.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Background.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ident.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Background.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Nofollow.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetBlank.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
require_once $__dir . '/HTMLPurifier/ChildDef/List.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Forms.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Iframe.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Nofollow.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeEmbed.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeObject.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeScripting.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetBlank.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
require_once $__dir . '/HTMLPurifier/Node/Comment.php';
require_once $__dir . '/HTMLPurifier/Node/Element.php';
require_once $__dir . '/HTMLPurifier/Node/Text.php';
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
require_once $__dir . '/HTMLPurifier/Strategy/MakeWellFormed.php';
require_once $__dir . '/HTMLPurifier/Strategy/RemoveForeignElements.php';
require_once $__dir . '/HTMLPurifier/Strategy/ValidateAttributes.php';
require_once $__dir . '/HTMLPurifier/TagTransform/Font.php';
require_once $__dir . '/HTMLPurifier/TagTransform/Simple.php';
require_once $__dir . '/HTMLPurifier/Token/Comment.php';
require_once $__dir . '/HTMLPurifier/Token/Tag.php';
require_once $__dir . '/HTMLPurifier/Token/Empty.php';
require_once $__dir . '/HTMLPurifier/Token/End.php';
require_once $__dir . '/HTMLPurifier/Token/Start.php';
require_once $__dir . '/HTMLPurifier/Token/Text.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableResources.php';
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
require_once $__dir . '/HTMLPurifier/URIFilter/SafeIframe.php';
require_once $__dir . '/HTMLPurifier/URIScheme/data.php';
require_once $__dir . '/HTMLPurifier/URIScheme/file.php';
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';

View File

@ -1,71 +0,0 @@
<?php
/**
* Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node,
* and back again.
*
* @note This transformation is not an equivalence. We mutate the input
* token stream to make it so; see all [MUT] markers in code.
*/
class HTMLPurifier_Arborize
{
public static function arborize($tokens, $config, $context) {
$definition = $config->getHTMLDefinition();
$parent = new HTMLPurifier_Token_Start($definition->info_parent);
$stack = array($parent->toNode());
foreach ($tokens as $token) {
$token->skip = null; // [MUT]
$token->carryover = null; // [MUT]
if ($token instanceof HTMLPurifier_Token_End) {
$token->start = null; // [MUT]
$r = array_pop($stack);
assert($r->name === $token->name);
assert(empty($token->attr));
$r->endCol = $token->col;
$r->endLine = $token->line;
$r->endArmor = $token->armor;
continue;
}
$node = $token->toNode();
$stack[count($stack)-1]->children[] = $node;
if ($token instanceof HTMLPurifier_Token_Start) {
$stack[] = $node;
}
}
assert(count($stack) == 1);
return $stack[0];
}
public static function flatten($node, $config, $context) {
$level = 0;
$nodes = array($level => new HTMLPurifier_Queue(array($node)));
$closingTokens = array();
$tokens = array();
do {
while (!$nodes[$level]->isEmpty()) {
$node = $nodes[$level]->shift(); // FIFO
list($start, $end) = $node->toTokenPair();
if ($level > 0) {
$tokens[] = $start;
}
if ($end !== NULL) {
$closingTokens[$level][] = $end;
}
if ($node instanceof HTMLPurifier_Node_Element) {
$level++;
$nodes[$level] = new HTMLPurifier_Queue();
foreach ($node->children as $childNode) {
$nodes[$level]->push($childNode);
}
}
}
$level--;
if ($level && isset($closingTokens[$level])) {
while ($token = array_pop($closingTokens[$level])) {
$tokens[] = $token;
}
}
} while ($level > 0);
return $tokens;
}
}

View File

@ -1,143 +0,0 @@
<?php
/**
* Defines common attribute collections that modules reference
*/
class HTMLPurifier_AttrCollections
{
/**
* Associative array of attribute collections, indexed by name.
* @type array
*/
public $info = array();
/**
* Performs all expansions on internal data for use by other inclusions
* It also collects all attribute collection extensions from
* modules
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
* @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members
*/
public function __construct($attr_types, $modules)
{
// load extensions from the modules
foreach ($modules as $module) {
foreach ($module->attr_collections as $coll_i => $coll) {
if (!isset($this->info[$coll_i])) {
$this->info[$coll_i] = array();
}
foreach ($coll as $attr_i => $attr) {
if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
// merge in includes
$this->info[$coll_i][$attr_i] = array_merge(
$this->info[$coll_i][$attr_i],
$attr
);
continue;
}
$this->info[$coll_i][$attr_i] = $attr;
}
}
}
// perform internal expansions and inclusions
foreach ($this->info as $name => $attr) {
// merge attribute collections that include others
$this->performInclusions($this->info[$name]);
// replace string identifiers with actual attribute objects
$this->expandIdentifiers($this->info[$name], $attr_types);
}
}
/**
* Takes a reference to an attribute associative array and performs
* all inclusions specified by the zero index.
* @param array &$attr Reference to attribute array
*/
public function performInclusions(&$attr)
{
if (!isset($attr[0])) {
return;
}
$merge = $attr[0];
$seen = array(); // recursion guard
// loop through all the inclusions
for ($i = 0; isset($merge[$i]); $i++) {
if (isset($seen[$merge[$i]])) {
continue;
}
$seen[$merge[$i]] = true;
// foreach attribute of the inclusion, copy it over
if (!isset($this->info[$merge[$i]])) {
continue;
}
foreach ($this->info[$merge[$i]] as $key => $value) {
if (isset($attr[$key])) {
continue;
} // also catches more inclusions
$attr[$key] = $value;
}
if (isset($this->info[$merge[$i]][0])) {
// recursion
$merge = array_merge($merge, $this->info[$merge[$i]][0]);
}
}
unset($attr[0]);
}
/**
* Expands all string identifiers in an attribute array by replacing
* them with the appropriate values inside HTMLPurifier_AttrTypes
* @param array &$attr Reference to attribute array
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
*/
public function expandIdentifiers(&$attr, $attr_types)
{
// because foreach will process new elements we add, make sure we
// skip duplicates
$processed = array();
foreach ($attr as $def_i => $def) {
// skip inclusions
if ($def_i === 0) {
continue;
}
if (isset($processed[$def_i])) {
continue;
}
// determine whether or not attribute is required
if ($required = (strpos($def_i, '*') !== false)) {
// rename the definition
unset($attr[$def_i]);
$def_i = trim($def_i, '*');
$attr[$def_i] = $def;
}
$processed[$def_i] = true;
// if we've already got a literal object, move on
if (is_object($def)) {
// preserve previous required
$attr[$def_i]->required = ($required || $attr[$def_i]->required);
continue;
}
if ($def === false) {
unset($attr[$def_i]);
continue;
}
if ($t = $attr_types->get($def)) {
$attr[$def_i] = $t;
$attr[$def_i]->required = $required;
} else {
unset($attr[$def_i]);
}
}
}
}
// vim: et sw=4 sts=4

View File

@ -1,138 +0,0 @@
<?php
/**
* Base class for all validating attribute definitions.
*
* This family of classes forms the core for not only HTML attribute validation,
* but also any sort of string that needs to be validated or cleaned (which
* means CSS properties and composite definitions are defined here too).
* Besides defining (through code) what precisely makes the string valid,
* subclasses are also responsible for cleaning the code if possible.
*/
abstract class HTMLPurifier_AttrDef
{
/**
* Tells us whether or not an HTML attribute is minimized.
* Has no meaning in other contexts.
* @type bool
*/
public $minimized = false;
/**
* Tells us whether or not an HTML attribute is required.
* Has no meaning in other contexts
* @type bool
*/
public $required = false;
/**
* Validates and cleans passed string according to a definition.
*
* @param string $string String to be validated and cleaned.
* @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object.
* @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object.
*/
abstract public function validate($string, $config, $context);
/**
* Convenience method that parses a string as if it were CDATA.
*
* This method process a string in the manner specified at
* <http://www.w3.org/TR/html4/types.html#h-6.2> by removing
* leading and trailing whitespace, ignoring line feeds, and replacing
* carriage returns and tabs with spaces. While most useful for HTML
* attributes specified as CDATA, it can also be applied to most CSS
* values.
*
* @note This method is not entirely standards compliant, as trim() removes
* more types of whitespace than specified in the spec. In practice,
* this is rarely a problem, as those extra characters usually have
* already been removed by HTMLPurifier_Encoder.
*
* @warning This processing is inconsistent with XML's whitespace handling
* as specified by section 3.3.3 and referenced XHTML 1.0 section
* 4.7. However, note that we are NOT necessarily
* parsing XML, thus, this behavior may still be correct. We
* assume that newlines have been normalized.
*/
public function parseCDATA($string)
{
$string = trim($string);
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
return $string;
}
/**
* Factory method for creating this class from a string.
* @param string $string String construction info
* @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string
*/
public function make($string)
{
// default implementation, return a flyweight of this object.
// If $string has an effect on the returned object (i.e. you
// need to overload this method), it is best
// to clone or instantiate new copies. (Instantiation is safer.)
return $this;
}
/**
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
* properly. THIS IS A HACK!
* @param string $string a CSS colour definition
* @return string
*/
protected function mungeRgb($string)
{
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
}
/**
* Parses a possibly escaped CSS string and returns the "pure"
* version of it.
*/
protected function expandCSSEscape($string)
{
// flexibly parse it
$ret = '';
for ($i = 0, $c = strlen($string); $i < $c; $i++) {
if ($string[$i] === '\\') {
$i++;
if ($i >= $c) {
$ret .= '\\';
break;
}
if (ctype_xdigit($string[$i])) {
$code = $string[$i];
for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
if (!ctype_xdigit($string[$i])) {
break;
}
$code .= $string[$i];
}
// We have to be extremely careful when adding
// new characters, to make sure we're not breaking
// the encoding.
$char = HTMLPurifier_Encoder::unichr(hexdec($code));
if (HTMLPurifier_Encoder::cleanUTF8($char) === '') {
continue;
}
$ret .= $char;
if ($i < $c && trim($string[$i]) !== '') {
$i--;
}
continue;
}
if ($string[$i] === "\n") {
continue;
}
}
$ret .= $string[$i];
}
return $ret;
}
}
// vim: et sw=4 sts=4

View File

@ -1,106 +0,0 @@
<?php
/**
* Validates the HTML attribute style, otherwise known as CSS.
* @note We don't implement the whole CSS specification, so it might be
* difficult to reuse this component in the context of validating
* actual stylesheet declarations.
* @note If we were really serious about validating the CSS, we would
* tokenize the styles and then parse the tokens. Obviously, we
* are not doing that. Doing that could seriously harm performance,
* but would make these components a lot more viable for a CSS
* filtering solution.
*/
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
{
/**
* @param string $css
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($css, $config, $context)
{
$css = $this->parseCDATA($css);
$definition = $config->getCSSDefinition();
// we're going to break the spec and explode by semicolons.
// This is because semicolon rarely appears in escaped form
// Doing this is generally flaky but fast
// IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI
// for details
$declarations = explode(';', $css);
$propvalues = array();
/**
* Name of the current CSS property being validated.
*/
$property = false;
$context->register('CurrentCSSProperty', $property);
foreach ($declarations as $declaration) {
if (!$declaration) {
continue;
}
if (!strpos($declaration, ':')) {
continue;
}
list($property, $value) = explode(':', $declaration, 2);
$property = trim($property);
$value = trim($value);
$ok = false;
do {
if (isset($definition->info[$property])) {
$ok = true;
break;
}
if (ctype_lower($property)) {
break;
}
$property = strtolower($property);
if (isset($definition->info[$property])) {
$ok = true;
break;
}
} while (0);
if (!$ok) {
continue;
}
// inefficient call, since the validator will do this again
if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $definition->info[$property]->validate(
$value,
$config,
$context
);
} else {
$result = 'inherit';
}
if ($result === false) {
continue;
}
$propvalues[$property] = $result;
}
$context->destroy('CurrentCSSProperty');
// procedure does not write the new CSS simultaneously, so it's
// slightly inefficient, but it's the only way of getting rid of
// duplicates. Perhaps config to optimize it, but not now.
$new_declarations = '';
foreach ($propvalues as $prop => $value) {
$new_declarations .= "$prop:$value;";
}
return $new_declarations ? $new_declarations : false;
}
}
// vim: et sw=4 sts=4

View File

@ -1,34 +0,0 @@
<?php
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
{
public function __construct()
{
parent::__construct(false); // opacity is non-negative, but we will clamp it
}
/**
* @param string $number
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
*/
public function validate($number, $config, $context)
{
$result = parent::validate($number, $config, $context);
if ($result === false) {
return $result;
}
$float = (float)$result;
if ($float < 0.0) {
$result = '0';
}
if ($float > 1.0) {
$result = '1';
}
return $result;
}
}
// vim: et sw=4 sts=4

View File

@ -1,111 +0,0 @@
<?php
/**
* Validates shorthand CSS property background.
* @warning Does not support url tokens that have internal spaces.
*/
class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
{
/**
* Local copy of component validators.
* @type HTMLPurifier_AttrDef[]
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
*/
protected $info;
/**
* @param HTMLPurifier_Config $config
*/
public function __construct($config)
{
$def = $config->getCSSDefinition();
$this->info['background-color'] = $def->info['background-color'];
$this->info['background-image'] = $def->info['background-image'];
$this->info['background-repeat'] = $def->info['background-repeat'];
$this->info['background-attachment'] = $def->info['background-attachment'];
$this->info['background-position'] = $def->info['background-position'];
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') {
return false;
}
// munge rgb() decl if necessary
$string = $this->mungeRgb($string);
// assumes URI doesn't have spaces in it
$bits = explode(' ', $string); // bits to process
$caught = array();
$caught['color'] = false;
$caught['image'] = false;
$caught['repeat'] = false;
$caught['attachment'] = false;
$caught['position'] = false;
$i = 0; // number of catches
foreach ($bits as $bit) {
if ($bit === '') {
continue;
}
foreach ($caught as $key => $status) {
if ($key != 'position') {
if ($status !== false) {
continue;
}
$r = $this->info['background-' . $key]->validate($bit, $config, $context);
} else {
$r = $bit;
}
if ($r === false) {
continue;
}
if ($key == 'position') {
if ($caught[$key] === false) {
$caught[$key] = '';
}
$caught[$key] .= $r . ' ';
} else {
$caught[$key] = $r;
}
$i++;
break;
}
}
if (!$i) {
return false;
}
if ($caught['position'] !== false) {
$caught['position'] = $this->info['background-position']->
validate($caught['position'], $config, $context);
}
$ret = array();
foreach ($caught as $value) {
if ($value === false) {
continue;
}
$ret[] = $value;
}
if (empty($ret)) {
return false;
}
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -1,157 +0,0 @@
<?php
/* W3C says:
[ // adjective and number must be in correct order, even if
// you could switch them without introducing ambiguity.
// some browsers support that syntax
[
<percentage> | <length> | left | center | right
]
[
<percentage> | <length> | top | center | bottom
]?
] |
[ // this signifies that the vertical and horizontal adjectives
// can be arbitrarily ordered, however, there can only be two,
// one of each, or none at all
[
left | center | right
] ||
[
top | center | bottom
]
]
top, left = 0%
center, (none) = 50%
bottom, right = 100%
*/
/* QuirksMode says:
keyword + length/percentage must be ordered correctly, as per W3C
Internet Explorer and Opera, however, support arbitrary ordering. We
should fix it up.
Minor issue though, not strictly necessary.
*/
// control freaks may appreciate the ability to convert these to
// percentages or something, but it's not necessary
/**
* Validates the value of background-position.
*/
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_AttrDef_CSS_Length
*/
protected $length;
/**
* @type HTMLPurifier_AttrDef_CSS_Percentage
*/
protected $percentage;
public function __construct()
{
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
$bits = explode(' ', $string);
$keywords = array();
$keywords['h'] = false; // left, right
$keywords['v'] = false; // top, bottom
$keywords['ch'] = false; // center (first word)
$keywords['cv'] = false; // center (second word)
$measures = array();
$i = 0;
$lookup = array(
'top' => 'v',
'bottom' => 'v',
'left' => 'h',
'right' => 'h',
'center' => 'c'
);
foreach ($bits as $bit) {
if ($bit === '') {
continue;
}
// test for keyword
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
if (isset($lookup[$lbit])) {
$status = $lookup[$lbit];
if ($status == 'c') {
if ($i == 0) {
$status = 'ch';
} else {
$status = 'cv';
}
}
$keywords[$status] = $lbit;
$i++;
}
// test for length
$r = $this->length->validate($bit, $config, $context);
if ($r !== false) {
$measures[] = $r;
$i++;
}
// test for percentage
$r = $this->percentage->validate($bit, $config, $context);
if ($r !== false) {
$measures[] = $r;
$i++;
}
}
if (!$i) {
return false;
} // no valid values were caught
$ret = array();
// first keyword
if ($keywords['h']) {
$ret[] = $keywords['h'];
} elseif ($keywords['ch']) {
$ret[] = $keywords['ch'];
$keywords['cv'] = false; // prevent re-use: center = center center
} elseif (count($measures)) {
$ret[] = array_shift($measures);
}
if ($keywords['v']) {
$ret[] = $keywords['v'];
} elseif ($keywords['cv']) {
$ret[] = $keywords['cv'];
} elseif (count($measures)) {
$ret[] = array_shift($measures);
}
if (empty($ret)) {
return false;
}
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -1,56 +0,0 @@
<?php
/**
* Validates the border property as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
{
/**
* Local copy of properties this property is shorthand for.
* @type HTMLPurifier_AttrDef[]
*/
protected $info = array();
/**
* @param HTMLPurifier_Config $config
*/
public function __construct($config)
{
$def = $config->getCSSDefinition();
$this->info['border-width'] = $def->info['border-width'];
$this->info['border-style'] = $def->info['border-style'];
$this->info['border-top-color'] = $def->info['border-top-color'];
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
$string = $this->mungeRgb($string);
$bits = explode(' ', $string);
$done = array(); // segments we've finished
$ret = ''; // return value
foreach ($bits as $bit) {
foreach ($this->info as $propname => $validator) {
if (isset($done[$propname])) {
continue;
}
$r = $validator->validate($bit, $config, $context);
if ($r !== false) {
$ret .= $r . ' ';
$done[$propname] = true;
break;
}
}
}
return rtrim($ret);
}
}
// vim: et sw=4 sts=4

View File

@ -1,105 +0,0 @@
<?php
/**
* Validates Color as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
{
/**
* @param string $color
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($color, $config, $context)
{
static $colors = null;
if ($colors === null) {
$colors = $config->get('Core.ColorKeywords');
}
$color = trim($color);
if ($color === '') {
return false;
}
$lower = strtolower($color);
if (isset($colors[$lower])) {
return $colors[$lower];
}
if (strpos($color, 'rgb(') !== false) {
// rgb literal handling
$length = strlen($color);
if (strpos($color, ')') !== $length - 1) {
return false;
}
$triad = substr($color, 4, $length - 4 - 1);
$parts = explode(',', $triad);
if (count($parts) !== 3) {
return false;
}
$type = false; // to ensure that they're all the same type
$new_parts = array();
foreach ($parts as $part) {
$part = trim($part);
if ($part === '') {
return false;
}
$length = strlen($part);
if ($part[$length - 1] === '%') {
// handle percents
if (!$type) {
$type = 'percentage';
} elseif ($type !== 'percentage') {
return false;
}
$num = (float)substr($part, 0, $length - 1);
if ($num < 0) {
$num = 0;
}
if ($num > 100) {
$num = 100;
}
$new_parts[] = "$num%";
} else {
// handle integers
if (!$type) {
$type = 'integer';
} elseif ($type !== 'integer') {
return false;
}
$num = (int)$part;
if ($num < 0) {
$num = 0;
}
if ($num > 255) {
$num = 255;
}
$new_parts[] = (string)$num;
}
}
$new_triad = implode(',', $new_parts);
$color = "rgb($new_triad)";
} else {
// hexadecimal handling
if ($color[0] === '#') {
$hex = substr($color, 1);
} else {
$hex = $color;
$color = '#' . $color;
}
$length = strlen($hex);
if ($length !== 3 && $length !== 6) {
return false;
}
if (!ctype_xdigit($hex)) {
return false;
}
}
return $color;
}
}
// vim: et sw=4 sts=4

View File

@ -1,48 +0,0 @@
<?php
/**
* Allows multiple validators to attempt to validate attribute.
*
* Composite is just what it sounds like: a composite of many validators.
* This means that multiple HTMLPurifier_AttrDef objects will have a whack
* at the string. If one of them passes, that's what is returned. This is
* especially useful for CSS values, which often are a choice between
* an enumerated set of predefined values or a flexible data type.
*/
class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
{
/**
* List of objects that may process strings.
* @type HTMLPurifier_AttrDef[]
* @todo Make protected
*/
public $defs;
/**
* @param HTMLPurifier_AttrDef[] $defs List of HTMLPurifier_AttrDef objects
*/
public function __construct($defs)
{
$this->defs = $defs;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
foreach ($this->defs as $i => $def) {
$result = $this->defs[$i]->validate($string, $config, $context);
if ($result !== false) {
return $result;
}
}
return false;
}
}
// vim: et sw=4 sts=4

View File

@ -1,44 +0,0 @@
<?php
/**
* Decorator which enables CSS properties to be disabled for specific elements.
*/
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_AttrDef
*/
public $def;
/**
* @type string
*/
public $element;
/**
* @param HTMLPurifier_AttrDef $def Definition to wrap
* @param string $element Element to deny
*/
public function __construct($def, $element)
{
$this->def = $def;
$this->element = $element;
}
/**
* Checks if CurrentToken is set and equal to $this->element
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$token = $context->get('CurrentToken', true);
if ($token && $token->name == $this->element) {
return false;
}
return $this->def->validate($string, $config, $context);
}
}
// vim: et sw=4 sts=4

View File

@ -1,77 +0,0 @@
<?php
/**
* Microsoft's proprietary filter: CSS property
* @note Currently supports the alpha filter. In the future, this will
* probably need an extensible framework
*/
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_AttrDef_Integer
*/
protected $intValidator;
public function __construct()
{
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
}
/**
* @param string $value
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($value, $config, $context)
{
$value = $this->parseCDATA($value);
if ($value === 'none') {
return $value;
}
// if we looped this we could support multiple filters
$function_length = strcspn($value, '(');
$function = trim(substr($value, 0, $function_length));
if ($function !== 'alpha' &&
$function !== 'Alpha' &&
$function !== 'progid:DXImageTransform.Microsoft.Alpha'
) {
return false;
}
$cursor = $function_length + 1;
$parameters_length = strcspn($value, ')', $cursor);
$parameters = substr($value, $cursor, $parameters_length);
$params = explode(',', $parameters);
$ret_params = array();
$lookup = array();
foreach ($params as $param) {
list($key, $value) = explode('=', $param);
$key = trim($key);
$value = trim($value);
if (isset($lookup[$key])) {
continue;
}
if ($key !== 'opacity') {
continue;
}
$value = $this->intValidator->validate($value, $config, $context);
if ($value === false) {
continue;
}
$int = (int)$value;
if ($int > 100) {
$value = '100';
}
if ($int < 0) {
$value = '0';
}
$ret_params[] = "$key=$value";
$lookup[$key] = true;
}
$ret_parameters = implode(',', $ret_params);
$ret_function = "$function($ret_parameters)";
return $ret_function;
}
}
// vim: et sw=4 sts=4

View File

@ -1,176 +0,0 @@
<?php
/**
* Validates shorthand CSS property font.
*/
class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
{
/**
* Local copy of validators
* @type HTMLPurifier_AttrDef[]
* @note If we moved specific CSS property definitions to their own
* classes instead of having them be assembled at run time by
* CSSDefinition, this wouldn't be necessary. We'd instantiate
* our own copies.
*/
protected $info = array();
/**
* @param HTMLPurifier_Config $config
*/
public function __construct($config)
{
$def = $config->getCSSDefinition();
$this->info['font-style'] = $def->info['font-style'];
$this->info['font-variant'] = $def->info['font-variant'];
$this->info['font-weight'] = $def->info['font-weight'];
$this->info['font-size'] = $def->info['font-size'];
$this->info['line-height'] = $def->info['line-height'];
$this->info['font-family'] = $def->info['font-family'];
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
static $system_fonts = array(
'caption' => true,
'icon' => true,
'menu' => true,
'message-box' => true,
'small-caption' => true,
'status-bar' => true
);
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') {
return false;
}
// check if it's one of the keywords
$lowercase_string = strtolower($string);
if (isset($system_fonts[$lowercase_string])) {
return $lowercase_string;
}
$bits = explode(' ', $string); // bits to process
$stage = 0; // this indicates what we're looking for
$caught = array(); // which stage 0 properties have we caught?
$stage_1 = array('font-style', 'font-variant', 'font-weight');
$final = ''; // output
for ($i = 0, $size = count($bits); $i < $size; $i++) {
if ($bits[$i] === '') {
continue;
}
switch ($stage) {
case 0: // attempting to catch font-style, font-variant or font-weight
foreach ($stage_1 as $validator_name) {
if (isset($caught[$validator_name])) {
continue;
}
$r = $this->info[$validator_name]->validate(
$bits[$i],
$config,
$context
);
if ($r !== false) {
$final .= $r . ' ';
$caught[$validator_name] = true;
break;
}
}
// all three caught, continue on
if (count($caught) >= 3) {
$stage = 1;
}
if ($r !== false) {
break;
}
case 1: // attempting to catch font-size and perhaps line-height
$found_slash = false;
if (strpos($bits[$i], '/') !== false) {
list($font_size, $line_height) =
explode('/', $bits[$i]);
if ($line_height === '') {
// ooh, there's a space after the slash!
$line_height = false;
$found_slash = true;
}
} else {
$font_size = $bits[$i];
$line_height = false;
}
$r = $this->info['font-size']->validate(
$font_size,
$config,
$context
);
if ($r !== false) {
$final .= $r;
// attempt to catch line-height
if ($line_height === false) {
// we need to scroll forward
for ($j = $i + 1; $j < $size; $j++) {
if ($bits[$j] === '') {
continue;
}
if ($bits[$j] === '/') {
if ($found_slash) {
return false;
} else {
$found_slash = true;
continue;
}
}
$line_height = $bits[$j];
break;
}
} else {
// slash already found
$found_slash = true;
$j = $i;
}
if ($found_slash) {
$i = $j;
$r = $this->info['line-height']->validate(
$line_height,
$config,
$context
);
if ($r !== false) {
$final .= '/' . $r;
}
}
$final .= ' ';
$stage = 2;
break;
}
return false;
case 2: // attempting to catch font-family
$font_family =
implode(' ', array_slice($bits, $i, $size - $i));
$r = $this->info['font-family']->validate(
$font_family,
$config,
$context
);
if ($r !== false) {
$final .= $r . ' ';
// processing completed successfully
return rtrim($final);
}
return false;
}
}
return false;
}
}
// vim: et sw=4 sts=4

View File

@ -1,219 +0,0 @@
<?php
/**
* Validates a font family list according to CSS spec
*/
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
{
protected $mask = null;
public function __construct()
{
$this->mask = '_- ';
for ($c = 'a'; $c <= 'z'; $c++) {
$this->mask .= $c;
}
for ($c = 'A'; $c <= 'Z'; $c++) {
$this->mask .= $c;
}
for ($c = '0'; $c <= '9'; $c++) {
$this->mask .= $c;
} // cast-y, but should be fine
// special bytes used by UTF-8
for ($i = 0x80; $i <= 0xFF; $i++) {
// We don't bother excluding invalid bytes in this range,
// because the our restriction of well-formed UTF-8 will
// prevent these from ever occurring.
$this->mask .= chr($i);
}
/*
PHP's internal strcspn implementation is
O(length of string * length of mask), making it inefficient
for large masks. However, it's still faster than
preg_match 8)
for (p = s1;;) {
spanp = s2;
do {
if (*spanp == c || p == s1_end) {
return p - s1;
}
} while (spanp++ < (s2_end - 1));
c = *++p;
}
*/
// possible optimization: invert the mask.
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
static $generic_names = array(
'serif' => true,
'sans-serif' => true,
'monospace' => true,
'fantasy' => true,
'cursive' => true
);
$allowed_fonts = $config->get('CSS.AllowedFonts');
// assume that no font names contain commas in them
$fonts = explode(',', $string);
$final = '';
foreach ($fonts as $font) {
$font = trim($font);
if ($font === '') {
continue;
}
// match a generic name
if (isset($generic_names[$font])) {
if ($allowed_fonts === null || isset($allowed_fonts[$font])) {
$final .= $font . ', ';
}
continue;
}
// match a quoted name
if ($font[0] === '"' || $font[0] === "'") {
$length = strlen($font);
if ($length <= 2) {
continue;
}
$quote = $font[0];
if ($font[$length - 1] !== $quote) {
continue;
}
$font = substr($font, 1, $length - 2);
}
$font = $this->expandCSSEscape($font);
// $font is a pure representation of the font name
if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) {
continue;
}
if (ctype_alnum($font) && $font !== '') {
// very simple font, allow it in unharmed
$final .= $font . ', ';
continue;
}
// bugger out on whitespace. form feed (0C) really
// shouldn't show up regardless
$font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font);
// Here, there are various classes of characters which need
// to be treated differently:
// - Alphanumeric characters are essentially safe. We
// handled these above.
// - Spaces require quoting, though most parsers will do
// the right thing if there aren't any characters that
// can be misinterpreted
// - Dashes rarely occur, but they fairly unproblematic
// for parsing/rendering purposes.
// The above characters cover the majority of Western font
// names.
// - Arbitrary Unicode characters not in ASCII. Because
// most parsers give little thought to Unicode, treatment
// of these codepoints is basically uniform, even for
// punctuation-like codepoints. These characters can
// show up in non-Western pages and are supported by most
// major browsers, for example: " 明朝" is a
// legitimate font-name
// <http://ja.wikipedia.org/wiki/MS_明朝>. See
// the CSS3 spec for more examples:
// <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png>
// You can see live samples of these on the Internet:
// <http://www.google.co.jp/search?q=font-family++明朝|ゴシック>
// However, most of these fonts have ASCII equivalents:
// for example, 'MS Mincho', and it's considered
// professional to use ASCII font names instead of
// Unicode font names. Thanks Takeshi Terada for
// providing this information.
// The following characters, to my knowledge, have not been
// used to name font names.
// - Single quote. While theoretically you might find a
// font name that has a single quote in its name (serving
// as an apostrophe, e.g. Dave's Scribble), I haven't
// been able to find any actual examples of this.
// Internet Explorer's cssText translation (which I
// believe is invoked by innerHTML) normalizes any
// quoting to single quotes, and fails to escape single
// quotes. (Note that this is not IE's behavior for all
// CSS properties, just some sort of special casing for
// font-family). So a single quote *cannot* be used
// safely in the font-family context if there will be an
// innerHTML/cssText translation. Note that Firefox 3.x
// does this too.
// - Double quote. In IE, these get normalized to
// single-quotes, no matter what the encoding. (Fun
// fact, in IE8, the 'content' CSS property gained
// support, where they special cased to preserve encoded
// double quotes, but still translate unadorned double
// quotes into single quotes.) So, because their
// fixpoint behavior is identical to single quotes, they
// cannot be allowed either. Firefox 3.x displays
// single-quote style behavior.
// - Backslashes are reduced by one (so \\ -> \) every
// iteration, so they cannot be used safely. This shows
// up in IE7, IE8 and FF3
// - Semicolons, commas and backticks are handled properly.
// - The rest of the ASCII punctuation is handled properly.
// We haven't checked what browsers do to unadorned
// versions, but this is not important as long as the
// browser doesn't /remove/ surrounding quotes (as IE does
// for HTML).
//
// With these results in hand, we conclude that there are
// various levels of safety:
// - Paranoid: alphanumeric, spaces and dashes(?)
// - International: Paranoid + non-ASCII Unicode
// - Edgy: Everything except quotes, backslashes
// - NoJS: Standards compliance, e.g. sod IE. Note that
// with some judicious character escaping (since certain
// types of escaping doesn't work) this is theoretically
// OK as long as innerHTML/cssText is not called.
// We believe that international is a reasonable default
// (that we will implement now), and once we do more
// extensive research, we may feel comfortable with dropping
// it down to edgy.
// Edgy: alphanumeric, spaces, dashes, underscores and Unicode. Use of
// str(c)spn assumes that the string was already well formed
// Unicode (which of course it is).
if (strspn($font, $this->mask) !== strlen($font)) {
continue;
}
// Historical:
// In the absence of innerHTML/cssText, these ugly
// transforms don't pose a security risk (as \\ and \"
// might--these escapes are not supported by most browsers).
// We could try to be clever and use single-quote wrapping
// when there is a double quote present, but I have choosen
// not to implement that. (NOTE: you can reduce the amount
// of escapes by one depending on what quoting style you use)
// $font = str_replace('\\', '\\5C ', $font);
// $font = str_replace('"', '\\22 ', $font);
// $font = str_replace("'", '\\27 ', $font);
// font possibly with spaces, requires quoting
$final .= "'$font', ";
}
$final = rtrim($final, ', ');
if ($final === '') {
return false;
}
return $final;
}
}
// vim: et sw=4 sts=4

View File

@ -1,32 +0,0 @@
<?php
/**
* Validates based on {ident} CSS grammar production
*/
class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
// early abort: '' and '0' (strings that convert to false) are invalid
if (!$string) {
return false;
}
$pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/';
if (!preg_match($pattern, $string)) {
return false;
}
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -1,56 +0,0 @@
<?php
/**
* Decorator which enables !important to be used in CSS values.
*/
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_AttrDef
*/
public $def;
/**
* @type bool
*/
public $allow;
/**
* @param HTMLPurifier_AttrDef $def Definition to wrap
* @param bool $allow Whether or not to allow !important
*/
public function __construct($def, $allow = false)
{
$this->def = $def;
$this->allow = $allow;
}
/**
* Intercepts and removes !important if necessary
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
// test for ! and important tokens
$string = trim($string);
$is_important = false;
// :TODO: optimization: test directly for !important and ! important
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
$temp = rtrim(substr($string, 0, -9));
// use a temp, because we might want to restore important
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
$string = rtrim(substr($temp, 0, -1));
$is_important = true;
}
}
$string = $this->def->validate($string, $config, $context);
if ($this->allow && $is_important) {
$string .= ' !important';
}
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -1,77 +0,0 @@
<?php
/**
* Represents a Length as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_Length|string
*/
protected $min;
/**
* @type HTMLPurifier_Length|string
*/
protected $max;
/**
* @param HTMLPurifier_Length|string $min Minimum length, or null for no bound. String is also acceptable.
* @param HTMLPurifier_Length|string $max Maximum length, or null for no bound. String is also acceptable.
*/
public function __construct($min = null, $max = null)
{
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
// Optimizations
if ($string === '') {
return false;
}
if ($string === '0') {
return '0';
}
if (strlen($string) === 1) {
return false;
}
$length = HTMLPurifier_Length::make($string);
if (!$length->isValid()) {
return false;
}
if ($this->min) {
$c = $length->compareTo($this->min);
if ($c === false) {
return false;
}
if ($c < 0) {
return false;
}
}
if ($this->max) {
$c = $length->compareTo($this->max);
if ($c === false) {
return false;
}
if ($c > 0) {
return false;
}
}
return $length->toString();
}
}
// vim: et sw=4 sts=4

View File

@ -1,112 +0,0 @@
<?php
/**
* Validates shorthand CSS property list-style.
* @warning Does not support url tokens that have internal spaces.
*/
class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
{
/**
* Local copy of validators.
* @type HTMLPurifier_AttrDef[]
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
*/
protected $info;
/**
* @param HTMLPurifier_Config $config
*/
public function __construct($config)
{
$def = $config->getCSSDefinition();
$this->info['list-style-type'] = $def->info['list-style-type'];
$this->info['list-style-position'] = $def->info['list-style-position'];
$this->info['list-style-image'] = $def->info['list-style-image'];
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') {
return false;
}
// assumes URI doesn't have spaces in it
$bits = explode(' ', strtolower($string)); // bits to process
$caught = array();
$caught['type'] = false;
$caught['position'] = false;
$caught['image'] = false;
$i = 0; // number of catches
$none = false;
foreach ($bits as $bit) {
if ($i >= 3) {
return;
} // optimization bit
if ($bit === '') {
continue;
}
foreach ($caught as $key => $status) {
if ($status !== false) {
continue;
}
$r = $this->info['list-style-' . $key]->validate($bit, $config, $context);
if ($r === false) {
continue;
}
if ($r === 'none') {
if ($none) {
continue;
} else {
$none = true;
}
if ($key == 'image') {
continue;
}
}
$caught[$key] = $r;
$i++;
break;
}
}
if (!$i) {
return false;
}
$ret = array();
// construct type
if ($caught['type']) {
$ret[] = $caught['type'];
}
// construct image
if ($caught['image']) {
$ret[] = $caught['image'];
}
// construct position
if ($caught['position']) {
$ret[] = $caught['position'];
}
if (empty($ret)) {
return false;
}
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -1,71 +0,0 @@
<?php
/**
* Framework class for strings that involve multiple values.
*
* Certain CSS properties such as border-width and margin allow multiple
* lengths to be specified. This class can take a vanilla border-width
* definition and multiply it, usually into a max of four.
*
* @note Even though the CSS specification isn't clear about it, inherit
* can only be used alone: it will never manifest as part of a multi
* shorthand declaration. Thus, this class does not allow inherit.
*/
class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
{
/**
* Instance of component definition to defer validation to.
* @type HTMLPurifier_AttrDef
* @todo Make protected
*/
public $single;
/**
* Max number of values allowed.
* @todo Make protected
*/
public $max;
/**
* @param HTMLPurifier_AttrDef $single HTMLPurifier_AttrDef to multiply
* @param int $max Max number of values allowed (usually four)
*/
public function __construct($single, $max = 4)
{
$this->single = $single;
$this->max = $max;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
if ($string === '') {
return false;
}
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
$length = count($parts);
$final = '';
for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) {
if (ctype_space($parts[$i])) {
continue;
}
$result = $this->single->validate($parts[$i], $config, $context);
if ($result !== false) {
$final .= $result . ' ';
$num++;
}
}
if ($final === '') {
return false;
}
return rtrim($final);
}
}
// vim: et sw=4 sts=4

View File

@ -1,84 +0,0 @@
<?php
/**
* Validates a number as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
{
/**
* Indicates whether or not only positive values are allowed.
* @type bool
*/
protected $non_negative = false;
/**
* @param bool $non_negative indicates whether negatives are forbidden
*/
public function __construct($non_negative = false)
{
$this->non_negative = $non_negative;
}
/**
* @param string $number
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string|bool
* @warning Some contexts do not pass $config, $context. These
* variables should not be used without checking HTMLPurifier_Length
*/
public function validate($number, $config, $context)
{
$number = $this->parseCDATA($number);
if ($number === '') {
return false;
}
if ($number === '0') {
return '0';
}
$sign = '';
switch ($number[0]) {
case '-':
if ($this->non_negative) {
return false;
}
$sign = '-';
case '+':
$number = substr($number, 1);
}
if (ctype_digit($number)) {
$number = ltrim($number, '0');
return $number ? $sign . $number : '0';
}
// Period is the only non-numeric character allowed
if (strpos($number, '.') === false) {
return false;
}
list($left, $right) = explode('.', $number, 2);
if ($left === '' && $right === '') {
return false;
}
if ($left !== '' && !ctype_digit($left)) {
return false;
}
$left = ltrim($left, '0');
$right = rtrim($right, '0');
if ($right === '') {
return $left ? $sign . $left : '0';
} elseif (!ctype_digit($right)) {
return false;
}
return $sign . $left . '.' . $right;
}
}
// vim: et sw=4 sts=4

View File

@ -1,54 +0,0 @@
<?php
/**
* Validates a Percentage as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef
{
/**
* Instance to defer number validation to.
* @type HTMLPurifier_AttrDef_CSS_Number
*/
protected $number_def;
/**
* @param bool $non_negative Whether to forbid negative values
*/
public function __construct($non_negative = false)
{
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
if ($string === '') {
return false;
}
$length = strlen($string);
if ($length === 1) {
return false;
}
if ($string[$length - 1] !== '%') {
return false;
}
$number = substr($string, 0, $length - 1);
$number = $this->number_def->validate($number, $config, $context);
if ($number === false) {
return false;
}
return "$number%";
}
}
// vim: et sw=4 sts=4

View File

@ -1,46 +0,0 @@
<?php
/**
* Validates the value for the CSS property text-decoration
* @note This class could be generalized into a version that acts sort of
* like Enum except you can compound the allowed values.
*/
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
static $allowed_values = array(
'line-through' => true,
'overline' => true,
'underline' => true,
);
$string = strtolower($this->parseCDATA($string));
if ($string === 'none') {
return $string;
}
$parts = explode(' ', $string);
$final = '';
foreach ($parts as $part) {
if (isset($allowed_values[$part])) {
$final .= $part . ' ';
}
}
$final = rtrim($final);
if ($final === '') {
return false;
}
return $final;
}
}
// vim: et sw=4 sts=4

View File

@ -1,74 +0,0 @@
<?php
/**
* Validates a URI in CSS syntax, which uses url('http://example.com')
* @note While theoretically speaking a URI in a CSS document could
* be non-embedded, as of CSS2 there is no such usage so we're
* generalizing it. This may need to be changed in the future.
* @warning Since HTMLPurifier_AttrDef_CSS blindly uses semicolons as
* the separator, you cannot put a literal semicolon in
* in the URI. Try percent encoding it, in that case.
*/
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
{
public function __construct()
{
parent::__construct(true); // always embedded
}
/**
* @param string $uri_string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($uri_string, $config, $context)
{
// parse the URI out of the string and then pass it onto
// the parent object
$uri_string = $this->parseCDATA($uri_string);
if (strpos($uri_string, 'url(') !== 0) {
return false;
}
$uri_string = substr($uri_string, 4);
$new_length = strlen($uri_string) - 1;
if ($uri_string[$new_length] != ')') {
return false;
}
$uri = trim(substr($uri_string, 0, $new_length));
if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) {
$quote = $uri[0];
$new_length = strlen($uri) - 1;
if ($uri[$new_length] !== $quote) {
return false;
}
$uri = substr($uri, 1, $new_length - 1);
}
$uri = $this->expandCSSEscape($uri);
$result = parent::validate($uri, $config, $context);
if ($result === false) {
return false;
}
// extra sanity check; should have been done by URI
$result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result);
// suspicious characters are ()'; we're going to percent encode
// them for safety.
$result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result);
// there's an extra bug where ampersands lose their escaping on
// an innerHTML cycle, so a very unlucky query parameter could
// then change the meaning of the URL. Unfortunately, there's
// not much we can do about that...
return "url(\"$result\")";
}
}
// vim: et sw=4 sts=4

View File

@ -1,44 +0,0 @@
<?php
/**
* Dummy AttrDef that mimics another AttrDef, BUT it generates clones
* with make.
*/
class HTMLPurifier_AttrDef_Clone extends HTMLPurifier_AttrDef
{
/**
* What we're cloning.
* @type HTMLPurifier_AttrDef
*/
protected $clone;
/**
* @param HTMLPurifier_AttrDef $clone
*/
public function __construct($clone)
{
$this->clone = $clone;
}
/**
* @param string $v
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($v, $config, $context)
{
return $this->clone->validate($v, $config, $context);
}
/**
* @param string $string
* @return HTMLPurifier_AttrDef
*/
public function make($string)
{
return clone $this->clone;
}
}
// vim: et sw=4 sts=4

View File

@ -1,73 +0,0 @@
<?php
// Enum = Enumerated
/**
* Validates a keyword against a list of valid values.
* @warning The case-insensitive compare of this function uses PHP's
* built-in strtolower and ctype_lower functions, which may
* cause problems with international comparisons
*/
class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
{
/**
* Lookup table of valid values.
* @type array
* @todo Make protected
*/
public $valid_values = array();
/**
* Bool indicating whether or not enumeration is case sensitive.
* @note In general this is always case insensitive.
*/
protected $case_sensitive = false; // values according to W3C spec
/**
* @param array $valid_values List of valid values
* @param bool $case_sensitive Whether or not case sensitive
*/
public function __construct($valid_values = array(), $case_sensitive = false)
{
$this->valid_values = array_flip($valid_values);
$this->case_sensitive = $case_sensitive;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
if (!$this->case_sensitive) {
// we may want to do full case-insensitive libraries
$string = ctype_lower($string) ? $string : strtolower($string);
}
$result = isset($this->valid_values[$string]);
return $result ? $string : false;
}
/**
* @param string $string In form of comma-delimited list of case-insensitive
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
* case sensitive
* @return HTMLPurifier_AttrDef_Enum
*/
public function make($string)
{
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
$string = substr($string, 2);
$sensitive = true;
} else {
$sensitive = false;
}
$values = explode(',', $string);
return new HTMLPurifier_AttrDef_Enum($values, $sensitive);
}
}
// vim: et sw=4 sts=4

View File

@ -1,51 +0,0 @@
<?php
/**
* Validates a boolean attribute
*/
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
{
/**
* @type bool
*/
protected $name;
/**
* @type bool
*/
public $minimized = true;
/**
* @param bool $name
*/
public function __construct($name = false)
{
$this->name = $name;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
if (empty($string)) {
return false;
}
return $this->name;
}
/**
* @param string $string Name of attribute
* @return HTMLPurifier_AttrDef_HTML_Bool
*/
public function make($string)
{
return new HTMLPurifier_AttrDef_HTML_Bool($string);
}
}
// vim: et sw=4 sts=4

View File

@ -1,48 +0,0 @@
<?php
/**
* Implements special behavior for class attribute (normally NMTOKENS)
*/
class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
protected function split($string, $config, $context)
{
// really, this twiddle should be lazy loaded
$name = $config->getDefinition('HTML')->doctype->name;
if ($name == "XHTML 1.1" || $name == "XHTML 2.0") {
return parent::split($string, $config, $context);
} else {
return preg_split('/\s+/', $string);
}
}
/**
* @param array $tokens
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return array
*/
protected function filter($tokens, $config, $context)
{
$allowed = $config->get('Attr.AllowedClasses');
$forbidden = $config->get('Attr.ForbiddenClasses');
$ret = array();
foreach ($tokens as $token) {
if (($allowed === null || isset($allowed[$token])) &&
!isset($forbidden[$token]) &&
// We need this O(n) check because of PHP's array
// implementation that casts -0 to 0.
!in_array($token, $ret, true)
) {
$ret[] = $token;
}
}
return $ret;
}
}

View File

@ -1,51 +0,0 @@
<?php
/**
* Validates a color according to the HTML spec.
*/
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
static $colors = null;
if ($colors === null) {
$colors = $config->get('Core.ColorKeywords');
}
$string = trim($string);
if (empty($string)) {
return false;
}
$lower = strtolower($string);
if (isset($colors[$lower])) {
return $colors[$lower];
}
if ($string[0] === '#') {
$hex = substr($string, 1);
} else {
$hex = $string;
}
$length = strlen($hex);
if ($length !== 3 && $length !== 6) {
return false;
}
if (!ctype_xdigit($hex)) {
return false;
}
if ($length === 3) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
return "#$hex";
}
}
// vim: et sw=4 sts=4

View File

@ -1,38 +0,0 @@
<?php
/**
* Special-case enum attribute definition that lazy loads allowed frame targets
*/
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
{
/**
* @type array
*/
public $valid_values = false; // uninitialized value
/**
* @type bool
*/
protected $case_sensitive = false;
public function __construct()
{
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
if ($this->valid_values === false) {
$this->valid_values = $config->get('Attr.AllowedFrameTargets');
}
return parent::validate($string, $config, $context);
}
}
// vim: et sw=4 sts=4

View File

@ -1,105 +0,0 @@
<?php
/**
* Validates the HTML attribute ID.
* @warning Even though this is the id processor, it
* will ignore the directive Attr:IDBlacklist, since it will only
* go according to the ID accumulator. Since the accumulator is
* automatically generated, it will have already absorbed the
* blacklist. If you're hacking around, make sure you use load()!
*/
class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
{
// selector is NOT a valid thing to use for IDREFs, because IDREFs
// *must* target IDs that exist, whereas selector #ids do not.
/**
* Determines whether or not we're validating an ID in a CSS
* selector context.
* @type bool
*/
protected $selector;
/**
* @param bool $selector
*/
public function __construct($selector = false)
{
$this->selector = $selector;
}
/**
* @param string $id
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($id, $config, $context)
{
if (!$this->selector && !$config->get('Attr.EnableID')) {
return false;
}
$id = trim($id); // trim it first
if ($id === '') {
return false;
}
$prefix = $config->get('Attr.IDPrefix');
if ($prefix !== '') {
$prefix .= $config->get('Attr.IDPrefixLocal');
// prevent re-appending the prefix
if (strpos($id, $prefix) !== 0) {
$id = $prefix . $id;
}
} elseif ($config->get('Attr.IDPrefixLocal') !== '') {
trigger_error(
'%Attr.IDPrefixLocal cannot be used unless ' .
'%Attr.IDPrefix is set',
E_USER_WARNING
);
}
if (!$this->selector) {
$id_accumulator =& $context->get('IDAccumulator');
if (isset($id_accumulator->ids[$id])) {
return false;
}
}
// we purposely avoid using regex, hopefully this is faster
if (ctype_alpha($id)) {
$result = true;
} else {
if (!ctype_alpha(@$id[0])) {
return false;
}
// primitive style of regexps, I suppose
$trim = trim(
$id,
'A..Za..z0..9:-._'
);
$result = ($trim === '');
}
$regexp = $config->get('Attr.IDBlacklistRegexp');
if ($regexp && preg_match($regexp, $id)) {
return false;
}
if (!$this->selector && $result) {
$id_accumulator->add($id);
}
// if no change was made to the ID, return the result
// else, return the new id if stripping whitespace made it
// valid, or return false.
return $result ? $id : false;
}
}
// vim: et sw=4 sts=4

View File

@ -1,56 +0,0 @@
<?php
/**
* Validates the HTML type length (not to be confused with CSS's length).
*
* This accepts integer pixels or percentages as lengths for certain
* HTML attributes.
*/
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
if ($string === '') {
return false;
}
$parent_result = parent::validate($string, $config, $context);
if ($parent_result !== false) {
return $parent_result;
}
$length = strlen($string);
$last_char = $string[$length - 1];
if ($last_char !== '%') {
return false;
}
$points = substr($string, 0, $length - 1);
if (!is_numeric($points)) {
return false;
}
$points = (int)$points;
if ($points < 0) {
return '0%';
}
if ($points > 100) {
return '100%';
}
return ((string)$points) . '%';
}
}
// vim: et sw=4 sts=4

View File

@ -1,72 +0,0 @@
<?php
/**
* Validates a rel/rev link attribute against a directive of allowed values
* @note We cannot use Enum because link types allow multiple
* values.
* @note Assumes link types are ASCII text
*/
class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
{
/**
* Name config attribute to pull.
* @type string
*/
protected $name;
/**
* @param string $name
*/
public function __construct($name)
{
$configLookup = array(
'rel' => 'AllowedRel',
'rev' => 'AllowedRev'
);
if (!isset($configLookup[$name])) {
trigger_error(
'Unrecognized attribute name for link ' .
'relationship.',
E_USER_ERROR
);
return;
}
$this->name = $configLookup[$name];
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$allowed = $config->get('Attr.' . $this->name);
if (empty($allowed)) {
return false;
}
$string = $this->parseCDATA($string);
$parts = explode(' ', $string);
// lookup to prevent duplicates
$ret_lookup = array();
foreach ($parts as $part) {
$part = strtolower(trim($part));
if (!isset($allowed[$part])) {
continue;
}
$ret_lookup[$part] = true;
}
if (empty($ret_lookup)) {
return false;
}
$string = implode(' ', array_keys($ret_lookup));
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -1,60 +0,0 @@
<?php
/**
* Validates a MultiLength as defined by the HTML spec.
*
* A multilength is either a integer (pixel count), a percentage, or
* a relative number.
*/
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
if ($string === '') {
return false;
}
$parent_result = parent::validate($string, $config, $context);
if ($parent_result !== false) {
return $parent_result;
}
$length = strlen($string);
$last_char = $string[$length - 1];
if ($last_char !== '*') {
return false;
}
$int = substr($string, 0, $length - 1);
if ($int == '') {
return '*';
}
if (!is_numeric($int)) {
return false;
}
$int = (int)$int;
if ($int < 0) {
return false;
}
if ($int == 0) {
return '0';
}
if ($int == 1) {
return '*';
}
return ((string)$int) . '*';
}
}
// vim: et sw=4 sts=4

View File

@ -1,70 +0,0 @@
<?php
/**
* Validates contents based on NMTOKENS attribute type.
*/
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
// early abort: '' and '0' (strings that convert to false) are invalid
if (!$string) {
return false;
}
$tokens = $this->split($string, $config, $context);
$tokens = $this->filter($tokens, $config, $context);
if (empty($tokens)) {
return false;
}
return implode(' ', $tokens);
}
/**
* Splits a space separated list of tokens into its constituent parts.
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return array
*/
protected function split($string, $config, $context)
{
// OPTIMIZABLE!
// do the preg_match, capture all subpatterns for reformulation
// we don't support U+00A1 and up codepoints or
// escaping because I don't know how to do that with regexps
// and plus it would complicate optimization efforts (you never
// see that anyway).
$pattern = '/(?:(?<=\s)|\A)' . // look behind for space or string start
'((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)' .
'(?:(?=\s)|\z)/'; // look ahead for space or string end
preg_match_all($pattern, $string, $matches);
return $matches[1];
}
/**
* Template method for removing certain tokens based on arbitrary criteria.
* @note If we wanted to be really functional, we'd do an array_filter
* with a callback. But... we're not.
* @param array $tokens
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return array
*/
protected function filter($tokens, $config, $context)
{
return $tokens;
}
}
// vim: et sw=4 sts=4

View File

@ -1,76 +0,0 @@
<?php
/**
* Validates an integer representation of pixels according to the HTML spec.
*/
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
{
/**
* @type int
*/
protected $max;
/**
* @param int $max
*/
public function __construct($max = null)
{
$this->max = $max;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
if ($string === '0') {
return $string;
}
if ($string === '') {
return false;
}
$length = strlen($string);
if (substr($string, $length - 2) == 'px') {
$string = substr($string, 0, $length - 2);
}
if (!is_numeric($string)) {
return false;
}
$int = (int)$string;
if ($int < 0) {
return '0';
}
// upper-bound value, extremely high values can
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
// WARNING, above link WILL crash you if you're using Windows
if ($this->max !== null && $int > $this->max) {
return (string)$this->max;
}
return (string)$int;
}
/**
* @param string $string
* @return HTMLPurifier_AttrDef
*/
public function make($string)
{
if ($string === '') {
$max = null;
} else {
$max = (int)$string;
}
$class = get_class($this);
return new $class($max);
}
}
// vim: et sw=4 sts=4

View File

@ -1,91 +0,0 @@
<?php
/**
* Validates an integer.
* @note While this class was modeled off the CSS definition, no currently
* allowed CSS uses this type. The properties that do are: widows,
* orphans, z-index, counter-increment, counter-reset. Some of the
* HTML attributes, however, find use for a non-negative version of this.
*/
class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
{
/**
* Whether or not negative values are allowed.
* @type bool
*/
protected $negative = true;
/**
* Whether or not zero is allowed.
* @type bool
*/
protected $zero = true;
/**
* Whether or not positive values are allowed.
* @type bool
*/
protected $positive = true;
/**
* @param $negative Bool indicating whether or not negative values are allowed
* @param $zero Bool indicating whether or not zero is allowed
* @param $positive Bool indicating whether or not positive values are allowed
*/
public function __construct($negative = true, $zero = true, $positive = true)
{
$this->negative = $negative;
$this->zero = $zero;
$this->positive = $positive;
}
/**
* @param string $integer
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($integer, $config, $context)
{
$integer = $this->parseCDATA($integer);
if ($integer === '') {
return false;
}
// we could possibly simply typecast it to integer, but there are
// certain fringe cases that must not return an integer.
// clip leading sign
if ($this->negative && $integer[0] === '-') {
$digits = substr($integer, 1);
if ($digits === '0') {
$integer = '0';
} // rm minus sign for zero
} elseif ($this->positive && $integer[0] === '+') {
$digits = $integer = substr($integer, 1); // rm unnecessary plus
} else {
$digits = $integer;
}
// test if it's numeric
if (!ctype_digit($digits)) {
return false;
}
// perform scope tests
if (!$this->zero && $integer == 0) {
return false;
}
if (!$this->positive && $integer > 0) {
return false;
}
if (!$this->negative && $integer < 0) {
return false;
}
return $integer;
}
}
// vim: et sw=4 sts=4

View File

@ -1,86 +0,0 @@
<?php
/**
* Validates the HTML attribute lang, effectively a language code.
* @note Built according to RFC 3066, which obsoleted RFC 1766
*/
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$string = trim($string);
if (!$string) {
return false;
}
$subtags = explode('-', $string);
$num_subtags = count($subtags);
if ($num_subtags == 0) { // sanity check
return false;
}
// process primary subtag : $subtags[0]
$length = strlen($subtags[0]);
switch ($length) {
case 0:
return false;
case 1:
if (!($subtags[0] == 'x' || $subtags[0] == 'i')) {
return false;
}
break;
case 2:
case 3:
if (!ctype_alpha($subtags[0])) {
return false;
} elseif (!ctype_lower($subtags[0])) {
$subtags[0] = strtolower($subtags[0]);
}
break;
default:
return false;
}
$new_string = $subtags[0];
if ($num_subtags == 1) {
return $new_string;
}
// process second subtag : $subtags[1]
$length = strlen($subtags[1]);
if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) {
return $new_string;
}
if (!ctype_lower($subtags[1])) {
$subtags[1] = strtolower($subtags[1]);
}
$new_string .= '-' . $subtags[1];
if ($num_subtags == 2) {
return $new_string;
}
// process all other subtags, index 2 and up
for ($i = 2; $i < $num_subtags; $i++) {
$length = strlen($subtags[$i]);
if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) {
return $new_string;
}
if (!ctype_lower($subtags[$i])) {
$subtags[$i] = strtolower($subtags[$i]);
}
$new_string .= '-' . $subtags[$i];
}
return $new_string;
}
}
// vim: et sw=4 sts=4

View File

@ -1,53 +0,0 @@
<?php
/**
* Decorator that, depending on a token, switches between two definitions.
*/
class HTMLPurifier_AttrDef_Switch
{
/**
* @type string
*/
protected $tag;
/**
* @type HTMLPurifier_AttrDef
*/
protected $withTag;
/**
* @type HTMLPurifier_AttrDef
*/
protected $withoutTag;
/**
* @param string $tag Tag name to switch upon
* @param HTMLPurifier_AttrDef $with_tag Call if token matches tag
* @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token
*/
public function __construct($tag, $with_tag, $without_tag)
{
$this->tag = $tag;
$this->withTag = $with_tag;
$this->withoutTag = $without_tag;
}
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
$token = $context->get('CurrentToken', true);
if (!$token || $token->name !== $this->tag) {
return $this->withoutTag->validate($string, $config, $context);
} else {
return $this->withTag->validate($string, $config, $context);
}
}
}
// vim: et sw=4 sts=4

View File

@ -1,21 +0,0 @@
<?php
/**
* Validates arbitrary text according to the HTML spec.
*/
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
{
/**
* @param string $string
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($string, $config, $context)
{
return $this->parseCDATA($string);
}
}
// vim: et sw=4 sts=4

View File

@ -1,111 +0,0 @@
<?php
/**
* Validates a URI as defined by RFC 3986.
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
*/
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_URIParser
*/
protected $parser;
/**
* @type bool
*/
protected $embedsResource;
/**
* @param bool $embeds_resource Does the URI here result in an extra HTTP request?
*/
public function __construct($embeds_resource = false)
{
$this->parser = new HTMLPurifier_URIParser();
$this->embedsResource = (bool)$embeds_resource;
}
/**
* @param string $string
* @return HTMLPurifier_AttrDef_URI
*/
public function make($string)
{
$embeds = ($string === 'embedded');
return new HTMLPurifier_AttrDef_URI($embeds);
}
/**
* @param string $uri
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return bool|string
*/
public function validate($uri, $config, $context)
{
if ($config->get('URI.Disable')) {
return false;
}
$uri = $this->parseCDATA($uri);
// parse the URI
$uri = $this->parser->parse($uri);
if ($uri === false) {
return false;
}
// add embedded flag to context for validators
$context->register('EmbeddedURI', $this->embedsResource);
$ok = false;
do {
// generic validation
$result = $uri->validate($config, $context);
if (!$result) {
break;
}
// chained filtering
$uri_def = $config->getDefinition('URI');
$result = $uri_def->filter($uri, $config, $context);
if (!$result) {
break;
}
// scheme-specific validation
$scheme_obj = $uri->getSchemeObj($config, $context);
if (!$scheme_obj) {
break;
}
if ($this->embedsResource && !$scheme_obj->browsable) {
break;
}
$result = $scheme_obj->validate($uri, $config, $context);
if (!$result) {
break;
}
// Post chained filtering
$result = $uri_def->postFilter($uri, $config, $context);
if (!$result) {
break;
}
// survived gauntlet
$ok = true;
} while (false);
$context->destroy('EmbeddedURI');
if (!$ok) {
return false;
}
// back to string
return $uri->toString();
}
}
// vim: et sw=4 sts=4

View File

@ -1,20 +0,0 @@
<?php
abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
{
/**
* Unpacks a mailbox into its display-name and address
* @param string $string
* @return mixed
*/
public function unpack($string)
{
// needs to be implemented
}
}
// sub-implementations
// vim: et sw=4 sts=4

Some files were not shown because too many files have changed in this diff Show More