Compare commits

..
192 Commits
Author SHA1 Message Date
bachir 9344a61b61 updated core to 7.58 (right after the site was hacked) 2018-04-20 23:48:40 +02:00
Bachir Soussi Chiadmi 18f4aba146 added redis contrib module 2018-02-21 14:07:00 +01:00
Bachir Soussi Chiadmi 1eb61fe020 fixed js bug Drupal.ajax undefined, fixe #81 2018-01-11 17:09:04 +01:00
Bachir Soussi Chiadmi a11650f2b4 fixed header height 2018-01-02 12:20:33 +01:00
Bachir Soussi Chiadmi f09e9563b2 Merge branch 'advanced-search' 2018-01-02 12:13:16 +01:00
Bachir Soussi Chiadmi c914e7e348 fixed header height 2018-01-02 12:11:58 +01:00
Bachir Soussi Chiadmi b5f3769416 new browser prefix ?? 2018-01-02 12:02:43 +01:00
Bachir Soussi Chiadmi 3133fd480b updated materio_personal_notes feature 2017-12-04 14:05:55 +01:00
Bachir Soussi Chiadmi b20732f9a8 personal note display for viewmode cardfull 2017-11-29 17:14:01 +01:00
Bachir Soussi Chiadmi 8b486ffc60 personal-notes display for card medium and cardfull is ok 2017-11-29 16:40:20 +01:00
Bachir Soussi Chiadmi 7d5bedcb0c personnale notes front ajax is working, remains to improve the display, do it like liked materiaux 2017-11-28 17:02:45 +01:00
Bachir Soussi Chiadmi 268c8b619b added link with query for target node id and prepopulated node form 2017-11-27 15:21:32 +01:00
Bachir Soussi Chiadmi bbeb5f01ac created materio personal notes feature 2017-11-27 12:28:46 +01:00
Bachir Soussi Chiadmi bd1a1de792 first commit of materio personal notes module : just displaying the icon button for now 2017-11-27 12:20:08 +01:00
Bachir Soussi Chiadmi af9630060a improved display of advanced search 2017-11-21 10:44:24 +01:00
Bachir Soussi Chiadmi 383ca8b173 improved display of advanced search 2017-11-21 10:38:27 +01:00
Bachir Soussi Chiadmi afc654c704 improved throbber display in advenced search 2017-11-21 09:58:45 +01:00
Bachir Soussi Chiadmi 106129c27c refined advanced search form display to be more explicite 2017-11-20 17:52:39 +01:00
Bachir Soussi Chiadmi 81810c5af4 fixed loading indicator for both search forms 2017-11-15 13:53:48 +01:00
Bachir Soussi Chiadmi 12c076c349 some comments cleaning 2017-11-07 20:00:55 +01:00
Bachir Soussi Chiadmi 9d45086951 fixed infinite scroll with advenced search 2017-11-06 16:45:40 +01:00
Bachir Soussi Chiadmi 8777adbe2e restored ajax search for filtered search 2017-11-06 16:28:05 +01:00
Bachir Soussi Chiadmi 82a22114d3 fixed one term search bug: no results 2017-11-06 16:20:03 +01:00
Bachir Soussi Chiadmi 098f083b8d fixed page title and performance display for filtered search by tids : displa term names instead of tids 2017-11-06 12:10:56 +01:00
Bachir Soussi Chiadmi e8586eb4da Sorl search based on term tid and scored is functional 2017-11-06 11:47:33 +01:00
Bachir Soussi Chiadmi 1e1a762b9b added settings for advanced search vocabulary choice and hidden terms 2017-10-31 12:47:28 +01:00
Bachir Soussi Chiadmi e9146c29ce handled ajax call for advanced search, handled permissions for advanced form display 2017-10-31 11:08:13 +01:00
Bachir Soussi Chiadmi 042e111bc4 created proper solr call for filtered search 2017-10-30 14:48:23 +01:00
Bachir Soussi Chiadmi 2f56697bb7 tabs interface for search forms is ready 2017-10-30 12:07:21 +01:00
Bachir Soussi Chiadmi 55700094a2 started to mix search form and advanced search form into one unique block, the idea is to switch to one from an other with tabs 2017-10-25 17:01:00 +02:00
Bachir Soussi Chiadmi 9bfbd861ca bugfix 2017-10-11 17:05:20 +02:00
Bachir Soussi Chiadmi 5f26b3e160 bugfix 2017-10-11 14:44:55 +02:00
Bachir Soussi Chiadmi 1b9f8e3ab4 first test of launch a research, read the url args and prepopulate the form, ajax add and remove filter are not working anymore 2017-10-10 16:51:22 +02:00
Bachir Soussi Chiadmi c90cfa63e4 advanced search : all ajax form behaviours are working 2017-10-10 12:43:45 +02:00
Bachir Soussi Chiadmi 7bc3c13ad6 fixed tode module php notice 2017-10-09 16:38:53 +02:00
Bachir Soussi Chiadmi 1ee4e95491 advanced search ajax callback for dynamic form building are almost working + started css 2017-10-09 16:38:18 +02:00
Bachir Soussi Chiadmi bf5f1a63ff updated gulp and bower files 2017-10-09 16:35:06 +02:00
Bachir Soussi Chiadmi 38648c1670 advenced search block is in place, remains to build the whole logic 2017-10-07 20:29:58 +02:00
Bachir Soussi Chiadmi 1d4fcf0d89 Merge branch 'master' into advanced-search 2017-10-07 20:05:52 +02:00
Bachir Soussi Chiadmi 73417de740 updated all features 2017-10-07 20:04:02 +02:00
Bachir Soussi Chiadmi 0edc6fd23a started advenced serch form block 2017-10-07 19:49:22 +02:00
Bachir Soussi Chiadmi abb106d7c2 optmized industriels esport 2017-09-18 16:04:53 +02:00
Bachir Soussi Chiadmi be2da7afe0 added the right export script for industriels users (not companies) 2017-09-18 15:46:40 +02:00
Bachir Soussi Chiadmi 243f5b689c fixed advanced search first rquest bug (bois+translucide) fix #31 2017-09-16 16:52:04 +02:00
Bachir Soussi Chiadmi 301d403887 fixed contactops export bug 2017-09-16 16:14:23 +02:00
Bachir Soussi Chiadmi 08e5ed7202 removed personnal script sync_uplaods from git tree 2017-09-16 16:06:39 +02:00
Bachir Soussi Chiadmi 4ca87255ab added export companies as csv file function 2017-09-16 16:03:43 +02:00
Bachir Soussi Chiadmi 4b2ab455c9 first draft of materio_contactops module : shows company taged materials for a user contactop 2017-07-25 22:32:52 +02:00
Bachir Soussi Chiadmi b9c809d2c7 updated webform, uuid, synonyms modules 2017-07-25 19:28:08 +02:00
Bachir Soussi Chiadmi ed483507e5 security update for smtp module 2017-07-25 19:17:08 +02:00
Bachir Soussi Chiadmi 8feebe3d1e repatched core with https://www.drupal.org/node/1754162#comment-9737269 2017-07-25 19:13:30 +02:00
Bachir Soussi Chiadmi 5c7f02554f updated core to 7.56, secutity update 2017-07-25 19:10:33 +02:00
Bachir Soussi Chiadmi 58161d2b57 fixed render function wrongly removed from industriel newsletter template 2017-07-06 17:46:22 +02:00
Bachir Soussi Chiadmi ce192b080e removed all html from industriel news template 2017-07-06 17:12:45 +02:00
Bachir Soussi Chiadmi aafe1c5460 added new template for industriels newsletter 2017-07-05 22:27:45 +02:00
Bachir Soussi Chiadmi 8539255353 optimzed some php code in admin views 2017-07-05 21:50:49 +02:00
Bachir Soussi Chiadmi 5706aea93b added some missing navigation menu items in admin feature 2017-07-05 21:39:11 +02:00
Bachir Soussi Chiadmi 9369b73118 added new light industriel view and indus. export list for simplenewsletter massive subscription 2017-07-05 21:29:03 +02:00
Bachir Soussi Chiadmi ab9f1d3cc4 added template for industriels simplenewletter 2017-07-05 18:34:56 +02:00
Bachir Soussi Chiadmi 8d0f110c50 fixe contact ops materiaux access, fixe #21 2017-07-04 20:56:25 +02:00
Bachir Soussi Chiadmi cedbce376b updated features 2017-07-04 20:02:56 +02:00
Bachir Soussi Chiadmi 6e2a36fe0c front : imporved location layout in fullcards
fix #6
2017-05-30 12:09:59 +02:00
Bachir Soussi Chiadmi d9f3677b98 applied security views modules updates
didn't repatched view module, keep it in mind, may be necessary
2017-05-24 19:35:05 +02:00
Bachir Soussi Chiadmi 5b82dfb691 repatched core with https://www.drupal.org/node/1754162#comment-9737269 2017-05-24 19:31:16 +02:00
Bachir Soussi Chiadmi 728f8e6d31 updated core to 7.54 2017-05-24 19:27:14 +02:00
Bachir Soussi Chiadmi 9acef9d37e updated ctools, panels, date, diff 2017-05-24 19:22:50 +02:00
Bachir Soussi Chiadmi 542ac42fca updated views_send views_bulk_update views_data_export 2017-05-24 19:09:09 +02:00
Bachir Soussi Chiadmi dbd7b88639 applied security contrib modules updates
didn't repatched view module, keep it in mind, may be necessary
2017-05-24 19:02:39 +02:00
Bachir Soussi Chiadmi 28c7a0965a updated search_api modules as indexation was not working localy
had to be tested in production
2017-05-24 18:57:04 +02:00
Bachir Soussi Chiadmi b5d76ec5e6 fixed home simplenews picture match 2017-05-24 15:28:00 +02:00
Bachir Soussi Chiadmi 83cbcefff9 re-added temporarly translate_perms 2016-12-20 12:22:42 +01:00
Bachir Soussi Chiadmi 0d940c99db updated features 2016-12-20 01:15:04 +01:00
Bachir Soussi Chiadmi 2334eb741b updated features for precedent commit 2016-12-20 00:18:28 +01:00
Bachir Soussi Chiadmi ddc28956c4 added string and field translation table for translators 2016-12-20 00:17:50 +01:00
Bachir Soussi Chiadmi abbcb19838 removed i18n_access from tree 2016-12-19 19:08:09 +01:00
Bachir Soussi Chiadmi 024afdfd3d Merge branch 'master' into translators 2016-12-19 18:15:12 +01:00
Bachir Soussi Chiadmi b9f2b16d24 modules security update
views_send, elysia_cron
2016-12-19 18:10:13 +01:00
Bachir Soussi Chiadmi 3f9ba49255 repatched core user module
language aware tokens
https://www.drupal.org/node/1754162
2016-12-19 17:06:32 +01:00
Bachir Soussi Chiadmi f01fdbdd9c security core update 2016-12-19 16:57:32 +01:00
Bachir Soussi Chiadmi 7563311a19 handled translation links from node edit 2016-12-19 00:39:20 +01:00
Bachir Soussi Chiadmi 669341f1d6 added forgoten materio_translators.install file 2016-12-13 13:01:55 +01:00
Bachir Soussi Chiadmi 13aafca7e4 moved the duplicatesmail menu 2016-12-13 13:00:59 +01:00
Bachir Soussi Chiadmi e24eec56e7 materio translator : Node overview DONE 2016-12-13 12:52:01 +01:00
Bachir Soussi Chiadmi eba58a57bf added the second patch to i18n_access BUT WE WONT USE THIS MODULE! 2016-12-13 12:50:01 +01:00
Bachir Soussi Chiadmi e190f5f47d improved original language on node form display 2016-12-13 12:49:02 +01:00
Bachir Soussi Chiadmi ec6f23e149 patched i18n_access module
https://www.drupal.org/node/2298475#comment-9419835
2016-12-12 16:01:17 +01:00
Bachir Soussi Chiadmi fdd842fe19 rolled back i18n_access to last dev version 2016-12-12 15:58:28 +01:00
Bachir Soussi Chiadmi 73ec6d3c1e fixed image for anonymous 2016-12-12 14:35:55 +01:00
Bachir Soussi Chiadmi dee5085c89 improved term field restoration batch script 2016-12-12 11:33:34 +01:00
Bachir Soussi Chiadmi c4ab89f177 trying to fix PHP Fatal error: Cannot use [] for reading 2016-12-12 11:30:20 +01:00
Bachir Soussi Chiadmi d1b069ad8b added term field restoration batch script 2016-12-12 11:24:20 +01:00
Bachir Soussi Chiadmi c56a523286 fixed showroom field form bug, removed ordering, fixed card js in node page 2016-12-11 19:50:48 +01:00
Bachir Soussi Chiadmi 8b5d721bfd fixed location field access for administrator, improved disbaled field display 2016-12-11 11:30:39 +01:00
Bachir Soussi Chiadmi 7ed9dc54bf fixed card print css display 2016-12-11 10:34:10 +01:00
Bachir Soussi Chiadmi adee2f54e3 fixed card print css display 2016-12-11 10:30:32 +01:00
Bachir Soussi Chiadmi 41e3e6dfb2 Location -> samples, fixed cs display, fixed empty field 2016-12-11 10:17:00 +01:00
Bachir Soussi Chiadmi 5f6a9ac5d1 fixed showroom location formatter and contentype display
remains css
2016-12-10 19:27:00 +01:00
Bachir Soussi Chiadmi 16d8adc672 trimed contentadminrelink 2016-12-10 18:31:21 +01:00
Bachir Soussi Chiadmi 138b68ac98 commited features for showroom release 2016-12-10 18:30:03 +01:00
Bachir Soussi Chiadmi 026a9bc241 commited custom modules for showroom release 2016-12-10 18:29:27 +01:00
Bachir Soussi Chiadmi adb1437a44 reseted old features as in prod 2016-12-10 11:10:49 +01:00
Bachir Soussi Chiadmi 5d17730143 added helpers scripts 2016-12-10 11:03:19 +01:00
Bachir Soussi Chiadmi 1ec80dc60e finished showroom migration batch function 2016-11-27 19:48:58 +01:00
Bachir Soussi Chiadmi 5423f6d3bc added per user showroom location field access 2016-11-27 12:27:57 +01:00
Bachir Soussi Chiadmi 1ccc5d07d6 coded the showroom field
still have to manage access
2016-11-26 21:18:06 +01:00
Bachir Soussi Chiadmi 597e6c9159 first draft of custom materio showroom location, recording values DOESN'T WORK 2016-11-22 19:12:02 +01:00
Bachir Soussi Chiadmi b26db27098 patched loggintobogan fixed bug against field_permissions
removed field_collection (gonna dev own custom modules for showroom
updated field-permissions to last dev
2016-11-22 19:05:44 +01:00
Bachir Soussi Chiadmi b9ac935de6 with last commit: contrib field_collection mod & custom showroom et translator mods 2016-11-21 19:42:00 +01:00
Bachir Soussi Chiadmi 091c01ce81 updated features : created showroom_localisation field. Perms with showroom role are still failing 2016-11-21 19:39:50 +01:00
Bachir Soussi Chiadmi 039f49aded updated amdin content-types showroom features 2016-11-21 15:32:15 +01:00
Bachir Soussi Chiadmi cc295255a1 Merge branch 'translators' into showroom 2016-11-21 10:50:21 +01:00
Bachir Soussi Chiadmi fedd8f4216 updated Fast permission admin module to last dev 2016-11-21 10:35:49 +01:00
Bachir Soussi Chiadmi 73f871cbcc added translate link to admin view 2016-11-07 17:29:00 +01:00
Bachir Soussi Chiadmi 0f286a2d78 css language switcher for more than 2 languages 2016-11-07 16:32:29 +01:00
Bachir Soussi Chiadmi ac87a57196 created translations feature 2016-11-07 16:31:32 +01:00
Bachir Soussi Chiadmi b00f897952 fixed images display bug in admin 2016-11-07 14:01:48 +01:00
Bachir Soussi Chiadmi 99f92edb37 updatedadmin feature 2016-11-07 13:15:03 +01:00
Bachir Soussi Chiadmi d0566a6155 tryig to fix admin feature 2016-11-07 13:12:59 +01:00
Bachir Soussi Chiadmi 0bf7b4a1c8 added companies views in admin feature 2016-11-07 13:00:45 +01:00
Bachir Soussi Chiadmi 2f02bb6485 fixed niouseletter on mobile 2016-11-07 12:18:15 +01:00
Bachir Soussi Chiadmi a477dbb8ec updated features 2016-11-07 10:51:20 +01:00
Bachir Soussi Chiadmi d4fee57337 removed TAC dependency form showroom feature 2016-11-07 09:56:29 +01:00
Bachir Soussi Chiadmi c97d1d7f75 updated features for showroom 2016-11-06 21:32:21 +01:00
Bachir Soussi Chiadmi c7e2de9e8b updated permission admin feature for showroom 2016-11-06 19:48:20 +01:00
Bachir Soussi Chiadmi cc000ce3d6 updated content admin views for showroom 2016-11-06 19:45:15 +01:00
Bachir Soussi Chiadmi 7abf64be00 Showroom feature 2016-11-06 19:40:18 +01:00
Bachir Soussi Chiadmi e8cadc31e1 patched link module to allow more tld
https://www.drupal.org/node/2299657#comment-11414075
http://studio.g-u-i.net/en/materio/node/1524#comment-2488
2016-11-05 19:53:24 +01:00
Bachir Soussi Chiadmi 7011e6c691 reverted node form columns du to scroll bug
http://studio.g-u-i.net/en/materio/node/1535
2016-11-05 19:22:53 +01:00
Bachir Soussi Chiadmi c70a4bed11 updated serial field 2016-11-05 17:58:43 +01:00
Bachir Soussi Chiadmi 252abe9b0e updated synonyms to 1.5 2016-11-05 17:54:56 +01:00
Bachir Soussi Chiadmi 773e7fbddd updated synonyms to 1.4 2016-11-05 17:53:45 +01:00
Bachir Soussi Chiadmi 8d24211bf5 updated synonyms to 1.3 2016-11-05 17:52:37 +01:00
Bachir Soussi Chiadmi 86c993f638 updated uc_termsofservice, session_limit 2016-11-05 17:26:29 +01:00
Bachir Soussi Chiadmi 08127672d6 updated wysiwyg_filter, video_filter 2016-11-05 17:23:03 +01:00
Bachir Soussi Chiadmi 66fa1d419d reverted webform_localization as it depends on webform 4.x 2016-11-05 17:19:33 +01:00
Bachir Soussi Chiadmi 0521608bb7 updated webform localization and phone, uuid, term_merge, spambot, performance 2016-11-05 17:14:57 +01:00
Bachir Soussi Chiadmi fdefc824d8 updated node_export, mimemail, menu_attributes 2016-11-05 17:09:40 +01:00
Bachir Soussi Chiadmi 2b028cf376 updated login-destination, libraries 2016-11-05 17:05:09 +01:00
Bachir Soussi Chiadmi d1963312a6 updated entity update 2016-11-05 16:55:34 +01:00
Bachir Soussi Chiadmi 3b6c7b914d updated view_send, vews_php, nodeformcols, email_registratio 2016-11-05 16:53:56 +01:00
Bachir Soussi Chiadmi 0bb339fc99 updated ubercart, faq 2016-11-05 16:50:18 +01:00
Bachir Soussi Chiadmi 3413d81bb8 updated context, metatag, imagestyleflush, browscap 2016-11-05 16:43:45 +01:00
Bachir Soussi Chiadmi 7aeabebddf updated imce, colorbox, admin_menu_source, honey_pot 2016-11-05 16:33:10 +01:00
Bachir Soussi Chiadmi 2e0abeed03 commented flag_lists failing updates
checked db table integrity, lokks like fine ...
2016-11-05 16:24:44 +01:00
Bachir Soussi Chiadmi 82bb633c3e updated contrib themes 2016-11-05 15:35:11 +01:00
Bachir Soussi Chiadmi 104fcaf970 removed unused search api page module 2016-11-05 14:59:48 +01:00
Bachir Soussi Chiadmi 34649ab98b finished security upadtes 2016-11-05 14:42:59 +01:00
Bachir Soussi Chiadmi 9c43ba2fc6 applied patch on user module
Implement language aware tokens for one time login link and cancel link
https://www.drupal.org/node/1754162
2016-11-01 18:24:53 +01:00
Bachir Soussi Chiadmi 1f780c974e updated drupal core to 7.51 2016-11-01 18:21:48 +01:00
Bachir Soussi Chiadmi 2ed8b48636 fixed compatibility with module flag_lists 3.x
converted materiobasemod js processor to gulp
2016-11-01 16:50:23 +01:00
Bachir Soussi Chiadmi d712e5881a load gui.js with module insted of theme 2016-11-01 16:47:25 +01:00
Bachir Soussi Chiadmi 253524c527 updated flag_list to 3.x version. ATTENTION DO NOT WORK ANYMORE create new folder broken 2016-10-25 20:12:36 +02:00
Bachir Soussi Chiadmi ae7349e811 updated entity translation, seems to don't need patch anymore 2016-10-25 18:32:11 +02:00
Bachir Soussi Chiadmi c64b25b261 repatched views module
is this realy necessary yet ?
didn't find where i found this fixe
2016-10-25 18:14:22 +02:00
Bachir Soussi Chiadmi 992c9a552a updated views 2016-10-25 17:59:47 +02:00
Bachir Soussi Chiadmi a2db826449 changed gitignore 2016-10-25 17:55:00 +02:00
Bachir Soussi Chiadmi b11abbed59 updated ctools, needed by panles 2016-10-25 17:47:45 +02:00
Bachir Soussi Chiadmi f6f7fd575f security updates of unpatched modules 2016-10-25 16:23:00 +02:00
Bachir Soussi Chiadmi 610760bedf updated features 2016-10-25 16:05:27 +02:00
Bachir Soussi Chiadmi 54399b169a created showroom feature 2016-10-25 16:05:07 +02:00
Bachir Soussi Chiadmi 598f3e8292 fixe email centering 2016-07-28 14:02:21 +02:00
Bachir Soussi Chiadmi 0347c5cb99 trying to fix daily mail not centered 2016-07-27 14:47:12 +02:00
Bachir Soussi Chiadmi 1f5092fb45 addded alt attribute on simplenews template img 2016-07-22 22:53:10 +02:00
Bachir Soussi Chiadmi 31d638cff7 addded alt attribute on simplenews template img 2016-07-22 22:52:36 +02:00
Bachir Soussi Chiadmi 31409daed2 added compser vendors for mailgun librarie 2016-07-19 20:40:37 +02:00
Bachir Soussi Chiadmi 42347006ff changed mailing feature 2016-07-19 20:17:47 +02:00
Bachir Soussi Chiadmi dd95b24f5b changed mailing feature 2016-07-19 20:14:04 +02:00
Bachir Soussi Chiadmi 507402d07b added mailing feature 2016-07-19 20:09:30 +02:00
Bachir Soussi Chiadmi e310490c7f added members sentence to simplenews daily template 2016-07-19 19:58:57 +02:00
Bachir Soussi Chiadmi 918b4cd5e1 added mailgun librarie 2016-07-19 19:58:07 +02:00
Bachir Soussi Chiadmi deae7e0b59 added mailgun module 2016-07-19 17:52:15 +02:00
Bachir Soussi Chiadmi c64551f50c removed the test.txt file as remote is working 2016-07-08 12:09:16 +02:00
Bachir Soussi Chiadmi 73793c9ba9 a commit to test the new remote prod serveur 2016-07-08 12:04:22 +02:00
Bachir Soussi Chiadmi d38e929be5 fixed img max-width on simplenews 2016-06-24 11:12:32 +02:00
Bachir Soussi Chiadmi 266fb10083 fixed img max-width on simplenews 2016-06-24 11:10:09 +02:00
Bachir Soussi Chiadmi 6fee348360 fixed mobile responsive display 2016-06-15 13:28:12 +02:00
Bachir Soussi Chiadmi 74f8c52af3 fixed mobile responsive display 2016-06-15 13:22:05 +02:00
Bachir Soussi Chiadmi 9c97849d78 added metatag feature 2016-06-13 19:53:16 +02:00
Bachir Soussi Chiadmi 2ca9694d84 added social links block 2016-06-13 19:14:58 +02:00
Bachir Soussi Chiadmi 422322c96d bug fix : print with only one image
http://studio.g-u-i.net/fr/materio/node/1523
2016-06-13 15:14:54 +02:00
Bachir Soussi Chiadmi aea9683c77 updated link module 2016-04-19 16:40:02 +02:00
Bachir Soussi Chiadmi e2fde76aff updated features 2016-04-19 16:32:54 +02:00
Bachir Soussi Chiadmi fb0666538c updated user_import 2016-04-19 16:29:53 +02:00
Bachir Soussi Chiadmi 3a55dcea49 fixed pager 2016-03-29 13:05:38 +02:00
Bachir Soussi Chiadmi 39dc81ad14 fixed and refactored solr search main function 2016-03-29 12:42:22 +02:00
Bachir Soussi Chiadmi 7b11f2794e fixed bug js missing gui.js function trace() 2016-03-16 18:01:53 +01:00
Bachir Soussi Chiadmi c23706f745 updated PATCH_LIST 2016-03-16 16:59:24 +01:00
Bachir Soussi Chiadmi c47d792cd1 field_group security update 2016-03-16 16:57:22 +01:00
Bachir Soussi Chiadmi d7697f0f76 repatched user module
https://www.drupal.org/node/1754162
2016-03-16 16:44:57 +01:00
Bachir Soussi Chiadmi b27aabe359 updated drupal core to 7.43 2016-03-16 16:41:44 +01:00
Bachir Soussi Chiadmi 8fb9c70e42 updated faq feature 2016-03-16 16:10:24 +01:00
Bachir Soussi Chiadmi 1658e609f8 updated materio_feature 2016-03-16 16:01:35 +01:00
4353 changed files with 390067 additions and 48521 deletions
+5
View File
@@ -22,3 +22,8 @@ node_modules
.sass-cache
typescript
.directory
*.old_patched
sync_uploads
+281 -30
View File
@@ -1,4 +1,255 @@
Drupal 7.58, 2018-03-28
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-002.
Drupal 7.57, 2018-02-21
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-001.
Drupal 7.56, 2017-06-21
-----------------------
- Fixed security issues (access bypass). See SA-CORE-2017-003.
Drupal 7.55, 2017-06-07
-----------------------
- Fixed incompatibility with PHP versions 7.0.19 and 7.1.5 due to duplicate
DATE_RFC7231 definition.
- Made Drupal core pass all automated tests on PHP 7.1.
- Allowed services such as Let's Encrypt to work with Drupal on Apache, by
making Drupal's .htaccess file allow access to the .well-known directory
defined by RFC 5785.
- Made new Drupal sites work correctly on Apache 2.4 when the mod_access_compat
Apache module is disabled.
- Fixed Drupal's URL-generating functions to always encode '[' and ']' so that
the URLs will pass HTML5 validation.
- Various additional bug fixes.
- Various API documentation improvements.
- Additional automated test coverage.
Drupal 7.54, 2017-02-01
-----------------------
- Modules are now able to define theme engines (API addition:
https://www.drupal.org/node/2826480).
- Logging of searches can now be disabled (new option in the administrative
interface).
- Added menu tree render structure to (pre-)process hooks for theme_menu_tree()
(API addition: https://www.drupal.org/node/2827134).
- Added new function for determining whether an HTTPS request is being served
(API addition: https://www.drupal.org/node/2824590).
- Fixed incorrect default value for short and medium date formats on the date
type configuration page.
- File validation error message is now removed after subsequent upload of valid
file.
- Numerous bug fixes.
- Numerous API documentation improvements.
- Additional performance improvements.
- Additional automated test coverage.
Drupal 7.53, 2016-12-07
-----------------------
- Fixed drag and drop support on newer Chrome/IE 11+ versions after 7.51 update
when jQuery is updated to 1.7-1.11.0.
Drupal 7.52, 2016-11-16
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-005.
Drupal 7.51, 2016-10-05
-----------------------
- The Update module now also checks for updates to a disabled theme that is
used as an admin theme.
- Exceptions thrown in dblog_watchdog() are now caught and ignored.
- Clarified the warning that appears when modules are missing or have moved.
- Log messages are now XSS filtered on display.
- Draggable tables now work on touch screen devices.
- Added a setting for allowing double underscores in CSS identifiers
(https://www.drupal.org/node/2810369).
- If a user navigates away from a page while an Ajax request is running they
will no longer get an error message saying "An Ajax HTTP request terminated
abnormally".
- The system_region_list() API function now takes an optional third parameter
which allows region name translations to be skipped when they are not needed
(API addition: https://www.drupal.org/node/2810365).
- Numerous performance improvements.
- Numerous bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.50, 2016-07-07
-----------------------
- Added a new "administer fields" permission for trusted users, which is
required in addition to other permissions to use the field UI
(https://www.drupal.org/node/2483307).
- Added clickjacking protection to Drupal core by setting the X-Frame-Options
header to SAMEORIGIN by default (https://www.drupal.org/node/2735873).
- Added support for full UTF-8 (emojis, Asian symbols, mathematical symbols) on
MySQL and other database drivers when the site and database are configured to
allow it (https://www.drupal.org/node/2761183).
- Improved performance by avoiding a re-scan of directories when a file is
missing; instead, trigger a PHP warning (minor API change:
https://www.drupal.org/node/2581445).
- Made it possible to use any PHP callable in Ajax form callbacks, form API
form-building functions, and form API wrapper callbacks (API addition:
https://www.drupal.org/node/2761169).
- Fixed that following a password reset link while logged in leaves users unable
to change their password (minor user interface change:
https://www.drupal.org/node/2759023).
- Implemented various fixes for automated test failures on PHP 5.4+ and PHP 7.
Drupal core automated tests now pass in these environments.
- Improved support for PHP 7 by fixing various problems.
- Fixed various bugs with PHP 5.5+ imagerotate(), including when incorrect
color indices are passed in.
- Fixed a regression introduced in Drupal 7.43 that allowed files uploaded by
anonymous users to be lost after form validation errors, and that also caused
regressions with certain contributed modules.
- Fixed a regression introduced in Drupal 7.36 which caused the default value
of hidden textarea fields to be ignored.
- Fixed robots.txt to allow search engines to access CSS, JavaScript and image
files.
- Changed wording on the Update Manager settings page to clarify that the
option to check for disabled module updates also applies to uninstalled
modules (administrative-facing translatable string change).
- Changed the help text when editing menu links and configuring URL redirect
actions so that it does not reference "Drupal" or the drupal.org website
(administrative-facing translatable string change).
- Fixed the locale safety check that is used to ensure that translations are
safe to allow for tokens in the href/src attributes of translated strings.
- Fixed that URL generation only works on port 80 when using domain based
language negotation.
- Made method="get" forms work inside the administrative overlay. The fix adds
a new hidden field to these forms when they appear inside the overlay (minor
data structure change).
- Increased maxlength of menu link title input fields in the node form and
menu link form from 128 to 255 characters.
- Removed meaningless post-check=0 and pre-check=0 cache control headers from
Drupal HTTP responses.
- Added a .editorconfig file to auto-configure editors that support it.
- Added --directory option to run-tests.sh for easier test discovery of all
tests within a project.
- Made run-tests.sh exit with a failure code when there are test fails or
problems running the script.
- Fixed that cookies from previous tests are still present when a new test
starts in DrupalWebTestCase.
- Improved performance of queries on the {authmap} database table.
- Fixed handling of missing files and functions inside the registry.
- Fixed Ajax handling for tableselect form elements that use checkboxes.
- Fixed a bug which caused ip_address() to return nothing when the client IP
address and proxy IP address are the same.
- Added a new option to format_xml_elements() to allow for already encoded
values.
- Changed the {history} table's node ID field to be an unsigned integer, to
match the same field in the {node} table and to prevent errors with very
large node IDs.
- Added an explicit page callback to the "admin/people/create" menu item in the
User module (minor data structure change). Previously this automatically
inherited the page callback from the parent "admin/people" menu item, which
broke contributed modules that override the "admin/people" page.
- Numerous small bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.44, 2016-06-15
-----------------------
- Fixed security issues (privilege escalation). See SA-CORE-2016-002.
Drupal 7.43, 2016-02-24
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-001.
Drupal 7.42, 2016-02-03
-----------------------
- Stopped invoking hook_flush_caches() on every cron run, since some modules
use that hook for expensive operations that are only needed on cache clears.
- Changed the default .htaccess and web.config to block Composer-related files.
- Added static caching to module_load_include() to improve performance.
- Fixed double-encoding bugs in select field widgets provided by the Options
module. The fix deprecates the 'strip_tags' property on option widgets and
replaces it with a new 'strip_tags_and_unescape' property (minor data
structure change).
- Improved MySQL 5.7 support by changing the MySQL database driver to stop
using the ANSI SQL mode alias, which has different meanings for different
MySQL versions.
- Fixed a regression introduced in Drupal 7.39 which prevented autocomplete
functionality from working on servers that are not configured to
automatically recognize index.php.
- Updated the Archive_Tar PEAR package to the latest 1.4.0 release, to fix bugs
with tar file handling on various operating systems.
- Fixed fatal errors on node preview when a field is displayed in the node
teaser but hidden in the full node view. The fix removes a
field_attach_prepare_view() call from the node_preview() function since it is
redundant with one in the node preview theme layer.
- Improved the description of the "Trimmed" format option on text fields
(translatable string change, and minor UI and data structure change).
- Numerous small bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.41, 2015-10-21
-----------------------
- Fixed security issues (open redirect). See SA-CORE-2015-004.
Drupal 7.40, 2015-10-14
-----------------------
- Made Drupal's code for parsing .info files run much faster and use much less
memory.
- Prevented drupal_http_request() from returning an error when it receives a
201 through 206 HTTP status code.
- Added support for autoloading traits via the registry on sites running PHP
5.4 or higher.
- Allowed the user-picture.tpl.php theme template to have HTML classes besides
the default "user-picture" class printed in it (markup change).
- Fixed the URL text filter to convert e-mail addresses with plus signs into
mailto: links.
- Added alternate text to file icons displayed by the File module, to improve
accessibility (string change, and minor API addition to theme_file_icon()).
- Changed one-time login link failure messages to be displayed as errors or
warnings as appropriate, rather than as regular status messages (minor UI
change and data structure change).
- Changed the default settings.php configuration to exclude private files from
the "404_fast_paths" behavior.
- Changed the page that displays filter tips for a particular text format, for
example filter/tips/full_html, to return "page not found" or "access denied"
if the format does not exist or the user does not have access to it. This
change adds a new menu item to the Filter module's hook_menu() entry (minor
data structure change).
- Added a new hook, hook_block_cid_parts_alter(), to allow modules to alter the
cache keys used for caching a particular block.
- Made drupal_set_message() display and return messages when "0" is passed in
as the message to set.
- Fixed non-functional "Files displayed by default" setting on file fields.
- The "worker callback" provided in hook_cron_queue_info() and the "finished"
callback specified during batch processing can now be any PHP callable
instead of just functions.
- Prevented drupal_set_time_limit() from decreasing the time limit in the case
where the PHP maximum execution time is already unlimited.
- Changed the default thousand marker for numeric fields from a space ("1 000")
to nothing ("1000") (minor UI change: https://www.drupal.org/node/1388376).
- Prevented malformed theme .info files (without a "name" key) from causing
exceptions during menu rebuilds. If an .info file without a "name" key is
found in a module or theme directory, Drupal will now use the module or
theme's machine name as the display name instead.
- Made the format column in the {date_format_locale} database table
case-sensitive, to match the equivalent column in the {date_formats} table.
- Fixed a bug in the Statistics module that caused JavaScript files attached to
a node while it is being viewed to be omitted from the page.
- Added an optional 'project:' prefix that can be added to dependencies in a
module's .info file to indicate which project the dependency resides in (API
addition: https://www.drupal.org/node/2299747).
- Fixed various bugs that occurred after hooks were invoked early in the Drupal
bootstrap and that caused module_implements() and drupal_alter() to cache an
incomplete set of hook implementations for later use.
- Set the X-Content-Type-Options header to "nosniff" when possible, to prevent
certain web browsers from picking an unsafe MIME type.
- Prevented the database API from executing multiple queries at once on MySQL,
if the site's PHP version is new enough to do so. This is a secondary defense
against SQL injection (API change: https://www.drupal.org/node/2463973).
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused the upgrade
to fail when there were multiple file records pointing to the same file.
- Numerous small bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.39, 2015-08-19
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2015-003.
@@ -86,11 +337,11 @@ Drupal 7.36, 2015-04-01
- Additional automated test coverage.
Drupal 7.35, 2015-03-18
----------------------
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2015-001.
Drupal 7.34, 2014-11-19
----------------------
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-006.
Drupal 7.33, 2014-11-07
@@ -159,11 +410,11 @@ Drupal 7.33, 2014-11-07
- Additional automated test coverage.
Drupal 7.32, 2014-10-15
----------------------
-----------------------
- Fixed security issues (SQL injection). See SA-CORE-2014-005.
Drupal 7.31, 2014-08-06
----------------------
-----------------------
- Fixed security issues (denial of service). See SA-CORE-2014-004.
Drupal 7.30, 2014-07-24
@@ -178,7 +429,7 @@ Drupal 7.30, 2014-07-24
- Additional automated test coverage.
Drupal 7.29, 2014-07-16
----------------------
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-003.
Drupal 7.28, 2014-05-08
@@ -224,11 +475,11 @@ Drupal 7.28, 2014-05-08
- Additional automated test coverage.
Drupal 7.27, 2014-04-16
----------------------
-----------------------
- Fixed security issues (information disclosure). See SA-CORE-2014-002.
Drupal 7.26, 2014-01-15
----------------------
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-001.
Drupal 7.25, 2014-01-02
@@ -294,7 +545,7 @@ Drupal 7.25, 2014-01-02
- Additional automated test coverage.
Drupal 7.24, 2013-11-20
----------------------
-----------------------
- Fixed security issues (multiple vulnerabilities), see SA-CORE-2013-003.
Drupal 7.23, 2013-08-07
@@ -548,8 +799,8 @@ Drupal 7.15, 2012-08-01
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.14 2012-05-02
----------------------
Drupal 7.14, 2012-05-02
-----------------------
- Fixed "integrity constraint" fatal errors when rebuilding registry.
- Fixed custom logo and favicon functionality referencing incorrect paths.
- Fixed DB Case Sensitivity: Allow BINARY attribute in MySQL.
@@ -597,12 +848,12 @@ Drupal 7.14 2012-05-02
- system_update_7061() converts filepaths too aggressively.
- Trigger upgrade path: Node triggers removed when upgrading to 7-x from 6.25.
Drupal 7.13 2012-05-02
----------------------
Drupal 7.13, 2012-05-02
-----------------------
- Fixed security issues (Multiple vulnerabilities), see SA-CORE-2012-002.
Drupal 7.12, 2012-02-01
----------------------
-----------------------
- Fixed bug preventing custom menus from receiving an active trail.
- Fixed hook_field_delete() no longer invoked during field_purge_data().
- Fixed bug causing entity info cache to not be cleared with the rest of caches.
@@ -636,11 +887,11 @@ Drupal 7.12, 2012-02-01
cache.
Drupal 7.11, 2012-02-01
----------------------
-----------------------
- Fixed security issues (Multiple vulnerabilities), see SA-CORE-2012-001.
Drupal 7.10, 2011-12-05
----------------------
-----------------------
- Fixed Content-Language HTTP header to not cause issues with Drush 5.x.
- Reduce memory usage of theme registry (performance).
- Fixed PECL upload progress bar for FileField
@@ -993,7 +1244,7 @@ Drupal 7.0, 2011-01-05
requests.
Drupal 6.23-dev, xxxx-xx-xx (development release)
-----------------------
---------------------------
Drupal 6.22, 2011-05-25
-----------------------
@@ -1003,25 +1254,25 @@ Drupal 6.22, 2011-05-25
- Fixed a variety of other bugs.
Drupal 6.21, 2011-05-25
----------------------
-----------------------
- Fixed security issues (Cross site scripting), see SA-CORE-2011-001.
Drupal 6.20, 2010-12-15
----------------------
-----------------------
- Fixed a variety of small bugs, improved code documentation.
Drupal 6.19, 2010-08-11
----------------------
-----------------------
- Fixed a variety of small bugs, improved code documentation.
Drupal 6.18, 2010-08-11
----------------------
-----------------------
- Fixed security issues (OpenID authentication bypass, File download access
bypass, Comment unpublishing bypass, Actions cross site scripting),
see SA-CORE-2010-002.
Drupal 6.17, 2010-06-02
----------------------
-----------------------
- Improved PostgreSQL compatibility
- Better PHP 5.3 and PHP 4 compatibility
- Better browser compatibility of CSS and JS aggregation
@@ -1030,7 +1281,7 @@ Drupal 6.17, 2010-06-02
- Fixed a variety of other bugs.
Drupal 6.16, 2010-03-03
----------------------
-----------------------
- Fixed security issues (Installation cross site scripting, Open redirection,
Locale module cross site scripting, Blocked user session regeneration),
see SA-CORE-2010-001.
@@ -1042,12 +1293,12 @@ Drupal 6.16, 2010-03-03
- Fixed a variety of other bugs.
Drupal 6.15, 2009-12-16
----------------------
-----------------------
- Fixed security issues (Cross site scripting), see SA-CORE-2009-009.
- Fixed a variety of other bugs.
Drupal 6.14, 2009-09-16
----------------------
-----------------------
- Fixed security issues (OpenID association cross site request forgeries,
OpenID impersonation and File upload), see SA-CORE-2009-008.
- Changed the system modules page to not run all cache rebuilds; use the
@@ -1056,18 +1307,18 @@ Drupal 6.14, 2009-09-16
- Fixed a variety of small bugs.
Drupal 6.13, 2009-07-01
----------------------
-----------------------
- Fixed security issues (Cross site scripting, Input format access bypass and
Password leakage in URL), see SA-CORE-2009-007.
- Fixed a variety of small bugs.
Drupal 6.12, 2009-05-13
----------------------
-----------------------
- Fixed security issues (Cross site scripting), see SA-CORE-2009-006.
- Fixed a variety of small bugs.
Drupal 6.11, 2009-04-29
----------------------
-----------------------
- Fixed security issues (Cross site scripting and limited information
disclosure), see SA-CORE-2009-005
- Fixed performance issues with the menu router cache, the update
@@ -1075,7 +1326,7 @@ Drupal 6.11, 2009-04-29
- Fixed a variety of small bugs.
Drupal 6.10, 2009-02-25
----------------------
-----------------------
- Fixed a security issue, (Local file inclusion on Windows),
see SA-CORE-2009-003
- Fixed node_feed() so custom fields can show up in RSS feeds.
@@ -1471,7 +1722,7 @@ Drupal 4.7.9, 2007-12-05
- fixed a security issue (SQL injection), see SA-2007-031
Drupal 4.7.8, 2007-10-17
----------------------
------------------------
- fixed a security issue (HTTP response splitting), see SA-2007-024
- fixed a security issue (Cross site scripting via uploads), see SA-2007-026
- fixed a security issue (API handling of unpublished comment), see SA-2007-030
@@ -1584,7 +1835,7 @@ Drupal 4.6.11, 2007-01-05
- Fixed security issue (DoS), see SA-2007-002
Drupal 4.6.10, 2006-10-18
------------------------
-------------------------
- Fixed security issue (XSS), see SA-2006-024
- Fixed security issue (CSRF), see SA-2006-025
- Fixed security issue (Form action attribute injection), see SA-2006-026
+45
View File
@@ -0,0 +1,45 @@
CREATE THE MySQL DATABASE
--------------------------
This step is only necessary if you don't already have a database set up (e.g.,
by your host). In the following examples, 'username' is an example MySQL user
which has the CREATE and GRANT privileges. Use the appropriate user name for
your system.
First, you must create a new database for your Drupal site (here, 'databasename'
is the name of the new database):
mysqladmin -u username -p create databasename
MySQL will prompt for the 'username' database password and then create the
initial database files. Next you must log in and set the access database rights:
mysql -u username -p
Again, you will be asked for the 'username' database password. At the MySQL
prompt, enter the following command:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
CREATE TEMPORARY TABLES ON databasename.*
TO 'username'@'localhost' IDENTIFIED BY 'password';
where:
'databasename' is the name of your database
'username' is the username of your MySQL account
'localhost' is the web server host where Drupal is installed
'password' is the password required for that username
Note: Unless the database user/host combination for your Drupal installation
has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
which is currently only used by Drupal core automated tests and some
contributed modules), you will not be able to install or run Drupal.
If successful, MySQL will reply with:
Query OK, 0 rows affected
If the InnoDB storage engine is available, it will be used for all database
tables. InnoDB provides features over MyISAM such as transaction support,
row-level locks, and consistent non-locking reads.
+44
View File
@@ -0,0 +1,44 @@
CREATE THE PostgreSQL DATABASE
------------------------------
Note that the database must be created with UTF-8 (Unicode) encoding.
1. CREATE DATABASE USER
This step is only necessary if you don't already have a user set up (e.g., by
your host), or want to create a new user for use with Drupal only. The
following command creates a new user named 'username' and asks for a password
for that user:
createuser --pwprompt --encrypted --no-createrole --no-createdb username
If there are no errors, then the command was successful.
2. CREATE DRUPAL DATABASE
This step is only necessary if you don't already have a database set up
(e.g., by your host) or want to create a new database for use with Drupal
only. The following command creates a new database named 'databasename',
which is owned by the previously created 'username':
createdb --encoding=UTF8 --owner=username databasename
If there are no errors, then the command was successful.
3. CREATE SCHEMA OR SCHEMAS (Optional advanced step)
Drupal will run across different schemas within your database if you so wish.
By default, Drupal runs inside the 'public' schema but you can use $db_prefix
inside settings.php to define a schema for Drupal to run inside of, or
specify tables that are shared inside of a separate schema. Drupal will not
create schemas for you. In fact, the user that Drupal runs as should not be
allowed to do this. You'll need to execute the SQL below as a superuser,
replace 'username' with the username that Drupal uses to connect to
PostgreSQL, and replace 'schema_name' with a schema name you wish to use,
such as 'shared':
CREATE SCHEMA schema_name AUTHORIZATION username;
Do this for as many schemas as you need. See default.settings.php for
instructions on how to set which tables use which schemas.
+31
View File
@@ -0,0 +1,31 @@
SQLITE REQUIREMENTS
-------------------
To use SQLite with your Drupal installation, the following requirements must be
met: Server has PHP 5.2 or later with PDO, and the PDO SQLite driver must be
enabled.
SQLITE DATABASE CREATION
------------------------
The Drupal installer will create the SQLite database for you. The only
requirement is that the installer must have write permissions to the directory
where the database file resides. This directory (not just the database file) also
has to remain writeable by the web server going forward for SQLite to continue to
be able to operate.
On the "Database configuration" form in the "Database file" field, you must
supply the exact path to where you wish your database file to reside. It is
strongly suggested that you choose a path that is outside of the webroot, yet
ensure that the directory is writeable by the web server.
If you must place your database file in your webroot, you could try using the
following in your "Database file" field:
sites/default/files/.ht.sqlite
Note: The .ht in the name will tell Apache to prevent the database from being
downloaded. Please check that the file is, indeed, protected by your webserver.
If not, please consult the documentation of your webserver on how to protect a
file from downloading.
+400
View File
@@ -0,0 +1,400 @@
CONTENTS OF THIS FILE
---------------------
* Requirements and notes
* Optional server requirements
* Installation
* Building and customizing your site
* Multisite configuration
* More information
REQUIREMENTS AND NOTES
----------------------
Drupal requires:
- A web server. Apache (version 2.0 or greater) is recommended.
- PHP 5.2.4 (or greater) (http://www.php.net/).
- One of the following databases:
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
compatible drop-in replacement for MySQL.
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
Server is a backwards-compatible replacement for MySQL.
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
- SQLite 3.3.7 (or greater) (http://www.sqlite.org/).
For more detailed information about Drupal requirements, including a list of
PHP extensions and configurations that are required, see "System requirements"
(http://drupal.org/requirements) in the Drupal.org online documentation.
For detailed information on how to configure a test server environment using a
variety of operating systems and web servers, see "Local server setup"
(http://drupal.org/node/157602) in the Drupal.org online documentation.
Note that all directories mentioned in this document are always relative to the
directory of your Drupal installation, and commands are meant to be run from
this directory (except for the initial commands that create that directory).
OPTIONAL SERVER REQUIREMENTS
----------------------------
- If you want to use Drupal's "Clean URLs" feature on an Apache web server, you
will need the mod_rewrite module and the ability to use local .htaccess
files. For Clean URLs support on IIS, see "Clean URLs with IIS"
(http://drupal.org/node/3854) in the Drupal.org online documentation.
- If you plan to use XML-based services such as RSS aggregation, you will need
PHP's XML extension. This extension is enabled by default on most PHP
installations.
- To serve gzip compressed CSS and JS files on an Apache web server, you will
need the mod_headers module and the ability to use local .htaccess files.
- Some Drupal functionality (e.g., checking whether Drupal and contributed
modules need updates, RSS aggregation, etc.) require that the web server be
able to go out to the web and download information. If you want to use this
functionality, you need to verify that your hosting provider or server
configuration allows the web server to initiate outbound connections. Most web
hosting setups allow this.
INSTALLATION
------------
1. Download and extract Drupal.
You can obtain the latest Drupal release from http://drupal.org -- the files
are available in .tar.gz and .zip formats and can be extracted using most
compression tools.
To download and extract the files, on a typical Unix/Linux command line, use
the following commands (assuming you want version x.y of Drupal in .tar.gz
format):
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
tar -zxvf drupal-x.y.tar.gz
This will create a new directory drupal-x.y/ containing all Drupal files and
directories. Then, to move the contents of that directory into a directory
within your web server's document root or your public HTML directory,
continue with this command:
mv drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
2. Optionally, download a translation.
By default, Drupal is installed in English, and further languages may be
installed later. If you prefer to install Drupal in another language
initially:
- Download a translation file for the correct Drupal version and language
from the translation server: http://localize.drupal.org/translate/downloads
- Place the file into your installation profile's translations directory.
For instance, if you are using the Standard installation profile,
move the .po file into the directory:
profiles/standard/translations/
For detailed instructions, visit http://drupal.org/localize
3. Create the Drupal database.
Because Drupal stores all site information in a database, you must create
this database in order to install Drupal, and grant Drupal certain database
privileges (such as the ability to create tables). For details, consult
INSTALL.mysql.txt, INSTALL.pgsql.txt, or INSTALL.sqlite.txt. You may also
need to consult your web hosting provider for instructions specific to your
web host.
Take note of the username, password, database name, and hostname as you
create the database. You will enter this information during the install.
4. Run the install script.
To run the install script, point your browser to the base URL of your
website (e.g., http://www.example.com).
You will be guided through several screens to set up the database, add the
site maintenance account (the first user, also known as user/1), and provide
basic web site settings.
During installation, several files and directories need to be created, which
the install script will try to do automatically. However, on some hosting
environments, manual steps are required, and the install script will tell
you that it cannot proceed until you fix certain issues. This is normal and
does not indicate a problem with your server.
The most common steps you may need to perform are:
a. Missing files directory.
The install script will attempt to create a file storage directory in
the default location at sites/default/files (the location of the files
directory may be changed after Drupal is installed).
If auto-creation fails, you can make it work by changing permissions on
the sites/default directory so that the web server can create the files
directory within it for you. (If you are creating a multisite
installation, substitute the correct sites directory for sites/default;
see the Multisite Configuration section of this file, below.)
For example, on a Unix/Linux command line, you can grant everyone
(including the web server) permission to write to the sites/default
directory with this command:
chmod a+w sites/default
Be sure to set the permissions back after the installation is finished!
Sample command:
chmod go-w sites/default
Alternatively, instead of allowing the web server to create the files
directory for you as described above, you can create it yourself. Sample
commands from a Unix/Linux command line:
mkdir sites/default/files
chmod a+w sites/default/files
b. Missing settings file.
Drupal will try to automatically create a settings.php configuration file,
which is normally in the directory sites/default (to avoid problems when
upgrading, Drupal is not packaged with this file). If auto-creation fails,
you will need to create this file yourself, using the file
sites/default/default.settings.php as a template.
For example, on a Unix/Linux command line, you can make a copy of the
default.settings.php file with the command:
cp sites/default/default.settings.php sites/default/settings.php
Next, grant write privileges to the file to everyone (including the web
server) with the command:
chmod a+w sites/default/settings.php
Be sure to set the permissions back after the installation is finished!
Sample command:
chmod go-w sites/default/settings.php
c. Write permissions after install.
The install script will attempt to write-protect the settings.php file and
the sites/default directory after saving your configuration. If this
fails, you will be notified, and you can do it manually. Sample commands
from a Unix/Linux command line:
chmod go-w sites/default/settings.php
chmod go-w sites/default
5. Verify that the site is working.
When the install script finishes, you will be logged in with the site
maintenance account on a "Welcome" page. If the default Drupal theme is not
displaying properly and links on the page result in "Page Not Found" errors,
you may be experiencing problems with clean URLs. Visit
http://drupal.org/getting-started/clean-urls to troubleshoot.
6. Change file system storage settings (optional).
The files directory created in step 4 is the default file system path used to
store all uploaded files, as well as some temporary files created by
Drupal. After installation, you can modify the file system path to store
uploaded files in a different location.
It is not necessary to modify this path, but you may wish to change it if:
- Your site runs multiple Drupal installations from a single codebase (modify
the file system path of each installation to a different directory so that
uploads do not overlap between installations).
- Your site runs on a number of web servers behind a load balancer or reverse
proxy (modify the file system path on each server to point to a shared file
repository).
- You want to restrict access to uploaded files.
To modify the file system path:
a. Ensure that the new location for the path exists and is writable by the
web server. For example, to create a new directory named uploads and grant
write permissions, use the following commands on a Unix/Linux command
line:
mkdir uploads
chmod a+w uploads
b. Navigate to Administration > Configuration > Media > File system, and
enter the desired path. Note that if you want to use private file storage,
you need to first enter the path for private files and save the
configuration, and then change the "Default download method" setting and
save again.
Changing the file system path after files have been uploaded may cause
unexpected problems on an existing site. If you modify the file system path
on an existing site, remember to copy all files from the original location
to the new location.
7. Revoke documentation file permissions (optional).
Some administrators suggest making the documentation files, especially
CHANGELOG.txt, non-readable so that the exact version of Drupal you are
running is slightly more difficult to determine. If you wish to implement
this optional security measure, from a Unix/Linux command line you can use
the following command:
chmod a-r CHANGELOG.txt
Note that the example only affects CHANGELOG.txt. To completely hide all
documentation files from public view, repeat this command for each of the
Drupal documentation files in the installation directory, substituting the
name of each file for CHANGELOG.txt in the example.
For more information on setting file permissions, see "Modifying Linux,
Unix, and Mac file permissions" (http://drupal.org/node/202483) or
"Modifying Windows file permissions" (http://drupal.org/node/202491) in the
Drupal.org online documentation.
8. Set up independent "cron" maintenance jobs.
Many Drupal modules have tasks that must be run periodically, including the
Search module (building and updating the index used for keyword searching),
the Aggregator module (retrieving feeds from other sites), and the System
module (performing routine maintenance and pruning of database tables). These
tasks are known as "cron maintenance tasks", named after the Unix/Linux
"cron" utility.
When you install Drupal, its built-in cron feature is enabled, which
automatically runs the cron tasks periodically, triggered by people visiting
pages of your site. You can configure the built-in cron feature by navigating
to Administration > Configuration > System > Cron.
It is also possible to run the cron tasks independent of site visits; this is
recommended for most sites. To do this, you will need to set up an automated
process to visit the page cron.php on your site, which executes the cron
tasks.
The URL of the cron.php page requires a "cron key" to protect against
unauthorized access. Your site's cron key is automatically generated during
installation and is specific to your site. The full URL of the page, with the
cron key, is available in the "Cron maintenance tasks" section of the Status
report page at Administration > Reports > Status report.
As an example for how to set up this automated process, you can use the
crontab utility on Unix/Linux systems. The following crontab line uses the
wget command to visit the cron.php page, and runs each hour, on the hour:
0 * * * * wget -O - -q -t 1 http://example.com/cron.php?cron_key=YOURKEY
Replace the text "http://example.com/cron.php?cron_key=YOURKEY" in the
example with the full URL displayed under "Cron maintenance tasks" on the
"Status report" page.
More information about cron maintenance tasks is available at
http://drupal.org/cron, and sample cron shell scripts can be found in the
scripts/ directory. (Note that these scripts must be customized like the
above example, to add your site-specific cron key and domain name.)
BUILDING AND CUSTOMIZING YOUR SITE
----------------------------------
A new installation of Drupal defaults to a very basic configuration. To extend
your site, you use "modules" and "themes". A module is a plugin that adds
functionality to Drupal, while a theme changes the look of your site. The core
of Drupal provides several optional modules and themes, and you can download
more at http://drupal.org/project/modules and http://drupal.org/project/themes
Do not mix downloaded or custom modules and themes with Drupal's core modules
and themes. Drupal's modules and themes are located in the top-level modules and
themes directories, while the modules and themes you add to Drupal are normally
placed in the sites/all/modules and sites/all/themes directories. If you run a
multisite installation, you can also place modules and themes in the
site-specific directories -- see the Multisite Configuration section, below.
Never edit Drupal's core modules and themes; instead, use the hooks available in
the Drupal API. To modify the behavior of Drupal, develop a module as described
at http://drupal.org/developing/modules. To modify the look of Drupal, create a
subtheme as described at http://drupal.org/node/225125, or a completely new
theme as described at http://drupal.org/documentation/theme
MULTISITE CONFIGURATION
-----------------------
A single Drupal installation can host several Drupal-powered sites, each with
its own individual configuration.
Additional site configurations are created in subdirectories within the 'sites'
directory. Each subdirectory must have a 'settings.php' file, which specifies
the configuration settings. The easiest way to create additional sites is to
copy the 'default' directory and modify the 'settings.php' file as appropriate.
The new directory name is constructed from the site's URL. The configuration for
www.example.com could be in 'sites/example.com/settings.php' (note that 'www.'
should be omitted if users can access your site at http://example.com/).
Sites do not have to have a different domain. You can also use subdomains and
subdirectories for Drupal sites. For example, example.com, sub.example.com, and
sub.example.com/site3 can all be defined as independent Drupal sites. The setup
for a configuration such as this would look like the following:
sites/default/settings.php
sites/example.com/settings.php
sites/sub.example.com/settings.php
sites/sub.example.com.site3/settings.php
When searching for a site configuration (for example www.sub.example.com/site3),
Drupal will search for configuration files in the following order, using the
first configuration it finds:
sites/www.sub.example.com.site3/settings.php
sites/sub.example.com.site3/settings.php
sites/example.com.site3/settings.php
sites/www.sub.example.com/settings.php
sites/sub.example.com/settings.php
sites/example.com/settings.php
sites/default/settings.php
If you are installing on a non-standard port, the port number is treated as the
deepest subdomain. For example: http://www.example.com:8080/ could be loaded
from sites/8080.www.example.com/. The port number will be removed according to
the pattern above if no port-specific configuration is found, just like a real
subdomain.
Each site configuration can have its own site-specific modules and themes in
addition to those installed in the standard 'modules' and 'themes' directories.
To use site-specific modules or themes, simply create a 'modules' or 'themes'
directory within the site configuration directory. For example, if
sub.example.com has a custom theme and a custom module that should not be
accessible to other sites, the setup would look like this:
sites/sub.example.com/
settings.php
themes/custom_theme
modules/custom_module
NOTE: for more information about multiple virtual hosts or the configuration
settings, consult http://drupal.org/getting-started/6/install/multi-site
For more information on configuring Drupal's file system path in a multisite
configuration, see step 6 above.
MORE INFORMATION
----------------
- See the Drupal.org online documentation:
http://drupal.org/documentation
- For a list of security announcements, see the "Security advisories" page at
http://drupal.org/security (available as an RSS feed). This page also
describes how to subscribe to these announcements via e-mail.
- For information about the Drupal security process, or to find out how to
report a potential security issue to the Drupal security team, see the
"Security team" page at http://drupal.org/security-team
- For information about the wide range of available support options, visit
http://drupal.org and click on Community and Support in the top or bottom
navigation.
+106 -106
View File
@@ -1,7 +1,8 @@
Drupal core is built and maintained by the Drupal project community. Everyone is
encouraged to submit issues and changes (patches) to improve Drupal, and to
contribute in other ways -- see http://drupal.org/contribute to find out how.
contribute in other ways -- see https://www.drupal.org/contribute to find out
how.
Branch maintainers
------------------
@@ -9,154 +10,154 @@ Branch maintainers
The Drupal Core branch maintainers oversee the development of Drupal as a whole.
The branch maintainers for Drupal 7 are:
- Dries Buytaert 'dries' http://drupal.org/user/1
- Angela Byron 'webchick' http://drupal.org/user/24967
- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
Component maintainers
---------------------
The Drupal Core component maintainers oversee the development of Drupal
subsystems. See http://drupal.org/contribute/core-maintainers for more
subsystems. See https://www.drupal.org/contribute/core-maintainers for more
information on their responsibilities, and to find out how to become a component
maintainer. Current component maintainers for Drupal 7:
Ajax system
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
Base system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
Batch system
- Yves Chedemois 'yched' http://drupal.org/user/39567
- Yves Chedemois 'yched' https://www.drupal.org/u/yched
Cache system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Cron system
- Derek Wright 'dww' http://drupal.org/user/46549
- Derek Wright 'dww' https://www.drupal.org/u/dww
Database system
- Larry Garfield 'Crell' http://drupal.org/user/26398
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- MySQL driver
- Larry Garfield 'Crell' http://drupal.org/user/26398
- David Strauss 'David Strauss' http://drupal.org/user/93254
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
- PostgreSQL driver
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Josh Waihi 'fiasco' http://drupal.org/user/188162
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Josh Waihi 'fiasco' https://www.drupal.org/u/josh-waihi
- Sqlite driver
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
Database update system
- Ashok Modi 'BTMash' http://drupal.org/user/60422
- Ashok Modi 'BTMash' https://www.drupal.org/u/btmash
Entity system
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
File system
- Andrew Morton 'drewish' http://drupal.org/user/34869
- Aaron Winborn 'aaron' http://drupal.org/user/33420
- Andrew Morton 'drewish' https://www.drupal.org/u/drewish
- Aaron Winborn 'aaron' https://www.drupal.org/u/aaron
Form system
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
Image system
- Andrew Morton 'drewish' http://drupal.org/user/34869
- Nathan Haug 'quicksketch' http://drupal.org/user/35821
- Andrew Morton 'drewish' https://www.drupal.org/u/drewish
- Nathan Haug 'quicksketch' https://www.drupal.org/u/quicksketch
Install system
- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
JavaScript
- Théodore Biadala 'nod_' http://drupal.org/user/598310
- Steve De Jonghe 'seutje' http://drupal.org/user/264148
- Jesse Renée Beach 'jessebeach' http://drupal.org/user/748566
- Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
- Steve De Jonghe 'seutje' https://www.drupal.org/u/seutje
Language system
- Francesco Placella 'plach' http://drupal.org/user/183211
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Francesco Placella 'plach' https://www.drupal.org/u/plach
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Lock system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
Mail system
- ?
Markup
- Jacine Luisi 'Jacine' http://drupal.org/user/88931
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Jacine Luisi 'Jacine' https://www.drupal.org/u/jacine
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Menu system
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Path system
- Dave Reid 'davereid' http://drupal.org/user/53892
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Render system
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
Theme system
- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Joon Park 'dvessel' http://drupal.org/user/56782
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Joon Park 'dvessel' https://www.drupal.org/u/dvessel
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Token system
- Dave Reid 'davereid' http://drupal.org/user/53892
- Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
XML-RPC system
- Frederic G. Marand 'fgm' http://drupal.org/user/27985
- Frederic G. Marand 'fgm' https://www.drupal.org/u/fgm
Topic coordinators
------------------
Accessibility
- Everett Zufelt 'Everett Zufelt' http://drupal.org/user/406552
- Brandon Bowersox-Johnson 'bowersox' http://drupal.org/user/186415
- Everett Zufelt 'Everett Zufelt' https://www.drupal.org/u/everett-zufelt
- Brandon Bowersox-Johnson 'bowersox' https://www.drupal.org/u/bowersox
Documentation
- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
- Jennifer Hodgdon 'jhodgdon' https://www.drupal.org/u/jhodgdon
Translations
- Gerhard Killesreiter 'killes' http://drupal.org/user/83
- Gerhard Killesreiter 'killes' https://www.drupal.org/u/gerhard-killesreiter
User experience and usability
- Roy Scholten 'yoroy' http://drupal.org/user/41502
- Bojhan Somers 'Bojhan' http://drupal.org/user/87969
- Roy Scholten 'yoroy' https://www.drupal.org/u/yoroy
- Bojhan Somers 'Bojhan' https://www.drupal.org/u/bojhan
Node Access
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- Ken Rickard 'agentrickard' http://drupal.org/user/20975
- Jess Myrbo 'xjm' http://drupal.org/user/65776
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard
Security team
-----------------
To report a security issue, see: https://drupal.org/security-team/report-issue
To report a security issue, see: https://www.drupal.org/security-team/report-issue
The Drupal security team provides Security Advisories for vulnerabilities,
assists developers in resolving security issues, and provides security
documentation. See http://drupal.org/security-team for more information. The
security team lead is:
documentation. See https://www.drupal.org/security-team for more information.
The security team lead is:
- Michael Hess 'mlhess' https://drupal.org/user/102818
- Michael Hess 'mlhess' https://www.drupal.org/u/mlhess
Module maintainers
@@ -166,142 +167,141 @@ Aggregator module
- ?
Block module
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Blog module
- ?
Book module
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Color module
- ?
Comment module
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Contact module
- Dave Reid 'davereid' http://drupal.org/user/53892
- Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
Contextual module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Dashboard module
- ?
Database logging module
- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
Field module
- Yves Chedemois 'yched' http://drupal.org/user/39567
- Barry Jaspan 'bjaspan' http://drupal.org/user/46413
- Yves Chedemois 'yched' https://www.drupal.org/u/yched
- Barry Jaspan 'bjaspan' https://www.drupal.org/u/bjaspan
Field UI module
- Yves Chedemois 'yched' http://drupal.org/user/39567
- Yves Chedemois 'yched' https://www.drupal.org/u/yched
File module
- Aaron Winborn 'aaron' http://drupal.org/user/33420
- Aaron Winborn 'aaron' https://www.drupal.org/u/aaron
Filter module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Forum module
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
Help module
- ?
Image module
- Nathan Haug 'quicksketch' http://drupal.org/user/35821
- Nathan Haug 'quicksketch' https://www.drupal.org/u/quicksketch
Locale module
- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
Menu module
- ?
Node module
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- David Strauss 'David Strauss' http://drupal.org/user/93254
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
OpenID module
- Vojtech Kusy 'wojtha' http://drupal.org/user/56154
- Christian Schmidt 'c960657' http://drupal.org/user/216078
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Vojtech Kusy 'wojtha' https://www.drupal.org/u/wojtha
- Christian Schmidt 'c960657' https://www.drupal.org/u/c960657
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
Overlay module
- Katherine Senzee 'ksenzee' http://drupal.org/user/139855
- Katherine Senzee 'ksenzee' https://www.drupal.org/u/ksenzee
Path module
- Dave Reid 'davereid' http://drupal.org/user/53892
- Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
PHP module
- ?
Poll module
- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Profile module
- ?
RDF module
- Stéphane Corlosquet 'scor' http://drupal.org/user/52142
- Stéphane Corlosquet 'scor' https://www.drupal.org/u/scor
Search module
- Doug Green 'douggreen' http://drupal.org/user/29191
- Doug Green 'douggreen' https://www.drupal.org/u/douggreen
Shortcut module
- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
Simpletest module
- Jimmy Berry 'boombatower' http://drupal.org/user/214218
- Jimmy Berry 'boombatower' https://www.drupal.org/u/boombatower
Statistics module
- Tim Millwood 'timmillwood' http://drupal.org/user/227849
- Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood
Syslog module
- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
System module
- ?
Taxonomy module
- Jess Myrbo 'xjm' http://drupal.org/user/65776
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Benjamin Doherty 'bangpound' http://drupal.org/user/100456
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Benjamin Doherty 'bangpound' https://www.drupal.org/u/bangpound
Toolbar module
- ?
Tracker module
- David Strauss 'David Strauss' http://drupal.org/user/93254
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Translation module
- Francesco Placella 'plach' http://drupal.org/user/183211
- Francesco Placella 'plach' https://www.drupal.org/u/plach
Trigger module
- ?
Update module
- Derek Wright 'dww' http://drupal.org/user/46549
- Derek Wright 'dww' https://www.drupal.org/u/dww
User module
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- David Strauss 'David Strauss' http://drupal.org/user/93254
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Theme maintainers
-----------------
Bartik theme
- Jen Simmons 'jensimmons' http://drupal.org/user/140882
- Jeff Burns 'Jeff Burnz' http://drupal.org/user/61393
- Jen Simmons 'jensimmons' https://www.drupal.org/u/jensimmons
- Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Garland theme
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Seven theme
- Jeff Burns 'Jeff Burnz' http://drupal.org/user/61393
- Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Stark theme
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
+16 -10
View File
@@ -2,24 +2,26 @@
- Implement language aware tokens for one time login link and cancel link
https://www.drupal.org/node/1754162
- est-ce que je dois faire ce patch ???
includes/entity.inc
see https://www.drupal.org/node/1003788
//- est-ce que je dois faire ce patch ???
//includes/entity.inc
//see https://www.drupal.org/node/1003788
# Modules :
link : allow any tld (https://www.drupal.org/node/2299657#comment-11414075)
cer
contentadminrelink
entity_translation_search_api
// entity_translation_search_api
entityreference
feedback
//field_group
// field_group
filter_path_alias
flag_lists
//nodeformcols
//search_api
search_api_page
//search_api_solr
// flag_lists
// nodeformcols
// search_api
// search_api_page
// search_api_solr
termreferencetree
views
wysiwyg
@@ -27,3 +29,7 @@ views_rss_media
node_export :
- https://www.drupal.org/node/1869918
- https://www.drupal.org/node/1911638
login_tobogan (pd with field permission et donc field collection)
- https://www.drupal.org/node/1365764#comment-10286257
- logintoboggan-exempting_lt_preauth_role_from_user_permissions_js-1365764-52.patch
- interdiff-1365764-23-52-do-not-test.diff
+10
View File
@@ -64,6 +64,9 @@ following the instructions in the INTRODUCTION section at the top of this file:
Sometimes an update includes changes to default.settings.php (this will be
noted in the release notes). If that's the case, follow these steps:
- Locate your settings.php file in the /sites/* directory. (Typically
sites/default.)
- Make a backup copy of your settings.php file, with a different file name.
- Make a copy of the new default.settings.php file, and name the copy
@@ -74,6 +77,13 @@ following the instructions in the INTRODUCTION section at the top of this file:
database information, and you will also want to copy in any other
customizations you have added.
You can find the release notes for your version at
https://www.drupal.org/project/drupal. At bottom of the project page under
"Downloads" use the link for your version of Drupal to view the release
notes. If your version is not listed, use the 'View all releases' link. From
this page you can scroll down or use the filter to find your version and its
release notes.
4. Download the latest Drupal 7.x release from http://drupal.org to a
directory outside of your web root. Extract the archive and copy the files
into your Drupal directory.
+4
View File
@@ -0,0 +1,4 @@
#! /bin/bash
sudo chown -R $USER:http sites/all/modules/features/
sudo chmod -R g+w sites/all/modules/features/
+1 -1
View File
@@ -394,7 +394,7 @@ function ajax_form_callback() {
if (!empty($form_state['triggering_element'])) {
$callback = $form_state['triggering_element']['#ajax']['callback'];
}
if (!empty($callback) && function_exists($callback)) {
if (!empty($callback) && is_callable($callback)) {
$result = $callback($form, $form_state);
if (!(is_array($result) && isset($result['#type']) && $result['#type'] == 'ajax')) {
+2 -2
View File
@@ -460,10 +460,10 @@ function _batch_finished() {
if (isset($batch_set['file']) && is_file($batch_set['file'])) {
include_once DRUPAL_ROOT . '/' . $batch_set['file'];
}
if (function_exists($batch_set['finished'])) {
if (is_callable($batch_set['finished'])) {
$queue = _batch_queue($batch_set);
$operations = $queue->getAllItems();
$batch_set['finished']($batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000));
call_user_func($batch_set['finished'], $batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000));
}
}
}
+366 -54
View File
@@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.39');
define('VERSION', '7.58');
/**
* Core API compatibility.
@@ -254,8 +254,13 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
*
* Example: Sun, 06 Nov 1994 08:49:37 GMT
*
* This constant was introduced in PHP 7.0.19 and PHP 7.1.5 but needs to be
* defined by Drupal for earlier PHP versions.
*/
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
if (!defined('DATE_RFC7231')) {
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
}
/**
* Provides a caching wrapper to be used in place of large array structures.
@@ -718,6 +723,16 @@ function drupal_valid_http_host($host) {
&& preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
}
/**
* Checks whether an HTTPS request is being served.
*
* @return bool
* TRUE if the request is HTTPS, FALSE otherwise.
*/
function drupal_is_https() {
return isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
}
/**
* Sets the base URL, cookie domain, and session name from configuration.
*/
@@ -731,7 +746,7 @@ function drupal_settings_initialize() {
if (file_exists(DRUPAL_ROOT . '/' . conf_path() . '/settings.php')) {
include_once DRUPAL_ROOT . '/' . conf_path() . '/settings.php';
}
$is_https = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
$is_https = drupal_is_https();
if (isset($base_url)) {
// Parse fixed base URL from settings.php.
@@ -828,14 +843,21 @@ function drupal_settings_initialize() {
* @param $filename
* The filename of the item if it is to be set explicitly rather
* than by consulting the database.
* @param bool $trigger_error
* Whether to trigger an error when a file is missing or has unexpectedly
* moved. This defaults to TRUE, but can be set to FALSE by calling code that
* merely wants to check whether an item exists in the filesystem.
*
* @return
* The filename of the requested item or NULL if the item is not found.
*/
function drupal_get_filename($type, $name, $filename = NULL) {
function drupal_get_filename($type, $name, $filename = NULL, $trigger_error = TRUE) {
// The $files static variable will hold the locations of all requested files.
// We can be sure that any file listed in this static variable actually
// exists as all additions have gone through a file_exists() check.
// The location of files will not change during the request, so do not use
// drupal_static().
static $files = array(), $dirs = array();
static $files = array();
// Profiles are a special case: they have a fixed location and naming.
if ($type == 'profile') {
@@ -847,59 +869,41 @@ function drupal_get_filename($type, $name, $filename = NULL) {
}
if (!empty($filename) && file_exists($filename)) {
// Prime the static cache with the provided filename.
$files[$type][$name] = $filename;
}
elseif (isset($files[$type][$name])) {
// nothing
// This item had already been found earlier in the request, either through
// priming of the static cache (for example, in system_list()), through a
// lookup in the {system} table, or through a file scan (cached or not). Do
// nothing.
}
// Verify that we have an active database connection, before querying
// the database. This is required because this function is called both
// before we have a database connection (i.e. during installation) and
// when a database connection fails.
else {
// Look for the filename listed in the {system} table. Verify that we have
// an active database connection before doing so, since this function is
// called both before we have a database connection (i.e. during
// installation) and when a database connection fails.
$database_unavailable = TRUE;
try {
if (function_exists('db_query')) {
$file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
if ($file !== FALSE && file_exists(DRUPAL_ROOT . '/' . $file)) {
$files[$type][$name] = $file;
}
$database_unavailable = FALSE;
}
}
catch (Exception $e) {
// The database table may not exist because Drupal is not yet installed,
// or the database might be down. We have a fallback for this case so we
// hide the error completely.
// the database might be down, or we may have done a non-database cache
// flush while $conf['page_cache_without_database'] = TRUE and
// $conf['page_cache_invoke_hooks'] = TRUE. We have a fallback for these
// cases so we hide the error completely.
}
// Fallback to searching the filesystem if the database could not find the
// file or the file returned by the database is not found.
// Fall back to searching the filesystem if the database could not find the
// file or the file does not exist at the path returned by the database.
if (!isset($files[$type][$name])) {
// We have a consistent directory naming: modules, themes...
$dir = $type . 's';
if ($type == 'theme_engine') {
$dir = 'themes/engines';
$extension = 'engine';
}
elseif ($type == 'theme') {
$extension = 'info';
}
else {
$extension = $type;
}
if (!isset($dirs[$dir][$extension])) {
$dirs[$dir][$extension] = TRUE;
if (!function_exists('drupal_system_listing')) {
require_once DRUPAL_ROOT . '/includes/common.inc';
}
// Scan the appropriate directories for all files with the requested
// extension, not just the file we are currently looking for. This
// prevents unnecessary scans from being repeated when this function is
// called more than once in the same page request.
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
foreach ($matches as $matched_name => $file) {
$files[$type][$matched_name] = $file->uri;
}
}
$files[$type][$name] = _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable);
}
}
@@ -908,6 +912,256 @@ function drupal_get_filename($type, $name, $filename = NULL) {
}
}
/**
* Performs a cached file system scan as a fallback when searching for a file.
*
* This function looks for the requested file by triggering a file scan,
* caching the new location if the file has moved and caching the miss
* if the file is missing. If a file had been marked as missing in a previous
* file scan, or if it has been marked as moved and is still in the last known
* location, no new file scan will be performed.
*
* @param string $type
* The type of the item (theme, theme_engine, module, profile).
* @param string $name
* The name of the item for which the filename is requested.
* @param bool $trigger_error
* Whether to trigger an error when a file is missing or has unexpectedly
* moved.
* @param bool $database_unavailable
* Whether this function is being called because the Drupal database could
* not be queried for the file's location.
*
* @return
* The filename of the requested item or NULL if the item is not found.
*
* @see drupal_get_filename()
*/
function _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable) {
$file_scans = &_drupal_file_scan_cache();
$filename = NULL;
// If the cache indicates that the item is missing, or we can verify that the
// item exists in the location the cache says it exists in, use that.
if (isset($file_scans[$type][$name]) && ($file_scans[$type][$name] === FALSE || file_exists($file_scans[$type][$name]))) {
$filename = $file_scans[$type][$name];
}
// Otherwise, perform a new file scan to find the item.
else {
$filename = _drupal_get_filename_perform_file_scan($type, $name);
// Update the static cache, and mark the persistent cache for updating at
// the end of the page request. See drupal_file_scan_write_cache().
$file_scans[$type][$name] = $filename;
$file_scans['#write_cache'] = TRUE;
}
// If requested, trigger a user-level warning about the missing or
// unexpectedly moved file. If the database was unavailable, do not trigger a
// warning in the latter case, though, since if the {system} table could not
// be queried there is no way to know if the location found here was
// "unexpected" or not.
if ($trigger_error) {
$error_type = $filename === FALSE ? 'missing' : 'moved';
if ($error_type == 'missing' || !$database_unavailable) {
_drupal_get_filename_fallback_trigger_error($type, $name, $error_type);
}
}
// The cache stores FALSE for files that aren't found (to be able to
// distinguish them from files that have not yet been searched for), but
// drupal_get_filename() expects NULL for these instead, so convert to NULL
// before returning.
if ($filename === FALSE) {
$filename = NULL;
}
return $filename;
}
/**
* Returns the current list of cached file system scan results.
*
* @return
* An associative array tracking the most recent file scan results for all
* files that have had scans performed. The keys are the type and name of the
* item that was searched for, and the values can be either:
* - Boolean FALSE if the item was not found in the file system.
* - A string pointing to the location where the item was found.
*/
function &_drupal_file_scan_cache() {
$file_scans = &drupal_static(__FUNCTION__, array());
// The file scan results are stored in a persistent cache (in addition to the
// static cache) but because this function can be called before the
// persistent cache is available, we must merge any items that were found
// earlier in the page request into the results from the persistent cache.
if (!isset($file_scans['#cache_merge_done'])) {
try {
if (function_exists('cache_get')) {
$cache = cache_get('_drupal_file_scan_cache', 'cache_bootstrap');
if (!empty($cache->data)) {
// File scan results from the current request should take precedence
// over the results from the persistent cache, since they are newer.
$file_scans = drupal_array_merge_deep($cache->data, $file_scans);
}
// Set a flag to indicate that the persistent cache does not need to be
// merged again.
$file_scans['#cache_merge_done'] = TRUE;
}
}
catch (Exception $e) {
// Hide the error.
}
}
return $file_scans;
}
/**
* Performs a file system scan to search for a system resource.
*
* @param $type
* The type of the item (theme, theme_engine, module, profile).
* @param $name
* The name of the item for which the filename is requested.
*
* @return
* The filename of the requested item or FALSE if the item is not found.
*
* @see drupal_get_filename()
* @see _drupal_get_filename_fallback()
*/
function _drupal_get_filename_perform_file_scan($type, $name) {
// The location of files will not change during the request, so do not use
// drupal_static().
static $dirs = array(), $files = array();
// We have a consistent directory naming: modules, themes...
$dir = $type . 's';
if ($type == 'theme_engine') {
$dir = 'themes/engines';
$extension = 'engine';
}
elseif ($type == 'theme') {
$extension = 'info';
}
else {
$extension = $type;
}
// Check if we had already scanned this directory/extension combination.
if (!isset($dirs[$dir][$extension])) {
// Log that we have now scanned this directory/extension combination
// into a static variable so as to prevent unnecessary file scans.
$dirs[$dir][$extension] = TRUE;
if (!function_exists('drupal_system_listing')) {
require_once DRUPAL_ROOT . '/includes/common.inc';
}
// Scan the appropriate directories for all files with the requested
// extension, not just the file we are currently looking for. This
// prevents unnecessary scans from being repeated when this function is
// called more than once in the same page request.
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
foreach ($matches as $matched_name => $file) {
// Log the locations found in the file scan into a static variable.
$files[$type][$matched_name] = $file->uri;
}
}
// Return the results of the file system scan, or FALSE to indicate the file
// was not found.
return isset($files[$type][$name]) ? $files[$type][$name] : FALSE;
}
/**
* Triggers a user-level warning for missing or unexpectedly moved files.
*
* @param $type
* The type of the item (theme, theme_engine, module, profile).
* @param $name
* The name of the item for which the filename is requested.
* @param $error_type
* The type of the error ('missing' or 'moved').
*
* @see drupal_get_filename()
* @see _drupal_get_filename_fallback()
*/
function _drupal_get_filename_fallback_trigger_error($type, $name, $error_type) {
// Hide messages due to known bugs that will appear on a lot of sites.
// @todo Remove this in https://www.drupal.org/node/2383823
if (empty($name)) {
return;
}
// Make sure we only show any missing or moved file errors only once per
// request.
static $errors_triggered = array();
if (empty($errors_triggered[$type][$name][$error_type])) {
// Use _drupal_trigger_error_with_delayed_logging() here since these are
// triggered during low-level operations that cannot necessarily be
// interrupted by a watchdog() call.
if ($error_type == 'missing') {
_drupal_trigger_error_with_delayed_logging(format_string('The following @type is missing from the file system: %name. For information about how to fix this, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
}
elseif ($error_type == 'moved') {
_drupal_trigger_error_with_delayed_logging(format_string('The following @type has moved within the file system: %name. In order to fix this, clear caches or put the @type back in its original location. For more information, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
}
$errors_triggered[$type][$name][$error_type] = TRUE;
}
}
/**
* Invokes trigger_error() with logging delayed until the end of the request.
*
* This is an alternative to PHP's trigger_error() function which can be used
* during low-level Drupal core operations that need to avoid being interrupted
* by a watchdog() call.
*
* Normally, Drupal's error handler calls watchdog() in response to a
* trigger_error() call. However, this invokes hook_watchdog() which can run
* arbitrary code. If the trigger_error() happens in the middle of an
* operation such as a rebuild operation which should not be interrupted by
* arbitrary code, that could potentially break or trigger the rebuild again.
* This function protects against that by delaying the watchdog() call until
* the end of the current page request.
*
* This is an internal function which should only be called by low-level Drupal
* core functions. It may be removed in a future Drupal 7 release.
*
* @param string $error_msg
* The error message to trigger. As with trigger_error() itself, this is
* limited to 1024 bytes; additional characters beyond that will be removed.
* @param int $error_type
* (optional) The type of error. This should be one of the E_USER family of
* constants. As with trigger_error() itself, this defaults to E_USER_NOTICE
* if not provided.
*
* @see _drupal_log_error()
*/
function _drupal_trigger_error_with_delayed_logging($error_msg, $error_type = E_USER_NOTICE) {
$delay_logging = &drupal_static(__FUNCTION__, FALSE);
$delay_logging = TRUE;
trigger_error($error_msg, $error_type);
$delay_logging = FALSE;
}
/**
* Writes the file scan cache to the persistent cache.
*
* This cache stores all files marked as missing or moved after a file scan
* to prevent unnecessary file scans in subsequent requests. This cache is
* cleared in system_list_reset() (i.e. after a module/theme rebuild).
*/
function drupal_file_scan_write_cache() {
// Only write to the persistent cache if requested, and if we know that any
// data previously in the cache was successfully loaded and merged in by
// _drupal_file_scan_cache().
$file_scans = &_drupal_file_scan_cache();
if (isset($file_scans['#write_cache']) && isset($file_scans['#cache_merge_done'])) {
unset($file_scans['#write_cache']);
cache_set('_drupal_file_scan_cache', $file_scans, 'cache_bootstrap');
}
}
/**
* Loads the persistent variable table.
*
@@ -1055,7 +1309,7 @@ function drupal_page_get_cache($check_only = FALSE) {
* Determines the cacheability of the current page.
*
* @param $allow_caching
* Set to FALSE if you want to prevent this page to get cached.
* Set to FALSE if you want to prevent this page from being cached.
*
* @return
* TRUE if the current page can be cached, FALSE otherwise.
@@ -1261,7 +1515,11 @@ function drupal_page_header() {
$default_headers = array(
'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT',
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
'Cache-Control' => 'no-cache, must-revalidate',
// Prevent browsers from sniffing a response and picking a MIME type
// different from the declared content-type, since that can lead to
// XSS and other vulnerabilities.
'X-Content-Type-Options' => 'nosniff',
);
drupal_send_headers($default_headers);
}
@@ -1435,6 +1693,23 @@ function drupal_unpack($obj, $field = 'data') {
* available to code that needs localization. See st() and get_t() for
* alternatives.
*
* @section sec_context String context
* Matching source strings are normally only translated once, and the same
* translation is used everywhere that has a matching string. However, in some
* cases, a certain English source string needs to have multiple translations.
* One example of this is the string "May", which could be used as either a
* full month name or a 3-letter abbreviated month. In other languages where
* the month name for May has more than 3 letters, you would need to provide
* two different translations (one for the full name and one abbreviated), and
* the correct form would need to be chosen, depending on how "May" is being
* used. To facilitate this, the "May" string should be provided with two
* different contexts in the $options parameter when calling t(). For example:
* @code
* t('May', array(), array('context' => 'Long month name')
* t('May', array(), array('context' => 'Abbreviated month name')
* @endcode
* See https://localize.drupal.org/node/2109 for more information.
*
* @param $string
* A string containing the English string to translate.
* @param $args
@@ -1445,8 +1720,9 @@ function drupal_unpack($obj, $field = 'data') {
* An associative array of additional options, with the following elements:
* - 'langcode' (defaults to the current language): The language code to
* translate to a language other than what is used to display the page.
* - 'context' (defaults to the empty context): The context the source string
* belongs to.
* - 'context' (defaults to the empty context): A string giving the context
* that the source string belongs to. See @ref sec_context above for more
* information.
*
* @return
* The translated string.
@@ -1776,7 +2052,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
* @see theme_status_messages()
*/
function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {
if ($message) {
if ($message || $message === '0' || $message === 0) {
if (!isset($_SESSION['messages'][$type])) {
$_SESSION['messages'][$type] = array();
}
@@ -2356,6 +2632,10 @@ function _drupal_bootstrap_configuration() {
timer_start('page');
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
// Sanitize unsafe keys from the request.
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
DrupalRequestSanitizer::sanitize();
}
/**
@@ -2464,6 +2744,9 @@ function _drupal_bootstrap_database() {
// the install or upgrade process.
spl_autoload_register('drupal_autoload_class');
spl_autoload_register('drupal_autoload_interface');
if (version_compare(PHP_VERSION, '5.4') >= 0) {
spl_autoload_register('drupal_autoload_trait');
}
}
/**
@@ -2779,10 +3062,14 @@ function language_list($field = 'language') {
}
/**
* Returns the default language used on the site
* Returns the default language, as an object, or one of its properties.
*
* @param $property
* Optional property of the language object to return
* (optional) The property of the language object to return.
*
* @return
* Either the language object for the default language used on the site,
* or the property of that object named in the $property parameter.
*/
function language_default($property = NULL) {
$language = variable_get('language_default', (object) array('language' => 'en', 'name' => 'English', 'native' => 'English', 'direction' => 0, 'enabled' => 1, 'plurals' => 0, 'formula' => '', 'domain' => '', 'prefix' => '', 'weight' => 0, 'javascript' => ''));
@@ -2934,8 +3221,15 @@ function ip_address() {
// Eliminate all trusted IPs.
$untrusted = array_diff($forwarded, $reverse_proxy_addresses);
// The right-most IP is the most specific we can trust.
$ip_address = array_pop($untrusted);
if (!empty($untrusted)) {
// The right-most IP is the most specific we can trust.
$ip_address = array_pop($untrusted);
}
else {
// All IP addresses in the forwarded array are configured proxy IPs
// (and thus trusted). We take the leftmost IP.
$ip_address = array_shift($forwarded);
}
}
}
}
@@ -2952,7 +3246,9 @@ function ip_address() {
* Gets the schema definition of a table, or the whole database schema.
*
* The returned schema will include any modifications made by any
* module that implements hook_schema_alter().
* module that implements hook_schema_alter(). To get the schema without
* modifications, use drupal_get_schema_unprocessed().
*
*
* @param $table
* The name of the table. If not given, the schema of all tables is returned.
@@ -3107,6 +3403,22 @@ function drupal_autoload_class($class) {
return _registry_check_code('class', $class);
}
/**
* Confirms that a trait is available.
*
* This function is rarely called directly. Instead, it is registered as an
* spl_autoload() handler, and PHP calls it for us when necessary.
*
* @param string $trait
* The name of the trait to check or load.
*
* @return bool
* TRUE if the trait is currently available, FALSE otherwise.
*/
function drupal_autoload_trait($trait) {
return _registry_check_code('trait', $trait);
}
/**
* Checks for a resource in the registry.
*
@@ -3125,7 +3437,7 @@ function drupal_autoload_class($class) {
function _registry_check_code($type, $name = NULL) {
static $lookup_cache, $cache_update_needed;
if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name)) {
if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name) || $type == 'trait' && trait_exists($name)) {
return TRUE;
}
@@ -3158,7 +3470,7 @@ function _registry_check_code($type, $name = NULL) {
$cache_key = $type[0] . $name;
if (isset($lookup_cache[$cache_key])) {
if ($lookup_cache[$cache_key]) {
require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
include_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
}
return (bool) $lookup_cache[$cache_key];
}
@@ -3183,7 +3495,7 @@ function _registry_check_code($type, $name = NULL) {
$lookup_cache[$cache_key] = $file;
if ($file) {
require_once DRUPAL_ROOT . '/' . $file;
include_once DRUPAL_ROOT . '/' . $file;
return TRUE;
}
else {
+13 -2
View File
@@ -14,6 +14,7 @@
*
* @param $bin
* The cache bin for which the cache object should be returned.
*
* @return DrupalCacheInterface
* The cache object associated with the specified bin.
*
@@ -121,7 +122,12 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
* the administrator panel.
* - cache_path: Stores the system paths that have an alias.
* @param $expire
* (optional) One of the following values:
* (optional) Controls the maximum lifetime of this cache entry. Note that
* caches might be subject to clearing at any time, so this setting does not
* guarantee a minimum lifetime. With this in mind, the cache should not be
* used for data that must be kept during a cache clear, like sessions.
*
* Use one of the following values:
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
* explicitly told to using cache_clear_all() with a cache ID.
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
@@ -261,7 +267,12 @@ interface DrupalCacheInterface {
* 1MB in size to be stored by default. When caching large arrays or
* similar, take care to ensure $data does not exceed this size.
* @param $expire
* (optional) One of the following values:
* (optional) Controls the maximum lifetime of this cache entry. Note that
* caches might be subject to clearing at any time, so this setting does not
* guarantee a minimum lifetime. With this in mind, the cache should not be
* used for data that must be kept during a cache clear, like sessions.
*
* Use one of the following values:
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
* explicitly told to using cache_clear_all() with a cache ID.
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
+129 -41
View File
@@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') {
$params = array();
foreach ($query as $key => $value) {
$key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
$key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key);
// Recurse into children.
if (is_array($value)) {
@@ -688,6 +688,13 @@ function drupal_goto($path = '', array $options = array(), $http_response_code =
$options['fragment'] = $destination['fragment'];
}
// In some cases modules call drupal_goto(current_path()). We need to ensure
// that such a redirect is not to an external URL.
if ($path === current_path() && empty($options['external']) && url_is_external($path)) {
// Force url() to generate a non-external URL.
$options['external'] = FALSE;
}
drupal_alter('drupal_goto', $path, $options, $http_response_code);
// The 'Location' HTTP header must be absolute.
@@ -753,7 +760,8 @@ function drupal_access_denied() {
* - headers: An array containing request headers to send as name/value pairs.
* - method: A string containing the request method. Defaults to 'GET'.
* - data: A string containing the request body, formatted as
* 'param=value&param=value&...'. Defaults to NULL.
* 'param=value&param=value&...'; to generate this, use http_build_query().
* Defaults to NULL.
* - max_redirects: An integer representing how many times a redirect
* may be followed. Defaults to 3.
* - timeout: A float representing the maximum number of seconds the function
@@ -778,6 +786,8 @@ function drupal_access_denied() {
* HTTP header names are case-insensitive (RFC 2616, section 4.2), so for
* easy access the array keys are returned in lower case.
* - data: A string containing the response body that was received.
*
* @see http_build_query()
*/
function drupal_http_request($url, array $options = array()) {
// Allow an alternate HTTP client library to replace Drupal's default
@@ -1057,6 +1067,12 @@ function drupal_http_request($url, array $options = array()) {
switch ($code) {
case 200: // OK
case 201: // Created
case 202: // Accepted
case 203: // Non-Authoritative Information
case 204: // No Content
case 205: // Reset Content
case 206: // Partial Content
case 304: // Not modified
break;
case 301: // Moved permanently
@@ -1754,9 +1770,15 @@ function format_rss_item($title, $link, $description, $args = array()) {
* - 'key': element name
* - 'value': element contents
* - 'attributes': associative array of element attributes
* - 'encoded': TRUE if 'value' is already encoded
*
* In both cases, 'value' can be a simple string, or it can be another array
* with the same format as $array itself for nesting.
*
* If 'encoded' is TRUE it is up to the caller to ensure that 'value' is either
* entity-encoded or CDATA-escaped. Using this option is not recommended when
* working with untrusted user input, since failing to escape the data
* correctly has security implications.
*/
function format_xml_elements($array) {
$output = '';
@@ -1769,7 +1791,7 @@ function format_xml_elements($array) {
}
if (isset($value['value']) && $value['value'] != '') {
$output .= '>' . (is_array($value['value']) ? format_xml_elements($value['value']) : check_plain($value['value'])) . '</' . $value['key'] . ">\n";
$output .= '>' . (is_array($value['value']) ? format_xml_elements($value['value']) : (!empty($value['encoded']) ? $value['value'] : check_plain($value['value']))) . '</' . $value['key'] . ">\n";
}
else {
$output .= " />\n";
@@ -2214,20 +2236,11 @@ function url($path = NULL, array $options = array()) {
'prefix' => ''
);
// A duplicate of the code from url_is_external() to avoid needing another
// function call, since performance inside url() is critical.
// Determine whether this is an external link, but ensure that the current
// path is always treated as internal by default (to prevent external link
// injection vulnerabilities).
if (!isset($options['external'])) {
// Return an external link if $path contains an allowed absolute URL. Avoid
// calling drupal_strip_dangerous_protocols() if there is any slash (/),
// hash (#) or question_mark (?) before the colon (:) occurrence - if any -
// as this would clearly mean it is not a URL. If the path starts with 2
// slashes then it is always considered an external URL without an explicit
// protocol part.
$colonpos = strpos($path, ':');
$options['external'] = (strpos($path, '//') === 0)
|| ($colonpos !== FALSE
&& !preg_match('![/?#]!', substr($path, 0, $colonpos))
&& drupal_strip_dangerous_protocols($path) == $path);
$options['external'] = $path === $_GET['q'] ? FALSE : url_is_external($path);
}
// Preserve the original path before altering or aliasing.
@@ -2347,12 +2360,18 @@ function url($path = NULL, array $options = array()) {
*/
function url_is_external($path) {
$colonpos = strpos($path, ':');
// Avoid calling drupal_strip_dangerous_protocols() if there is any slash (/),
// hash (#) or question_mark (?) before the colon (:) occurrence - if any - as
// this would clearly mean it is not a URL. If the path starts with 2 slashes
// then it is always considered an external URL without an explicit protocol
// part.
// Some browsers treat \ as / so normalize to forward slashes.
$path = str_replace('\\', '/', $path);
// If the path starts with 2 slashes then it is always considered an external
// URL without an explicit protocol part.
return (strpos($path, '//') === 0)
// Leading control characters may be ignored or mishandled by browsers, so
// assume such a path may lead to an external location. The \p{C} character
// class matches all UTF-8 control, unassigned, and private characters.
|| (preg_match('/^\p{C}/u', $path) !== 0)
// Avoid calling drupal_strip_dangerous_protocols() if there is any slash
// (/), hash (#) or question_mark (?) before the colon (:) occurrence - if
// any - as this would clearly mean it is not a URL.
|| ($colonpos !== FALSE
&& !preg_match('![/?#]!', substr($path, 0, $colonpos))
&& drupal_strip_dangerous_protocols($path) == $path);
@@ -2637,6 +2656,15 @@ function drupal_deliver_html_page($page_callback_result) {
global $language;
drupal_add_http_header('Content-Language', $language->language);
// By default, do not allow the site to be rendered in an iframe on another
// domain, but provide a variable to override this. If the code running for
// this page request already set the X-Frame-Options header earlier, don't
// overwrite it here.
$frame_options = variable_get('x_frame_options', 'SAMEORIGIN');
if ($frame_options && is_null(drupal_get_http_header('X-Frame-Options'))) {
drupal_add_http_header('X-Frame-Options', $frame_options);
}
// Menu status constants are integers; page content is a string or array.
if (is_int($page_callback_result)) {
// @todo: Break these up into separate functions?
@@ -2751,6 +2779,7 @@ function drupal_page_footer() {
_registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
drupal_cache_system_paths();
module_implements_write_cache();
drupal_file_scan_write_cache();
system_run_automated_cron();
}
@@ -2812,11 +2841,11 @@ function drupal_map_assoc($array, $function = NULL) {
* into script execution a call such as set_time_limit(20) is made, the
* script will run for a total of 45 seconds before timing out.
*
* It also means that it is possible to decrease the total time limit if
* the sum of the new time limit and the current time spent running the
* script is inferior to the original time limit. It is inherent to the way
* set_time_limit() works, it should rather be called with an appropriate
* value every time you need to allocate a certain amount of time
* If the current time limit is not unlimited it is possible to decrease the
* total time limit if the sum of the new time limit and the current time spent
* running the script is inferior to the original time limit. It is inherent to
* the way set_time_limit() works, it should rather be called with an
* appropriate value every time you need to allocate a certain amount of time
* to execute a task than only once at the beginning of the script.
*
* Before calling set_time_limit(), we check if this function is available
@@ -2833,7 +2862,11 @@ function drupal_map_assoc($array, $function = NULL) {
*/
function drupal_set_time_limit($time_limit) {
if (function_exists('set_time_limit')) {
@set_time_limit($time_limit);
$current = ini_get('max_execution_time');
// Do not set time limit if it is currently unlimited.
if ($current != 0) {
@set_time_limit($time_limit);
}
}
}
@@ -3014,6 +3047,13 @@ function drupal_add_html_head_link($attributes, $header = FALSE) {
*/
function drupal_add_css($data = NULL, $options = NULL) {
$css = &drupal_static(__FUNCTION__, array());
$count = &drupal_static(__FUNCTION__ . '_count', 0);
// If the $css variable has been reset with drupal_static_reset(), there is
// no longer any CSS being tracked, so set the counter back to 0 also.
if (count($css) === 0) {
$count = 0;
}
// Construct the options, taking the defaults into consideration.
if (isset($options)) {
@@ -3049,7 +3089,8 @@ function drupal_add_css($data = NULL, $options = NULL) {
}
// Always add a tiny value to the weight, to conserve the insertion order.
$options['weight'] += count($css) / 1000;
$options['weight'] += $count / 1000;
$count++;
// Add the data to the CSS array depending on the type.
switch ($options['type']) {
@@ -3862,6 +3903,21 @@ function drupal_delete_file_if_stale($uri) {
* The cleaned identifier.
*/
function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '')) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['allow_css_double_underscores'] = &drupal_static(__FUNCTION__ . ':allow_css_double_underscores');
}
$allow_css_double_underscores = &$drupal_static_fast['allow_css_double_underscores'];
if (!isset($allow_css_double_underscores)) {
$allow_css_double_underscores = variable_get('allow_css_double_underscores', FALSE);
}
// Preserve BEM-style double-underscores depending on custom setting.
if ($allow_css_double_underscores) {
$filter['__'] = '__';
}
// By default, we filter using Drupal's coding standards.
$identifier = strtr($identifier, $filter);
@@ -3933,7 +3989,11 @@ function drupal_html_id($id) {
// be merged with content already on the base page. The HTML IDs must be
// unique for the fully merged content. Therefore, initialize $seen_ids to
// take into account IDs that are already in use on the base page.
$seen_ids_init = &drupal_static(__FUNCTION__ . ':init');
static $drupal_static_fast;
if (!isset($drupal_static_fast['seen_ids_init'])) {
$drupal_static_fast['seen_ids_init'] = &drupal_static(__FUNCTION__ . ':init');
}
$seen_ids_init = &$drupal_static_fast['seen_ids_init'];
if (!isset($seen_ids_init)) {
// Ideally, Drupal would provide an API to persist state information about
// prior page requests in the database, and we'd be able to add this
@@ -3978,7 +4038,10 @@ function drupal_html_id($id) {
}
}
}
$seen_ids = &drupal_static(__FUNCTION__, $seen_ids_init);
if (!isset($drupal_static_fast['seen_ids'])) {
$drupal_static_fast['seen_ids'] = &drupal_static(__FUNCTION__, $seen_ids_init);
}
$seen_ids = &$drupal_static_fast['seen_ids'];
$id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
@@ -5212,6 +5275,11 @@ function _drupal_bootstrap_full() {
fix_gpc_magic();
// Load all enabled modules
module_load_all();
// Reset drupal_alter() and module_implements() static caches as these
// include implementations for vital modules only when called early on
// in the bootstrap.
drupal_static_reset('drupal_alter');
drupal_static_reset('module_implements');
// Make sure all stream wrappers are registered.
file_get_stream_wrappers();
// Ensure mt_rand is reseeded, to prevent random values from one page load
@@ -5308,8 +5376,8 @@ function drupal_page_set_cache() {
*
* Do not call this function from a test. Use $this->cronRun() instead.
*
* @return
* TRUE if cron ran successfully.
* @return bool
* TRUE if cron ran successfully and FALSE if cron is already running.
*/
function drupal_cron_run() {
// Allow execution to continue even if the request gets canceled.
@@ -5371,12 +5439,12 @@ function drupal_cron_run() {
// Do not run if queue wants to skip.
continue;
}
$function = $info['worker callback'];
$callback = $info['worker callback'];
$end = time() + (isset($info['time']) ? $info['time'] : 15);
$queue = DrupalQueue::get($queue_name);
while (time() < $end && ($item = $queue->claimItem())) {
try {
$function($item->data);
call_user_func($callback, $item->data);
$queue->deleteItem($item);
}
catch (Exception $e) {
@@ -7083,7 +7151,8 @@ function drupal_uninstall_schema($module) {
* specification of a schema, as it was defined in a module's
* hook_schema(). No additional default values will be set,
* hook_schema_alter() is not invoked and these unprocessed
* definitions won't be cached.
* definitions won't be cached. To retrieve the schema after
* hook_schema_alter() has been invoked use drupal_get_schema().
*
* This function can be used to retrieve a schema specification in
* hook_schema(), so it allows you to derive your tables from existing
@@ -7156,6 +7225,7 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
*/
function drupal_schema_field_types($table) {
$table_schema = drupal_get_schema($table);
$field_types = array();
foreach ($table_schema['fields'] as $field_name => $field_info) {
$field_types[$field_name] = isset($field_info['type']) ? $field_info['type'] : NULL;
}
@@ -7363,7 +7433,16 @@ function drupal_write_record($table, &$record, $primary_keys = array()) {
* Information stored in a module .info file:
* - name: The real name of the module for display purposes.
* - description: A brief description of the module.
* - dependencies: An array of shortnames of other modules this module requires.
* - dependencies: An array of dependency strings. Each is in the form
* 'project:module (versions)'; with the following meanings:
* - project: (optional) Project shortname, recommended to ensure uniqueness,
* if the module is part of a project hosted on drupal.org. If omitted,
* also omit the : that follows. The project name is currently ignored by
* Drupal core but is used for automated testing.
* - module: (required) Module shortname within the project.
* - (versions): Optional version information, consisting of one or more
* comma-separated operator/value pairs or simply version numbers, which
* can contain "x" as a wildcard. Examples: (>=7.22, <7.28), (7.x-3.x).
* - package: The name of the package of modules this module belongs to.
*
* See forum.info for an example of a module .info file.
@@ -7443,7 +7522,6 @@ function drupal_parse_info_file($filename) {
*/
function drupal_parse_info_format($data) {
$info = array();
$constants = get_defined_constants();
if (preg_match_all('
@^\s* # Start at the beginning of a line, ignoring leading whitespace
@@ -7483,8 +7561,8 @@ function drupal_parse_info_format($data) {
}
// Handle PHP constants.
if (isset($constants[$value])) {
$value = $constants[$value];
if (preg_match('/^\w+$/i', $value) && defined($value)) {
$value = constant($value);
}
// Insert actual value.
@@ -7648,7 +7726,12 @@ function debug($data, $label = NULL, $print_r = FALSE) {
* Parses a dependency for comparison by drupal_check_incompatibility().
*
* @param $dependency
* A dependency string, for example 'foo (>=7.x-4.5-beta5, 3.x)'.
* A dependency string, which specifies a module dependency, and optionally
* the project it comes from and versions that are supported. Supported
* formats include:
* - 'module'
* - 'project:module'
* - 'project:module (>=version, version)'
*
* @return
* An associative array with three keys:
@@ -7663,6 +7746,12 @@ function debug($data, $label = NULL, $print_r = FALSE) {
* @see drupal_check_incompatibility()
*/
function drupal_parse_dependency($dependency) {
$value = array();
// Split out the optional project name.
if (strpos($dependency, ':')) {
list($project_name, $dependency) = explode(':', $dependency);
$value['project'] = $project_name;
}
// We use named subpatterns and support every op that version_compare
// supports. Also, op is optional and defaults to equals.
$p_op = '(?P<operation>!=|==|=|<|<=|>|>=|<>)?';
@@ -7671,7 +7760,6 @@ function drupal_parse_dependency($dependency) {
$p_major = '(?P<major>\d+)';
// By setting the minor version to x, branches can be matched.
$p_minor = '(?P<minor>(?:\d+|x)(?:-[A-Za-z]+\d+)?)';
$value = array();
$parts = explode('(', $dependency, 2);
$value['name'] = trim($parts[0]);
if (isset($parts[1])) {
+63 -7
View File
@@ -296,6 +296,20 @@ abstract class DatabaseConnection extends PDO {
*/
protected $prefixReplace = array();
/**
* List of escaped database, table, and field names, keyed by unescaped names.
*
* @var array
*/
protected $escapedNames = array();
/**
* List of escaped aliases names, keyed by unescaped aliases.
*
* @var array
*/
protected $escapedAliases = array();
function __construct($dsn, $username, $password, $driver_options = array()) {
// Initialize and prepare the connection prefix.
$this->setPrefix(isset($this->connectionOptions['prefix']) ? $this->connectionOptions['prefix'] : '');
@@ -656,7 +670,7 @@ abstract class DatabaseConnection extends PDO {
* @return DatabaseStatementInterface
* This method will return one of: the executed statement, the number of
* rows affected by the query (not the number matched), or the generated
* insert IT of the last query, depending on the value of
* insert ID of the last query, depending on the value of
* $options['return']. Typically that value will be set by default or a
* query builder and should not be set by a user. If there is an error,
* this method will return NULL and may throw an exception if
@@ -919,11 +933,14 @@ abstract class DatabaseConnection extends PDO {
* For some database drivers, it may also wrap the table name in
* database-specific escape characters.
*
* @return
* @return string
* The sanitized table name string.
*/
public function escapeTable($table) {
return preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
if (!isset($this->escapedNames[$table])) {
$this->escapedNames[$table] = preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
}
return $this->escapedNames[$table];
}
/**
@@ -933,11 +950,14 @@ abstract class DatabaseConnection extends PDO {
* For some database drivers, it may also wrap the field name in
* database-specific escape characters.
*
* @return
* @return string
* The sanitized field name string.
*/
public function escapeField($field) {
return preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
if (!isset($this->escapedNames[$field])) {
$this->escapedNames[$field] = preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
}
return $this->escapedNames[$field];
}
/**
@@ -948,11 +968,14 @@ abstract class DatabaseConnection extends PDO {
* DatabaseConnection::escapeTable(), this doesn't allow the period (".")
* because that is not allowed in aliases.
*
* @return
* @return string
* The sanitized field name string.
*/
public function escapeAlias($field) {
return preg_replace('/[^A-Za-z0-9_]+/', '', $field);
if (!isset($this->escapedAliases[$field])) {
$this->escapedAliases[$field] = preg_replace('/[^A-Za-z0-9_]+/', '', $field);
}
return $this->escapedAliases[$field];
}
/**
@@ -1313,6 +1336,39 @@ abstract class DatabaseConnection extends PDO {
* also larger than the $existing_id if one was passed in.
*/
abstract public function nextId($existing_id = 0);
/**
* Checks whether utf8mb4 support is configurable in settings.php.
*
* @return bool
*/
public function utf8mb4IsConfigurable() {
// Since 4 byte UTF-8 is not supported by default, there is nothing to
// configure.
return FALSE;
}
/**
* Checks whether utf8mb4 support is currently active.
*
* @return bool
*/
public function utf8mb4IsActive() {
// Since 4 byte UTF-8 is not supported by default, there is nothing to
// activate.
return FALSE;
}
/**
* Checks whether utf8mb4 support is available on the current database system.
*
* @return bool
*/
public function utf8mb4IsSupported() {
// By default we assume that the database backend may not support 4 byte
// UTF-8.
return FALSE;
}
}
/**
+55 -6
View File
@@ -28,6 +28,12 @@ class DatabaseConnection_mysql extends DatabaseConnection {
$this->connectionOptions = $connection_options;
$charset = 'utf8';
// Check if the charset is overridden to utf8mb4 in settings.php.
if ($this->utf8mb4IsActive()) {
$charset = 'utf8mb4';
}
// The DSN should use either a socket or a host/port.
if (isset($connection_options['unix_socket'])) {
$dsn = 'mysql:unix_socket=' . $connection_options['unix_socket'];
@@ -39,7 +45,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// Character set is added to dsn to ensure PDO uses the proper character
// set when escaping. This has security implications. See
// https://www.drupal.org/node/1201452 for further discussion.
$dsn .= ';charset=utf8';
$dsn .= ';charset=' . $charset;
$dsn .= ';dbname=' . $connection_options['database'];
// Allow PDO options to be overridden.
$connection_options += array(
@@ -51,6 +57,11 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// Because MySQL's prepared statements skip the query cache, because it's dumb.
PDO::ATTR_EMULATE_PREPARES => TRUE,
);
if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) {
// An added connection option in PHP 5.5.21+ to optionally limit SQL to a
// single statement like mysqli.
$connection_options['pdo'] += array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => FALSE);
}
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
@@ -58,10 +69,10 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8.
if (!empty($connection_options['collation'])) {
$this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
$this->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']);
}
else {
$this->exec('SET NAMES utf8');
$this->exec('SET NAMES ' . $charset);
}
// Set MySQL init_commands if not already defined. Default Drupal's MySQL
@@ -76,10 +87,12 @@ class DatabaseConnection_mysql extends DatabaseConnection {
'init_commands' => array(),
);
$connection_options['init_commands'] += array(
'sql_mode' => "SET sql_mode = 'ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
'sql_mode' => "SET sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
);
// Set connection options.
$this->exec(implode('; ', $connection_options['init_commands']));
// Execute initial commands.
foreach ($connection_options['init_commands'] as $sql) {
$this->exec($sql);
}
}
public function __destruct() {
@@ -199,6 +212,42 @@ class DatabaseConnection_mysql extends DatabaseConnection {
}
}
}
public function utf8mb4IsConfigurable() {
return TRUE;
}
public function utf8mb4IsActive() {
return isset($this->connectionOptions['charset']) && $this->connectionOptions['charset'] === 'utf8mb4';
}
public function utf8mb4IsSupported() {
// Ensure that the MySQL driver supports utf8mb4 encoding.
$version = $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
if (strpos($version, 'mysqlnd') !== FALSE) {
// The mysqlnd driver supports utf8mb4 starting at version 5.0.9.
$version = preg_replace('/^\D+([\d.]+).*/', '$1', $version);
if (version_compare($version, '5.0.9', '<')) {
return FALSE;
}
}
else {
// The libmysqlclient driver supports utf8mb4 starting at version 5.5.3.
if (version_compare($version, '5.5.3', '<')) {
return FALSE;
}
}
// Ensure that the MySQL server supports large prefixes and utf8mb4.
try {
$this->query("CREATE TABLE {drupal_utf8mb4_test} (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB");
}
catch (Exception $e) {
return FALSE;
}
$this->query("DROP TABLE {drupal_utf8mb4_test}");
return TRUE;
}
}
+11 -3
View File
@@ -39,8 +39,8 @@ class DatabaseSchema_mysql extends DatabaseSchema {
$info['table'] = substr($table, ++$pos);
}
else {
$db_info = Database::getConnectionInfo();
$info['database'] = $db_info[$this->connection->getTarget()]['database'];
$db_info = $this->connection->getConnectionOptions();
$info['database'] = $db_info['database'];
$info['table'] = $table;
}
return $info;
@@ -81,7 +81,8 @@ class DatabaseSchema_mysql extends DatabaseSchema {
// Provide defaults if needed.
$table += array(
'mysql_engine' => 'InnoDB',
'mysql_character_set' => 'utf8',
// Allow the default charset to be overridden in settings.php.
'mysql_character_set' => $this->connection->utf8mb4IsActive() ? 'utf8mb4' : 'utf8',
);
$sql = "CREATE TABLE {" . $name . "} (\n";
@@ -109,6 +110,13 @@ class DatabaseSchema_mysql extends DatabaseSchema {
$sql .= ' COLLATE ' . $info['collation'];
}
// The row format needs to be either DYNAMIC or COMPRESSED in order to allow
// for the innodb_large_prefix setting to take effect, see
// https://dev.mysql.com/doc/refman/5.6/en/create-table.html
if ($this->connection->utf8mb4IsActive()) {
$sql .= ' ROW_FORMAT=DYNAMIC';
}
// Add table comment.
if (!empty($table['description'])) {
$sql .= ' COMMENT ' . $this->prepareComment($table['description'], self::COMMENT_MAX_TABLE);
+14 -6
View File
@@ -11,7 +11,7 @@
*/
/**
* The name by which to obtain a lock for retrive the next insert id.
* The name by which to obtain a lock for retrieving the next insert id.
*/
define('POSTGRESQL_NEXTID_LOCK', 1000);
@@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
$connection_options['pdo'] += array(
// Prepared statements are most effective for performance when queries
// are recycled (used several times). However, if they are not re-used,
// prepared statements become ineffecient. Since most of Drupal's
// prepared statements become inefficient. Since most of Drupal's
// prepared queries are not re-used, it should be faster to emulate
// the preparation than to actually ready statements for re-use. If in
// doubt, reset to FALSE and measure performance.
@@ -175,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
}
/**
* Retrive a the next id in a sequence.
* Retrieve the next id in a sequence.
*
* PostgreSQL has built in sequences. We'll use these instead of inserting
* and updating a sequences table.
*/
public function nextId($existing = 0) {
// Retrive the name of the sequence. This information cannot be cached
// Retrieve the name of the sequence. This information cannot be cached
// because the prefix may change, for example, like it does in simpletests.
$sequence_name = $this->makeSequenceName('sequences', 'value');
@@ -194,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
}
// PostgreSQL advisory locks are simply locks to be used by an
// application such as Drupal. This will prevent other Drupal proccesses
// application such as Drupal. This will prevent other Drupal processes
// from altering the sequence while we are.
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
@@ -209,13 +209,21 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
// Reset the sequence to a higher value than the existing id.
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
// Retrive the next id. We know this will be as high as we want it.
// Retrieve the next id. We know this will be as high as we want it.
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
return $id;
}
public function utf8mb4IsActive() {
return TRUE;
}
public function utf8mb4IsSupported() {
return TRUE;
}
}
/**
+1 -1
View File
@@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
LANGUAGE \'sql\''
);
// Using || to concatenate in Drupal is not recommeneded because there are
// Using || to concatenate in Drupal is not recommended because there are
// database drivers for Drupal that do not support the syntax, however
// they do support CONCAT(item1, item2) which we can replicate in
// PostgreSQL. PostgreSQL requires the function to be defined for each
+2 -2
View File
@@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery {
}
// If a table loads all fields, it can not be added again. It would
// result in an ambigious alias error because that field would be loaded
// result in an ambiguous alias error because that field would be loaded
// twice: Once through table_alias.* and once directly. If the field
// actually belongs to a different table, it must be added manually.
foreach ($this->tables as $table) {
@@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery {
}
// If $field contains an characters which are not allowed in a field name
// it is considered an expression, these can't be handeld automatically
// it is considered an expression, these can't be handled automatically
// either.
if ($this->connection->escapeField($field) != $field) {
return $return;
+3 -3
View File
@@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface {
/**
* Executes the DELETE query.
*
* @return
* The return value is dependent on the database connection.
* @return int
* The number of rows affected by the delete query.
*/
public function execute() {
$values = array();
@@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
* instead. MergeQuery::fields() can also be called which calls both of these
* methods as the common case is to use the same column-value pairs for both
* INSERT and UPDATE. However, this is not mandatory. Another convinient
* INSERT and UPDATE. However, this is not mandatory. Another convenient
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
* condition and the INSERT query part.
*
+8 -2
View File
@@ -92,7 +92,8 @@ require_once dirname(__FILE__) . '/query.inc';
* specification). Each specification is an array containing the name of
* the referenced table ('table'), and an array of column mappings
* ('columns'). Column mappings are defined by key pairs ('source_column' =>
* 'referenced_column').
* 'referenced_column'). This key is for documentation purposes only; foreign
* keys are not created in the database, nor are they enforced by Drupal.
* - 'indexes': An associative array of indexes ('indexname' =>
* specification). Each specification is an array of one or more
* key column specifiers (see below) that form an index on the
@@ -144,6 +145,8 @@ require_once dirname(__FILE__) . '/query.inc';
* 'unique keys' => array(
* 'vid' => array('vid'),
* ),
* // For documentation purposes only; foreign keys are not created in the
* // database.
* 'foreign keys' => array(
* 'node_revision' => array(
* 'table' => 'node_revision',
@@ -161,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc';
* @see drupal_install_schema()
*/
/**
* Base class for database schema definitions.
*/
abstract class DatabaseSchema implements QueryPlaceholderInterface {
protected $connection;
@@ -288,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
$info = $this->connection->getConnectionOptions();
// Retrive the table name and schema
// Retrieve the table name and schema
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
$condition = new DatabaseCondition('AND');
+15
View File
@@ -1231,6 +1231,21 @@ class SelectQuery extends Query implements SelectQueryInterface {
// Modules may alter all queries or only those having a particular tag.
if (isset($this->alterTags)) {
// Many contrib modules assume that query tags used for access-checking
// purposes follow the pattern $entity_type . '_access'. But this is
// not the case for taxonomy terms, since core used to add term_access
// instead of taxonomy_term_access to its queries. Provide backwards
// compatibility by adding both tags here instead of attempting to fix
// all contrib modules in a coordinated effort.
// TODO:
// - Extract this mechanism into a hook as part of a public (non-security)
// issue.
// - Emit E_USER_DEPRECATED if term_access is used.
// https://www.drupal.org/node/2575081
$term_access_tags = array('term_access' => 1, 'taxonomy_term_access' => 1);
if (array_intersect_key($this->alterTags, $term_access_tags)) {
$this->alterTags += $term_access_tags;
}
$hooks = array('query');
foreach ($this->alterTags as $tag => $value) {
$hooks[] = 'query_' . $tag;
+8
View File
@@ -378,6 +378,14 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
}
}
public function utf8mb4IsActive() {
return TRUE;
}
public function utf8mb4IsSupported() {
return TRUE;
}
}
/**
-2
View File
@@ -14,8 +14,6 @@ class DatabaseTasks_sqlite extends DatabaseTasks {
/**
* Minimum engine version.
*
* @todo: consider upping to 3.6.8 in Drupal 8 to get SAVEPOINT support.
*/
public function minimumVersion() {
return '3.3.7';
+6 -7
View File
@@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery {
/**
* SQLite specific implementation of DeleteQuery.
*
* When the WHERE is omitted from a DELETE statement and the table being deleted
* has no triggers, SQLite uses an optimization to erase the entire table content
* without having to visit each row of the table individually.
*
* Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted
* by that optimized "truncate" optimization.
*/
class DeleteQuery_sqlite extends DeleteQuery {
public function execute() {
// When the WHERE is omitted from a DELETE statement and the table being
// deleted has no triggers, SQLite uses an optimization to erase the entire
// table content without having to visit each row of the table individually.
// Prior to SQLite 3.6.5, SQLite does not return the actual number of rows
// deleted by that optimized "truncate" optimization. But we want to return
// the number of rows affected, so we calculate it directly.
if (!count($this->condition)) {
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
parent::execute();
+1 -1
View File
@@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
// database. So the syntax '...RENAME TO database.table' would fail.
// So we must determine the full table name here rather than surrounding
// the table with curly braces incase the db_prefix contains a reference
// to a database outside of our existsing database.
// to a database outside of our existing database.
$info = $this->getPrefixInfo($new_name);
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
+10 -10
View File
@@ -12,11 +12,6 @@ function system_default_date_formats() {
$formats = array();
// Short date formats.
$formats[] = array(
'type' => 'short',
'format' => 'Y-m-d H:i',
'locales' => array(),
);
$formats[] = array(
'type' => 'short',
'format' => 'm/d/Y - H:i',
@@ -37,6 +32,11 @@ function system_default_date_formats() {
'format' => 'd.m.Y - H:i',
'locales' => array('de-ch', 'de-de', 'de-lu', 'fi-fi', 'fr-ch', 'is-is', 'pl-pl', 'ro-ro', 'ru-ru'),
);
$formats[] = array(
'type' => 'short',
'format' => 'Y-m-d H:i',
'locales' => array(),
);
$formats[] = array(
'type' => 'short',
'format' => 'm/d/Y - g:ia',
@@ -84,11 +84,6 @@ function system_default_date_formats() {
);
// Medium date formats.
$formats[] = array(
'type' => 'medium',
'format' => 'D, Y-m-d H:i',
'locales' => array(),
);
$formats[] = array(
'type' => 'medium',
'format' => 'D, m/d/Y - H:i',
@@ -104,6 +99,11 @@ function system_default_date_formats() {
'format' => 'D, Y/m/d - H:i',
'locales' => array('en-ca', 'fr-ca', 'no-no', 'sv-se'),
);
$formats[] = array(
'type' => 'medium',
'format' => 'D, Y-m-d H:i',
'locales' => array(),
);
$formats[] = array(
'type' => 'medium',
'format' => 'F j, Y - H:i',
+34 -10
View File
@@ -446,7 +446,7 @@ class EntityFieldQueryException extends Exception {}
*
* This class allows finding entities based on entity properties (for example,
* node->changed), field values, and generic entity meta data (bundle,
* entity type, entity id, and revision ID). It is not possible to query across
* entity type, entity ID, and revision ID). It is not possible to query across
* multiple entity types. For example, there is no facility to find published
* nodes written by users created in the last hour, as this would require
* querying both node->status and user->created.
@@ -688,14 +688,36 @@ class EntityFieldQuery {
* @param $field
* Either a field name or a field array.
* @param $column
* The column that should hold the value to be matched.
* The column that should hold the value to be matched, defined in the
* hook_field_schema() of this field. If this is omitted then all of the
* other parameters are ignored, except $field, and this call will just be
* adding a condition that says that the field has a value, rather than
* testing the value itself.
* @param $value
* The value to test the column value against.
* The value to test the column value against. In most cases, this is a
* scalar. For more complex options, it is an array. The meaning of each
* element in the array is dependent on $operator.
* @param $operator
* The operator to be used to test the given value.
* The operator to be used to test the given value. The possible values are:
* - '=', '<>', '>', '>=', '<', '<=', 'STARTS_WITH', 'CONTAINS': These
* operators expect $value to be a literal of the same type as the
* column.
* - 'IN', 'NOT IN': These operators expect $value to be an array of
* literals of the same type as the column.
* - 'BETWEEN': This operator expects $value to be an array of two literals
* of the same type as the column.
* The operator can be omitted, and will default to 'IN' if the value is an
* array, or to '=' otherwise.
* @param $delta_group
* An arbitrary identifier: conditions in the same group must have the same
* $delta_group.
* $delta_group. For example, let's presume a multivalue field which has
* two columns, 'color' and 'shape', and for entity ID 1, there are two
* values: red/square and blue/circle. Entity ID 1 does not have values
* corresponding to 'red circle'; however if you pass 'red' and 'circle' as
* conditions, it will appear in the results -- by default queries will run
* against any combination of deltas. By passing the conditions with the
* same $delta_group it will ensure that only values attached to the same
* delta are matched, and entity 1 would then be excluded from the results.
* @param $language_group
* An arbitrary identifier: conditions in the same group must have the same
* $language_group.
@@ -770,9 +792,11 @@ class EntityFieldQuery {
* @param $field
* Either a field name or a field array.
* @param $column
* A column defined in the hook_field_schema() of this field. If this is
* omitted then the query will find only entities that have data in this
* field, using the entity and property conditions if there are any.
* The column that should hold the value to be matched, defined in the
* hook_field_schema() of this field. If this is omitted then all of the
* other parameters are ignored, except $field, and this call will just be
* adding a condition that says that the field has a value, rather than
* testing the value itself.
* @param $value
* The value to test the column value against. In most cases, this is a
* scalar. For more complex options, it is an array. The meaning of each
@@ -791,10 +815,10 @@ class EntityFieldQuery {
* @param $delta_group
* An arbitrary identifier: conditions in the same group must have the same
* $delta_group. For example, let's presume a multivalue field which has
* two columns, 'color' and 'shape', and for entity id 1, there are two
* two columns, 'color' and 'shape', and for entity ID 1, there are two
* values: red/square and blue/circle. Entity ID 1 does not have values
* corresponding to 'red circle', however if you pass 'red' and 'circle' as
* conditions, it will appear in the results - by default queries will run
* conditions, it will appear in the results -- by default queries will run
* against any combination of deltas. By passing the conditions with the
* same $delta_group it will ensure that only values attached to the same
* delta are matched, and entity 1 would then be excluded from the results.
+13 -4
View File
@@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
_drupal_log_error(array(
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
// The standard PHP error handler considers that the error messages
// are HTML. We mimick this behavior here.
// are HTML. We mimic this behavior here.
'!message' => filter_xss_admin($message),
'%function' => $caller['function'],
'%file' => $caller['file'],
@@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) {
return array(
'%type' => get_class($exception),
// The standard PHP exception handler considers that the exception message
// is plain-text. We mimick this behavior here.
// is plain-text. We mimic this behavior here.
'!message' => check_plain($message),
'%function' => $caller['function'],
'%file' => $caller['file'],
@@ -199,7 +199,16 @@ function _drupal_log_error($error, $fatal = FALSE) {
$number++;
}
watchdog('php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
// Log the error immediately, unless this is a non-fatal error which has been
// triggered via drupal_trigger_error_with_delayed_logging(); in that case
// trigger it in a shutdown function. Fatal errors are always triggered
// immediately since for a fatal error the page request will end here anyway.
if (!$fatal && drupal_static('_drupal_trigger_error_with_delayed_logging')) {
drupal_register_shutdown_function('watchdog', 'php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
}
else {
watchdog('php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
}
if ($fatal) {
drupal_add_http_header('Status', '500 Service unavailable (with message)');
@@ -224,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
}
else {
// Display the message if the current error reporting level allows this type
// of message to be displayed, and unconditionnaly in update.php.
// of message to be displayed, and unconditionally in update.php.
if (error_displayable($error)) {
$class = 'error';
+31 -6
View File
@@ -273,7 +273,9 @@ function file_default_scheme() {
* The normalized URI.
*/
function file_stream_wrapper_uri_normalize($uri) {
$scheme = file_uri_scheme($uri);
// Inline file_uri_scheme() function call for performance reasons.
$position = strpos($uri, '://');
$scheme = $position ? substr($uri, 0, $position) : FALSE;
if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
$target = file_uri_target($uri);
@@ -533,7 +535,18 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
EOF;
if ($private) {
$lines = "Deny from all\n\n" . $lines;
$lines = <<<EOF
# Deny all requests from Apache 2.4+.
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# Deny all requests from Apache 2.0-2.2.
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
EOF
. "\n\n" . $lines;
}
return $lines;
@@ -887,7 +900,6 @@ function file_valid_uri($uri) {
*/
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
$original_source = $source;
$original_destination = $destination;
// Assert that the source file actually exists.
if (!file_exists($source)) {
@@ -1602,6 +1614,20 @@ function file_save_upload($form_field_name, $validators = array(), $destination
// If we made it this far it's safe to record this file in the database.
if ($file = file_save($file)) {
// Track non-public files in the session if they were uploaded by an
// anonymous user. This allows modules such as the File module to only
// grant view access to the specific anonymous user who uploaded the file.
// See file_file_download().
// The 'file_public_schema' variable is used to allow other publicly
// accessible file schemes to be treated the same as the public:// scheme
// provided by Drupal core and to avoid adding unnecessary data to the
// session (and the resulting bypass of the page cache) in those cases. For
// security reasons, only schemes that are completely publicly accessible,
// with no download restrictions, should be added to this variable. See
// file_managed_file_value().
if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) {
$_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid;
}
// Add file to the cache.
$upload_cache[$form_field_name] = $file;
return $file;
@@ -1785,7 +1811,7 @@ function file_validate_is_image(stdClass $file) {
/**
* Verifies that image dimensions are within the specified maximum and minimum.
*
* Non-image files will be ignored. If a image toolkit is available the image
* Non-image files will be ignored. If an image toolkit is available the image
* will be scaled to fit within the desired maximum dimensions.
*
* @param $file
@@ -2022,7 +2048,7 @@ function file_download() {
*
* @see file_transfer()
* @see file_download_access()
* @see hook_file_downlaod()
* @see hook_file_download()
*/
function file_download_headers($uri) {
// Let other modules provide headers and control access to the file.
@@ -2551,7 +2577,6 @@ function file_directory_temp() {
* An associative array of headers, as expected by file_transfer().
*/
function file_get_content_headers($file) {
$name = mime_header_encode($file->filename);
$type = mime_header_encode($file->filemime);
return array(
+21 -11
View File
@@ -105,7 +105,8 @@
* generate the same form (or very similar forms) using different $form_ids
* can implement hook_forms(), which maps different $form_id values to the
* proper form constructor function. Examples may be found in node_forms(),
* and search_forms().
* and search_forms(). hook_forms() can also be used to define forms in
* classes.
* @param ...
* Any additional arguments are passed on to the functions called by
* drupal_get_form(), including the unique form constructor function. For
@@ -809,7 +810,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
}
if (isset($form_definition['callback'])) {
$callback = $form_definition['callback'];
$form_state['build_info']['base_form_id'] = $callback;
$form_state['build_info']['base_form_id'] = isset($form_definition['base_form_id']) ? $form_definition['base_form_id'] : $callback;
}
// In case $form_state['wrapper_callback'] is not defined already, we also
// allow hook_forms() to define one.
@@ -830,7 +831,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
// the actual form builder function ($callback) expects. This allows for
// pre-populating a form with common elements for certain forms, such as
// back/next/save buttons in multi-step form wizards. See drupal_build_form().
if (isset($form_state['wrapper_callback']) && function_exists($form_state['wrapper_callback'])) {
if (isset($form_state['wrapper_callback']) && is_callable($form_state['wrapper_callback'])) {
$form = call_user_func_array($form_state['wrapper_callback'], $args);
// Put the prepopulated $form into $args.
$args[0] = $form;
@@ -1175,7 +1176,7 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
// If the session token was set by drupal_prepare_form(), ensure that it
// matches the current user's session. This is duplicate to code in
// form_builder() but left to protect any custom form handling code.
if (isset($form['#token'])) {
if (!empty($form['#token'])) {
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token']) || !empty($form_state['invalid_token'])) {
_drupal_invalid_token_set_form_error();
// Stop here and don't run any further validation handlers, because they
@@ -1836,7 +1837,7 @@ function form_builder($form_id, &$element, &$form_state) {
// If the session token was set by drupal_prepare_form(), ensure that it
// matches the current user's session.
$form_state['invalid_token'] = FALSE;
if (isset($element['#token'])) {
if (!empty($element['#token'])) {
if (empty($form_state['input']['form_token']) || !drupal_valid_token($form_state['input']['form_token'], $element['#token'])) {
// Set an early form error to block certain input processing since that
// opens the door for CSRF vulnerabilities.
@@ -2571,7 +2572,7 @@ function form_type_select_value($element, $input = FALSE) {
* for this element. Return nothing to use the default.
*/
function form_type_textarea_value($element, $input = FALSE) {
if ($input !== FALSE) {
if ($input !== FALSE && $input !== NULL) {
// This should be a string, but allow other scalars since they might be
// valid input in programmatic form submissions.
return is_scalar($input) ? (string) $input : '';
@@ -3028,7 +3029,7 @@ function form_process_password_confirm($element) {
function password_confirm_validate($element, &$element_state) {
$pass1 = trim($element['pass1']['#value']);
$pass2 = trim($element['pass2']['#value']);
if (!empty($pass1) || !empty($pass2)) {
if (strlen($pass1) > 0 || strlen($pass2) > 0) {
if (strcmp($pass1, $pass2)) {
form_error($element, t('The specified passwords do not match.'));
}
@@ -3385,9 +3386,12 @@ function form_process_container($element, &$form_state) {
/**
* Returns HTML to wrap child elements in a container.
*
* Used for grouped form items. Can also be used as a #theme_wrapper for any
* Used for grouped form items. Can also be used as a theme wrapper for any
* renderable element, to surround it with a <div> and add attributes such as
* classes or an HTML id.
* classes or an HTML ID.
*
* See the @link forms_api_reference.html Form API reference @endlink for more
* information on the #theme_wrappers render array property.
*
* @param $variables
* An associative array containing:
@@ -3542,6 +3546,7 @@ function form_process_tableselect($element) {
'#return_value' => $key,
'#default_value' => isset($value[$key]) ? $key : NULL,
'#attributes' => $element['#attributes'],
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
);
}
else {
@@ -3979,7 +3984,12 @@ function form_process_autocomplete($element) {
// browser interpreting the path plus search string as an actual file.
$current_clean_url = isset($GLOBALS['conf']['clean_url']) ? $GLOBALS['conf']['clean_url'] : NULL;
$GLOBALS['conf']['clean_url'] = 0;
$element['#autocomplete_input']['#url_value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
// Force the script path to 'index.php', in case the server is not
// configured to find it automatically. Normally it is the responsibility
// of the site to do this themselves using hook_url_outbound_alter() (see
// url()) but since this code is forcing non-clean URLs on sites that don't
// normally use them, it is done here instead.
$element['#autocomplete_input']['#url_value'] = url($element['#autocomplete_path'], array('absolute' => TRUE, 'script' => 'index.php'));
$GLOBALS['conf']['clean_url'] = $current_clean_url;
}
return $element;
@@ -4484,7 +4494,7 @@ function element_validate_number($element, &$form_state) {
*
* Sample callback_batch_finished():
* @code
* function batch_test_finished($success, $results, $operations) {
* function my_finished_callback($success, $results, $operations) {
* // The 'success' parameter means no fatal PHP errors were detected. All
* // other error management should be handled using 'results'.
* if ($success) {
+12 -1
View File
@@ -809,6 +809,13 @@ function install_system_module(&$install_state) {
variable_set('install_profile_modules', array_diff($modules, array('system')));
$install_state['database_tables_exist'] = TRUE;
// Prevent the hook_requirements() check from telling us to convert the
// database to utf8mb4.
$connection = Database::getConnection();
if ($connection->utf8mb4IsConfigurable() && $connection->utf8mb4IsActive()) {
variable_set('drupal_all_databases_are_utf8mb4', TRUE);
}
}
/**
@@ -1590,7 +1597,9 @@ function install_finished(&$install_state) {
}
/**
* Batch callback for batch installation of modules.
* Implements callback_batch_operation().
*
* Performs batch installation of modules.
*/
function _install_module_batch($module, $module_name, &$context) {
// Install and enable the module right away, so that the module will be
@@ -1603,6 +1612,8 @@ function _install_module_batch($module, $module_name, &$context) {
}
/**
* Implements callback_batch_finished().
*
* 'Finished' callback for module installation batch.
*/
function _install_profile_modules_finished($success, $results, $operations) {
+2 -1
View File
@@ -750,7 +750,7 @@ function drupal_install_system() {
/**
* Uninstalls a given list of disabled modules.
*
* @param array $module_list
* @param string[] $module_list
* The modules to uninstall. It is the caller's responsibility to ensure that
* all modules in this list have already been disabled before this function
* is called.
@@ -769,6 +769,7 @@ function drupal_install_system() {
* included in $module_list).
*
* @see module_disable()
* @see module_enable()
*/
function drupal_uninstall_modules($module_list = array(), $uninstall_dependents = TRUE) {
if ($uninstall_dependents) {
+48 -3
View File
@@ -435,6 +435,13 @@ function locale_language_url_rewrite_url(&$path, &$options) {
switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
if ($options['language']->domain) {
// Save the original base URL. If it contains a port, we need to
// retain it below.
if (!empty($options['base_url'])) {
// The colon in the URL scheme messes up the port checking below.
$normalized_base_url = str_replace(array('https://', 'http://'), '', $options['base_url']);
}
// Ask for an absolute URL with our modified base_url.
global $is_https;
$url_scheme = ($is_https) ? 'https://' : 'http://';
@@ -449,6 +456,19 @@ function locale_language_url_rewrite_url(&$path, &$options) {
// Apply the appropriate protocol to the URL.
$options['base_url'] = $url_scheme . $host;
// In case either the original base URL or the HTTP host contains a
// port, retain it.
$http_host = $_SERVER['HTTP_HOST'];
if (isset($normalized_base_url) && strpos($normalized_base_url, ':') !== FALSE) {
list($host, $port) = explode(':', $normalized_base_url);
$options['base_url'] .= ':' . $port;
}
elseif (strpos($http_host, ':') !== FALSE) {
list($host, $port) = explode(':', $http_host);
$options['base_url'] .= ':' . $port;
}
if (isset($options['https']) && variable_get('https', FALSE)) {
if ($options['https'] === TRUE) {
$options['base_url'] = str_replace('http://', 'https://', $options['base_url']);
@@ -523,6 +543,22 @@ function locale_language_url_rewrite_session(&$path, &$options) {
* possible attack vector (img).
*/
function locale_string_is_safe($string) {
// Some strings have tokens in them. For tokens in the first part of href or
// src HTML attributes, filter_xss() removes part of the token, the part
// before the first colon. filter_xss() assumes it could be an attempt to
// inject javascript. When filter_xss() removes part of tokens, it causes the
// string to not be translatable when it should be translatable. See
// LocaleStringIsSafeTest::testLocaleStringIsSafe().
//
// We can recognize tokens since they are wrapped with brackets and are only
// composed of alphanumeric characters, colon, underscore, and dashes. We can
// be sure these strings are safe to strip out before the string is checked in
// filter_xss() because no dangerous javascript will match that pattern.
//
// @todo Do not strip out the token. Fix filter_xss() to not incorrectly
// alter the string. https://www.drupal.org/node/2372127
$string = preg_replace('/\[[a-z0-9_-]+(:[a-z0-9_-]+)+\]/i', '', $string);
return decode_entities($string) == decode_entities(filter_xss($string, array('a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var')));
}
@@ -631,9 +667,6 @@ function locale_add_language($langcode, $name = NULL, $native = NULL, $direction
* translations).
*/
function _locale_import_po($file, $langcode, $mode, $group = NULL) {
// Try to allocate enough time to parse and import the data.
drupal_set_time_limit(240);
// Check if we have the language already in the database.
if (!db_query("SELECT COUNT(language) FROM {languages} WHERE language = :language", array(':language' => $langcode))->fetchField()) {
drupal_set_message(t('The language selected for import is not supported.'), 'error');
@@ -717,6 +750,12 @@ function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group =
$lineno = 0;
while (!feof($fd)) {
// Refresh the time limit every 10 parsed rows to ensure there is always
// enough time to import the data for large PO files.
if (!($lineno % 10)) {
drupal_set_time_limit(30);
}
// A line should not be longer than 10 * 1024.
$line = fgets($fd, 10 * 1024);
@@ -2306,6 +2345,8 @@ function _locale_batch_build($files, $finished = NULL, $components = array()) {
}
/**
* Implements callback_batch_operation().
*
* Perform interface translation import as a batch step.
*
* @param $filepath
@@ -2324,6 +2365,8 @@ function _locale_batch_import($filepath, &$context) {
}
/**
* Implements callback_batch_finished().
*
* Finished callback of system page locale import batch.
* Inform the user of translation files imported.
*/
@@ -2334,6 +2377,8 @@ function _locale_batch_system_finished($success, $results) {
}
/**
* Implements callback_batch_finished().
*
* Finished callback of language addition locale import batch.
* Inform the user of translation files imported.
*/
+1 -1
View File
@@ -566,7 +566,7 @@ function _drupal_wrap_mail_line(&$line, $key, $values) {
// Use soft-breaks only for purely quoted or unindented text.
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
// Break really long words at the maximum width allowed.
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n", TRUE);
}
/**
+36 -7
View File
@@ -229,12 +229,20 @@ define('MENU_CONTEXT_INLINE', 0x0002);
define('MENU_FOUND', 1);
/**
* Internal menu status code -- Menu item was not found.
* Menu status code -- Not found.
*
* This can be used as the return value from a page callback, although it is
* preferable to use a load function to accomplish this; see the hook_menu()
* documentation for details.
*/
define('MENU_NOT_FOUND', 2);
/**
* Internal menu status code -- Menu item access is denied.
* Menu status code -- Access denied.
*
* This can be used as the return value from a page callback, although it is
* preferable to use an access callback to accomplish this; see the hook_menu()
* documentation for details.
*/
define('MENU_ACCESS_DENIED', 3);
@@ -431,7 +439,7 @@ function menu_set_item($path, $router_item) {
*
* @param $path
* The path; for example, 'node/5'. The function will find the corresponding
* node/% item and return that.
* node/% item and return that. Defaults to the current path.
* @param $router_item
* Internal use only.
*
@@ -1598,6 +1606,7 @@ function _menu_tree_data(&$links, $parents, $depth) {
* Implements template_preprocess_HOOK() for theme_menu_tree().
*/
function template_preprocess_menu_tree(&$variables) {
$variables['#tree'] = $variables['tree'];
$variables['tree'] = $variables['tree']['#children'];
}
@@ -2411,7 +2420,7 @@ function menu_set_active_trail($new_trail = NULL) {
// argument placeholders (%). Such links are not contained in regular
// menu trees, and have only been loaded for the additional
// translation that happens here, so as to be able to display them in
// the breadcumb for the current page.
// the breadcrumb for the current page.
// @see _menu_tree_check_access()
// @see _menu_link_translate()
if (strpos($link['href'], '%') !== FALSE) {
@@ -2613,10 +2622,30 @@ function menu_get_active_breadcrumb() {
*/
function menu_get_active_title() {
$active_trail = menu_get_active_trail();
$local_task_title = NULL;
foreach (array_reverse($active_trail) as $item) {
if (!(bool) ($item['type'] & MENU_IS_LOCAL_TASK)) {
return $item['title'];
// Local task titles are displayed as tabs and therefore should not be
// repeated as the page title. However, if the local task appears in a
// top-level menu, it is no longer a "local task" anymore (the front page
// of the site does not have tabs) so it is better to use the local task
// title in that case than to fall back on the front page link in the
// active trail (which is usually "Home" and would not make sense in this
// context).
if ((bool) ($item['type'] & MENU_IS_LOCAL_TASK)) {
// A local task title is being skipped; track it in case it needs to be
// used later.
$local_task_title = $item['title'];
}
else {
// This is not a local task, so use it for the page title (unless the
// conditions described above are met).
if (isset($local_task_title) && isset($item['href']) && $item['href'] == '<front>') {
return $local_task_title;
}
else {
return $item['title'];
}
}
}
}
@@ -2654,7 +2683,7 @@ function menu_link_load($mlid) {
}
/**
* Clears the cached cached data for a single named menu.
* Clears the cached data for a single named menu.
*/
function menu_cache_clear($menu_name = 'navigation') {
$cache_cleared = &drupal_static(__FUNCTION__, array());
+73 -11
View File
@@ -227,6 +227,10 @@ function system_list_reset() {
drupal_static_reset('list_themes');
cache_clear_all('bootstrap_modules', 'cache_bootstrap');
cache_clear_all('system_list', 'cache_bootstrap');
// Clean up the bootstrap file scan cache.
drupal_static_reset('_drupal_file_scan_cache');
cache_clear_all('_drupal_file_scan_cache', 'cache_bootstrap');
}
/**
@@ -320,16 +324,27 @@ function module_load_install($module) {
* The name of the included file, if successful; FALSE otherwise.
*/
function module_load_include($type, $module, $name = NULL) {
static $files = array();
if (!isset($name)) {
$name = $module;
}
$key = $type . ':' . $module . ':' . $name;
if (isset($files[$key])) {
return $files[$key];
}
if (function_exists('drupal_get_path')) {
$file = DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "/$name.$type";
if (is_file($file)) {
require_once $file;
$files[$key] = $file;
return $file;
}
else {
$files[$key] = FALSE;
}
}
return FALSE;
}
@@ -365,20 +380,22 @@ function module_load_all_includes($type, $name = NULL) {
* - Invoke hook_modules_installed().
* - Invoke hook_modules_enabled().
*
* @param $module_list
* @param string[] $module_list
* An array of module names.
* @param $enable_dependencies
* @param bool $enable_dependencies
* If TRUE, dependencies will automatically be added and enabled in the
* correct order. This incurs a significant performance cost, so use FALSE
* if you know $module_list is already complete and in the correct order.
*
* @return
* @return bool
* FALSE if one or more dependencies are missing, TRUE otherwise.
*
* @see hook_install()
* @see hook_enable()
* @see hook_modules_installed()
* @see hook_modules_enabled()
* @see module_disable()
* @see drupal_uninstall_modules()
*/
function module_enable($module_list, $enable_dependencies = TRUE) {
if ($enable_dependencies) {
@@ -505,12 +522,15 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
/**
* Disables a given set of modules.
*
* @param $module_list
* @param string[] $module_list
* An array of module names.
* @param $disable_dependents
* @param bool $disable_dependents
* If TRUE, dependent modules will automatically be added and disabled in the
* correct order. This incurs a significant performance cost, so use FALSE
* if you know $module_list is already complete and in the correct order.
*
* @see drupal_uninstall_modules()
* @see module_enable()
*/
function module_disable($module_list, $disable_dependents = TRUE) {
if ($disable_dependents) {
@@ -676,12 +696,16 @@ function module_hook($module, $hook) {
/**
* Determines which modules are implementing a hook.
*
* @param $hook
* Lazy-loaded include files specified with "group" via hook_hook_info() or
* hook_module_implements_alter() will be automatically included by this
* function when necessary.
*
* @param string $hook
* The name of the hook (e.g. "help" or "menu").
* @param $sort
* @param bool $sort
* By default, modules are ordered by weight and filename, settings this option
* to TRUE, module list will be ordered by module name.
* @param $reset
* @param bool $reset
* For internal use only: Whether to force the stored list of hook
* implementations to be regenerated (such as after enabling a new module,
* before processing hook_enable).
@@ -696,8 +720,10 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['implementations'] = &drupal_static(__FUNCTION__);
$drupal_static_fast['verified'] = &drupal_static(__FUNCTION__ . ':verified');
}
$implementations = &$drupal_static_fast['implementations'];
$verified = &$drupal_static_fast['verified'];
// We maintain a persistent cache of hook implementations in addition to the
// static cache to avoid looping through every module and every hook on each
@@ -711,14 +737,19 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
// per request.
if ($reset) {
$implementations = array();
$verified = array();
cache_set('module_implements', array(), 'cache_bootstrap');
drupal_static_reset('module_hook_info');
drupal_static_reset('drupal_alter');
cache_clear_all('hook_info', 'cache_bootstrap');
cache_clear_all('system_cache_tables', 'cache');
return;
}
// Fetch implementations from cache.
// This happens on the first call to module_implements(*, *, FALSE) during a
// request, but also when $implementations have been reset, e.g. after
// module_enable().
if (empty($implementations)) {
$implementations = cache_get('module_implements', 'cache_bootstrap');
if ($implementations === FALSE) {
@@ -727,12 +758,17 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
else {
$implementations = $implementations->data;
}
// Forget all previously "verified" hooks, in case that $implementations
// were cleared via drupal_static_reset('module_implements') instead of
// module_implements(*, *, TRUE).
$verified = array();
}
if (!isset($implementations[$hook])) {
// The hook is not cached, so ensure that whether or not it has
// implementations, that the cache is updated at the end of the request.
$implementations['#write_cache'] = TRUE;
// Discover implementations for this hook.
$hook_info = module_hook_info();
$implementations[$hook] = array();
$list = module_list(FALSE, FALSE, $sort);
@@ -744,13 +780,31 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
$implementations[$hook][$module] = $include_file ? $hook_info[$hook]['group'] : FALSE;
}
}
// Allow modules to change the weight of specific implementations but avoid
// Allow modules to change the weight of specific implementations, but avoid
// an infinite loop.
if ($hook != 'module_implements_alter') {
// Remember the implementations before hook_module_implements_alter().
$implementations_before = $implementations[$hook];
drupal_alter('module_implements', $implementations[$hook], $hook);
// Verify implementations that were added or modified.
foreach (array_diff_assoc($implementations[$hook], $implementations_before) as $module => $group) {
// If drupal_alter('module_implements') changed or added a $group, the
// respective file needs to be included.
if ($group) {
module_load_include('inc', $module, "$module.$group");
}
// If a new implementation was added, verify that the function exists.
if (!function_exists($module . '_' . $hook)) {
unset($implementations[$hook][$module]);
}
}
}
// Implementations for this hook are now "verified".
$verified[$hook] = TRUE;
}
else {
elseif (!isset($verified[$hook])) {
// Implementations for this hook were in the cache, but they are not
// "verified" yet.
foreach ($implementations[$hook] as $module => $group) {
// If this hook implementation is stored in a lazy-loaded file, so include
// that file first.
@@ -769,6 +823,7 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
$implementations['#write_cache'] = TRUE;
}
}
$verified[$hook] = TRUE;
}
return array_keys($implementations[$hook]);
@@ -833,6 +888,11 @@ function module_hook_info() {
* @see module_implements()
*/
function module_implements_write_cache() {
// The list of implementations includes vital modules only before full
// bootstrap, so do not write cache if we are not fully bootstrapped yet.
if (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL) {
return;
}
$implementations = &drupal_static('module_implements');
if (isset($implementations['#write_cache'])) {
unset($implementations['#write_cache']);
@@ -880,7 +940,9 @@ function module_invoke($module, $hook) {
*
* @return
* An array of return values of the hook implementations. If modules return
* arrays from their implementations, those are merged into one array.
* arrays from their implementations, those are merged into one array
* recursively. Note: integer keys in arrays will be lost, as the merge is
* done using array_merge_recursive().
*
* @see drupal_alter()
*/
+2 -1
View File
@@ -347,7 +347,8 @@ function drupal_match_path($path, $patterns) {
* drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) makes this function available.
*
* @return
* The current Drupal URL path.
* The current Drupal URL path. The path is untrusted user input and must be
* treated as such.
*
* @see request_path()
*/
+1 -1
View File
@@ -164,7 +164,7 @@ function _registry_parse_files($files) {
* (optional) Weight of the module.
*/
function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
if (preg_match_all('/^\s*(?:abstract|final)?\s*(class|interface)\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
if (preg_match_all('/^\s*(?:abstract|final)?\s*(class|interface|trait)\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
foreach ($matches[2] as $key => $name) {
db_merge('registry')
->key(array(
+82
View File
@@ -0,0 +1,82 @@
<?php
/**
* @file
* Contains code for sanitizing user input from the request.
*/
/**
* Sanitizes user input from the request.
*/
class DrupalRequestSanitizer {
/**
* Tracks whether the request was already sanitized.
*/
protected static $sanitized = FALSE;
/**
* Modifies the request to strip dangerous keys from user input.
*/
public static function sanitize() {
if (!self::$sanitized) {
$whitelist = variable_get('sanitize_input_whitelist', array());
$log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
// Process query string parameters.
$get_sanitized_keys = array();
$_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
if ($log_sanitized_keys && $get_sanitized_keys) {
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
}
// Process request body parameters.
$post_sanitized_keys = array();
$_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
if ($log_sanitized_keys && $post_sanitized_keys) {
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
}
// Process cookie parameters.
$cookie_sanitized_keys = array();
$_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
if ($log_sanitized_keys && $cookie_sanitized_keys) {
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
}
$request_sanitized_keys = array();
$_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
self::$sanitized = TRUE;
}
}
/**
* Strips dangerous keys from the provided input.
*
* @param mixed $input
* The input to sanitize.
* @param string[] $whitelist
* An array of keys to whitelist as safe.
* @param string[] $sanitized_keys
* An array of keys that have been removed.
*
* @return mixed
* The sanitized input.
*/
protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
if (is_array($input)) {
foreach ($input as $key => $value) {
if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
unset($input[$key]);
$sanitized_keys[] = $key;
}
else {
$input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
}
}
}
return $input;
}
}
+4 -2
View File
@@ -163,7 +163,7 @@ function _drupal_session_write($sid, $value) {
try {
if (!drupal_save_session()) {
// We don't have anything to do if we are not allowed to save the session.
return;
return TRUE;
}
// Check whether $_SESSION has been changed in this request.
@@ -425,7 +425,7 @@ function _drupal_session_destroy($sid) {
// Nothing to do if we are not allowed to change the session.
if (!drupal_save_session()) {
return;
return TRUE;
}
// Delete session data.
@@ -446,6 +446,8 @@ function _drupal_session_destroy($sid) {
elseif (variable_get('https', FALSE)) {
_drupal_session_delete_cookie('S' . session_name(), TRUE);
}
return TRUE;
}
/**
+150 -2
View File
@@ -133,7 +133,7 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
* @param $uri
* A string containing the URI that should be used for this instance.
*/
function setUri($uri);
public function setUri($uri);
/**
* Returns the stream resource URI.
@@ -219,7 +219,6 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
public function dirname($uri = NULL);
}
/**
* Drupal stream wrapper base class for local files.
*
@@ -549,6 +548,155 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
return fclose($this->handle);
}
/**
* Sets metadata on the stream.
*
* WARNING: Do not call this method directly! It will be called internally by
* PHP itself when one of the following functions is called on a stream URL:
*
* @param string $uri
* A string containing the URI to the file to set metadata on.
* @param int $option
* One of:
* - STREAM_META_TOUCH: The method was called in response to touch().
* - STREAM_META_OWNER_NAME: The method was called in response to chown()
* with string parameter.
* - STREAM_META_OWNER: The method was called in response to chown().
* - STREAM_META_GROUP_NAME: The method was called in response to chgrp().
* - STREAM_META_GROUP: The method was called in response to chgrp().
* - STREAM_META_ACCESS: The method was called in response to chmod().
* @param mixed $value
* If option is:
* - STREAM_META_TOUCH: Array consisting of two arguments of the touch()
* function.
* - STREAM_META_OWNER_NAME or STREAM_META_GROUP_NAME: The name of the owner
* user/group as string.
* - STREAM_META_OWNER or STREAM_META_GROUP: The value of the owner
* user/group as integer.
* - STREAM_META_ACCESS: The argument of the chmod() as integer.
*
* @return bool
* Returns TRUE on success or FALSE on failure. If $option is not
* implemented, FALSE should be returned.
*
* @see touch()
* @see chmod()
* @see chown()
* @see chgrp()
* @link http://php.net/manual/streamwrapper.stream-metadata.php
*/
public function stream_metadata($uri, $option, $value) {
$target = $this->getLocalPath($uri);
$return = FALSE;
switch ($option) {
case STREAM_META_TOUCH:
if (!empty($value)) {
$return = touch($target, $value[0], $value[1]);
}
else {
$return = touch($target);
}
break;
case STREAM_META_OWNER_NAME:
case STREAM_META_OWNER:
$return = chown($target, $value);
break;
case STREAM_META_GROUP_NAME:
case STREAM_META_GROUP:
$return = chgrp($target, $value);
break;
case STREAM_META_ACCESS:
$return = chmod($target, $value);
break;
}
if ($return) {
// For convenience clear the file status cache of the underlying file,
// since metadata operations are often followed by file status checks.
clearstatcache(TRUE, $target);
}
return $return;
}
/**
* Truncate stream.
*
* Will respond to truncation; e.g., through ftruncate().
*
* @param int $new_size
* The new size.
*
* @return bool
* TRUE on success, FALSE otherwise.
*/
public function stream_truncate($new_size) {
return ftruncate($this->handle, $new_size);
}
/**
* Retrieve the underlying stream resource.
*
* This method is called in response to stream_select().
*
* @param int $cast_as
* Can be STREAM_CAST_FOR_SELECT when stream_select() is calling
* stream_cast() or STREAM_CAST_AS_STREAM when stream_cast() is called for
* other uses.
*
* @return resource|false
* The underlying stream resource or FALSE if stream_select() is not
* supported.
*
* @see stream_select()
* @link http://php.net/manual/streamwrapper.stream-cast.php
*/
public function stream_cast($cast_as) {
return $this->handle ? $this->handle : FALSE;
}
/**
* Change stream options.
*
* This method is called to set options on the stream.
*
* Since Windows systems do not allow it and it is not needed for most use
* cases anyway, this method is not supported on local files and will trigger
* an error and return false. If needed, custom subclasses can provide
* OS-specific implementations for advanced use cases.
*
* @param int $option
* One of:
* - STREAM_OPTION_BLOCKING: The method was called in response to
* stream_set_blocking().
* - STREAM_OPTION_READ_TIMEOUT: The method was called in response to
* stream_set_timeout().
* - STREAM_OPTION_WRITE_BUFFER: The method was called in response to
* stream_set_write_buffer().
* @param int $arg1
* If option is:
* - STREAM_OPTION_BLOCKING: The requested blocking mode:
* - 1 means blocking.
* - 0 means not blocking.
* - STREAM_OPTION_READ_TIMEOUT: The timeout in seconds.
* - STREAM_OPTION_WRITE_BUFFER: The buffer mode, STREAM_BUFFER_NONE or
* STREAM_BUFFER_FULL.
* @param int $arg2
* If option is:
* - STREAM_OPTION_BLOCKING: This option is not set.
* - STREAM_OPTION_READ_TIMEOUT: The timeout in microseconds.
* - STREAM_OPTION_WRITE_BUFFER: The requested buffer size.
*
* @return bool
* TRUE on success, FALSE otherwise. If $option is not implemented, FALSE
* should be returned.
*/
public function stream_set_option($option, $arg1, $arg2) {
trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
return FALSE;
}
/**
* Support for unlink().
*
+28 -7
View File
@@ -1248,6 +1248,7 @@ function path_to_theme() {
function drupal_find_theme_functions($cache, $prefixes) {
$implementations = array();
$functions = get_defined_functions();
$theme_functions = preg_grep('/^(' . implode(')|(', $prefixes) . ')_/', $functions['user']);
foreach ($cache as $hook => $info) {
foreach ($prefixes as $prefix) {
@@ -1264,7 +1265,7 @@ function drupal_find_theme_functions($cache, $prefixes) {
// intermediary suggestion.
$pattern = isset($info['pattern']) ? $info['pattern'] : ($hook . '__');
if (!isset($info['base hook']) && !empty($pattern)) {
$matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $functions['user']);
$matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $theme_functions);
if ($matches) {
foreach ($matches as $match) {
$new_hook = substr($match, strlen($prefix) + 1);
@@ -1710,11 +1711,29 @@ function theme_status_messages($variables) {
* copy if none of the enabled modules or the active theme implement any
* preprocess or process functions or override this theme implementation.
*
* @param $variables
* An associative array containing the keys 'text', 'path', and 'options'.
* See the l() function for information about these variables.
* @param array $variables
* An associative array containing the keys:
* - text: The text of the link.
* - path: The internal path or external URL being linked to. It is used as
* the $path parameter of the url() function.
* - options: (optional) An array that defaults to empty, but can contain:
* - attributes: Can contain optional attributes:
* - class: must be declared in an array. Example: 'class' =>
* array('class_name1','class_name2').
* - title: must be a string. Example: 'title' => 'Example title'
* - Others are more flexible as long as they work with
* drupal_attributes($variables['options']['attributes]).
* - html: Boolean flag that tells whether text contains HTML or plain
* text. If set to TRUE, the text value will not be sanitized so the
calling function must ensure that it already contains safe HTML.
* The elements $variables['options']['attributes'] and
* $variables['options']['html'] are used in this function similarly to the
* way that $options['attributes'] and $options['html'] are used in l().
* The link itself is built by the url() function, which takes
* $variables['path'] and $variables['options'] as arguments.
*
* @see l()
* @see url()
*/
function theme_link($variables) {
return '<a href="' . check_plain(url($variables['path'], $variables['options'])) . '"' . drupal_attributes($variables['options']['attributes']) . '>' . ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text'])) . '</a>';
@@ -1791,7 +1810,8 @@ function theme_links($variables) {
foreach ($links as $key => $link) {
$class = array($key);
// Add first, last and active classes to the list of links to help out themers.
// Add first, last and active classes to the list of links to help out
// themers.
if ($i == 1) {
$class[] = 'first';
}
@@ -1809,7 +1829,8 @@ function theme_links($variables) {
$output .= l($link['title'], $link['href'], $link);
}
elseif (!empty($link['title'])) {
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes.
// Some links are actually not links, but we wrap these in <span> for
// adding title and class attributes.
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
@@ -2618,7 +2639,7 @@ function template_preprocess_page(&$variables) {
// Move some variables to the top level for themer convenience and template cleanliness.
$variables['show_messages'] = $variables['page']['#show_messages'];
foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {
foreach (system_region_list($GLOBALS['theme'], REGIONS_ALL, FALSE) as $region_key) {
if (!isset($variables['page'][$region_key])) {
$variables['page'][$region_key] = array();
}
+12
View File
@@ -795,6 +795,14 @@ function update_fix_d7_requirements() {
function update_fix_d7_install_profile() {
$profile = drupal_get_profile();
// 'Default' profile has been renamed to 'Standard' in D7.
// We change the profile here to prevent a broken record in the system table.
// See system_update_7049().
if ($profile == 'default') {
$profile = 'standard';
variable_set('install_profile', $profile);
}
$results = db_select('system', 's')
->fields('s', array('name', 'schema_version'))
->condition('name', $profile)
@@ -908,6 +916,8 @@ function update_get_d6_session_name() {
}
/**
* Implements callback_batch_operation().
*
* Performs one update and stores the results for display on the results page.
*
* If an update function completes successfully, it should return a message
@@ -1078,6 +1088,8 @@ function update_batch($start, $redirect = NULL, $url = NULL, $batch = array(), $
}
/**
* Implements callback_batch_finished().
*
* Finishes the update process and stores the results for eventual display.
*
* After the updates run, all caches are flushed. The update results are
+8
View File
@@ -264,6 +264,10 @@ function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
*/
function xmlrpc_server_multicall($methodcalls) {
// See http://www.xmlrpc.com/discuss/msgReader$1208
// To avoid multicall expansion attacks, limit the number of duplicate method
// calls allowed with a default of 1. Set to -1 for unlimited.
$duplicate_method_limit = variable_get('xmlrpc_multicall_duplicate_method_limit', 1);
$method_count = array();
$return = array();
$xmlrpc_server = xmlrpc_server_get();
foreach ($methodcalls as $call) {
@@ -273,10 +277,14 @@ function xmlrpc_server_multicall($methodcalls) {
$ok = FALSE;
}
$method = $call['methodName'];
$method_count[$method] = isset($method_count[$method]) ? $method_count[$method] + 1 : 1;
$params = $call['params'];
if ($method == 'system.multicall') {
$result = xmlrpc_error(-32600, t('Recursive calls to system.multicall are forbidden.'));
}
elseif ($duplicate_method_limit > 0 && $method_count[$method] > $duplicate_method_limit) {
$result = xmlrpc_error(-156579, t('Too many duplicate method calls in system.multicall.'));
}
elseif ($ok) {
$result = xmlrpc_server_call($xmlrpc_server, $method, $params);
}
+26
View File
@@ -0,0 +1,26 @@
<?php
/**
* @file
* Initiates a browser-based installation of Drupal.
*/
/**
* Defines the root directory of the Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());
/**
* Global flag to indicate the site is in installation mode.
*/
define('MAINTENANCE_MODE', 'install');
// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
exit;
}
// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();
+14
View File
@@ -0,0 +1,14 @@
diff --git a/logintoboggan.permissions.js b/logintoboggan.permissions.js
index d463d29..492b64c 100644
--- a/logintoboggan.permissions.js
+++ b/logintoboggan.permissions.js
@@ -14,6 +14,9 @@ Drupal.behaviors.LoginTobogganPermissions = {
$('table#permissions', context).once('tobogganPermissions', function () {
$('input[type=checkbox]', this).filter('.rid-' + settings.LoginToboggan.preAuthID).removeClass('real-checkbox').each(function () {
$(this).next().filter('.dummy-checkbox').remove();
+ $('input.rid-' + settings.LoginToboggan.preAuthID).each(function () {
+ this.style.display = '';
+ });
});
});
},
@@ -0,0 +1,136 @@
diff --git a/logintoboggan.module b/logintoboggan.module
index 55b93fe..4e4e0fc 100644
--- a/logintoboggan.module
+++ b/logintoboggan.module
@@ -306,26 +306,6 @@ function logintoboggan_form_user_pass_reset_alter(&$form, &$form_state) {
}
/**
- * Implement hook_form_user_admin_permissions_alter().
- *
- * @ingroup logintoboggan_core
- */
-function logintoboggan_form_user_admin_permissions_alter(&$form, &$form_state) {
- // If the pre-auth role isn't the auth user, then add it as a setting.
- $id = logintoboggan_validating_id();
- if ($id != DRUPAL_AUTHENTICATED_RID) {
- $form['#attached']['js'][] = array(
- 'data' => array(
- 'LoginToboggan' => array(
- 'preAuthID' => $id,
- ),
- ),
- 'type' => 'setting',
- );
- }
-}
-
-/**
* Implement hook_form_alter().
*
* @ingroup logintoboggan_core
@@ -410,7 +390,10 @@ function logintoboggan_js_alter(&$javascript) {
// prevent the pre-auth role's checkboxes from being automatically disabled
// when the auth user's checkboxes are checked.
if ($id != DRUPAL_AUTHENTICATED_RID) {
- $javascript['modules/user/user.permissions.js']['data'] = drupal_get_path('module', 'logintoboggan') . '/logintoboggan.permissions.js';
+ $javascript['settings']['data'][] = array('LoginToboggan' => array('preAuthID' => $id));
+ $file = drupal_get_path('module', 'logintoboggan') . '/logintoboggan.permissions.js';
+ $javascript[$file] = drupal_js_defaults($file);
+ $javascript[$file]['weight'] = 999;
}
}
}
diff --git a/logintoboggan.permissions.js b/logintoboggan.permissions.js
index 1d406cc..492b64c 100644
--- a/logintoboggan.permissions.js
+++ b/logintoboggan.permissions.js
@@ -1,77 +1,25 @@
/**
- * This is a custom implementation of user.permissions.js, which is necessary
- * because LoginToboggan needs its pre-auth role to not be explicitly tied to
- * the auth role. The change is minor -- simply exclude the pre-auth role from
- * all the auto-checking as the anon and auth user roles are.
+ * LoginToboggan needs its pre-auth role to not be explicitly tied to
+ * the auth role.
*/
-
(function ($) {
/**
* Shows checked and disabled checkboxes for inherited permissions.
*/
-Drupal.behaviors.permissions = {
- attach: function (context) {
- var self = this;
- $('table#permissions').once('permissions', function () {
- // On a site with many roles and permissions, this behavior initially has
- // to perform thousands of DOM manipulations to inject checkboxes and hide
- // them. By detaching the table from the DOM, all operations can be
- // performed without triggering internal layout and re-rendering processes
- // in the browser.
- var $table = $(this);
- if ($table.prev().length) {
- var $ancestor = $table.prev(), method = 'after';
- }
- else {
- var $ancestor = $table.parent(), method = 'append';
- }
- $table.detach();
-
- // Create dummy checkboxes. We use dummy checkboxes instead of reusing
- // the existing checkboxes here because new checkboxes don't alter the
- // submitted form. If we'd automatically check existing checkboxes, the
- // permission table would be polluted with redundant entries. This
- // is deliberate, but desirable when we automatically check them.
- var $dummy = $('<input type="checkbox" class="dummy-checkbox" disabled="disabled" checked="checked" />')
- .attr('title', Drupal.t("This permission is inherited from the authenticated user role."))
- .hide();
-
- $('input[type=checkbox]', this).not('.rid-2, .rid-1, .rid-' + Drupal.settings.LoginToboggan.preAuthID).addClass('real-checkbox').each(function () {
- $dummy.clone().insertAfter(this);
+Drupal.behaviors.LoginTobogganPermissions = {
+ attach: function (context, settings) {
+ // Revert changes made by modules/user/user.permissions.js
+ $('table#permissions', context).once('tobogganPermissions', function () {
+ $('input[type=checkbox]', this).filter('.rid-' + settings.LoginToboggan.preAuthID).removeClass('real-checkbox').each(function () {
+ $(this).next().filter('.dummy-checkbox').remove();
+ $('input.rid-' + settings.LoginToboggan.preAuthID).each(function () {
+ this.style.display = '';
+ });
});
-
- // Initialize the authenticated user checkbox.
- $('input[type=checkbox].rid-2', this)
- .bind('click.permissions', self.toggle)
- // .triggerHandler() cannot be used here, as it only affects the first
- // element.
- .each(self.toggle);
-
- // Re-insert the table into the DOM.
- $ancestor[method]($table);
});
},
-
- /**
- * Toggles all dummy checkboxes based on the checkboxes' state.
- *
- * If the "authenticated user" checkbox is checked, the checked and disabled
- * checkboxes are shown, the real checkboxes otherwise.
- */
- toggle: function () {
- var authCheckbox = this, $row = $(this).closest('tr');
- // jQuery performs too many layout calculations for .hide() and .show(),
- // leading to a major page rendering lag on sites with many roles and
- // permissions. Therefore, we toggle visibility directly.
- $row.find('.real-checkbox').each(function () {
- this.style.display = (authCheckbox.checked ? 'none' : '');
- });
- $row.find('.dummy-checkbox').each(function () {
- this.style.display = (authCheckbox.checked ? '' : 'none');
- });
- }
};
})(jQuery);
+1 -1
View File
@@ -476,7 +476,7 @@ Drupal.ajax.prototype.getEffect = function (response) {
* Handler for the form redirection error.
*/
Drupal.ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
alert(Drupal.ajaxError(xmlhttprequest, uri, customMessage));
Drupal.displayAjaxError(Drupal.ajaxError(xmlhttprequest, uri, customMessage));
// Remove the progress element.
if (this.progress.element) {
$(this.progress.element).remove();
+1 -1
View File
@@ -310,7 +310,7 @@ Drupal.ACDB.prototype.search = function (searchString) {
}
},
error: function (xmlhttp) {
alert(Drupal.ajaxError(xmlhttp, db.uri));
Drupal.displayAjaxError(Drupal.ajaxError(xmlhttp, db.uri));
}
});
}, this.delay);
+129 -17
View File
@@ -27,6 +27,42 @@ $.fn.init = function (selector, context, rootjQuery) {
};
$.fn.init.prototype = jquery_init.prototype;
/**
* Pre-filter Ajax requests to guard against XSS attacks.
*
* See https://github.com/jquery/jquery/issues/2432
*/
if ($.ajaxPrefilter) {
// For newer versions of jQuery, use an Ajax prefilter to prevent
// auto-executing script tags from untrusted domains. This is similar to the
// fix that is built in to jQuery 3.0 and higher.
$.ajaxPrefilter(function (s) {
if (s.crossDomain) {
s.contents.script = false;
}
});
}
else if ($.httpData) {
// For the version of jQuery that ships with Drupal core, override
// jQuery.httpData to prevent auto-detecting "script" data types from
// untrusted domains.
var jquery_httpData = $.httpData;
$.httpData = function (xhr, type, s) {
// @todo Consider backporting code from newer jQuery versions to check for
// a cross-domain request here, rather than using Drupal.urlIsLocal() to
// block scripts from all URLs that are not on the same site.
if (!type && !Drupal.urlIsLocal(s.url)) {
var content_type = xhr.getResponseHeader('content-type') || '';
if (content_type.indexOf('javascript') >= 0) {
// Default to a safe data type.
type = 'text';
}
}
return jquery_httpData.call(this, xhr, type, s);
};
$.httpData.prototype = jquery_httpData.prototype;
}
/**
* Attach all registered behaviors to a page element.
*
@@ -137,7 +173,7 @@ Drupal.detachBehaviors = function (context, settings, trigger) {
*/
Drupal.checkPlain = function (str) {
var character, regex,
replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
replace = { '&': '&amp;', "'": '&#39;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
str = String(str);
for (character in replace) {
if (replace.hasOwnProperty(character)) {
@@ -168,23 +204,76 @@ Drupal.checkPlain = function (str) {
Drupal.formatString = function(str, args) {
// Transform arguments before inserting them.
for (var key in args) {
switch (key.charAt(0)) {
// Escaped only.
case '@':
args[key] = Drupal.checkPlain(args[key]);
break;
// Pass-through.
case '!':
break;
// Escaped and placeholder.
case '%':
default:
args[key] = Drupal.theme('placeholder', args[key]);
break;
if (args.hasOwnProperty(key)) {
switch (key.charAt(0)) {
// Escaped only.
case '@':
args[key] = Drupal.checkPlain(args[key]);
break;
// Pass-through.
case '!':
break;
// Escaped and placeholder.
default:
args[key] = Drupal.theme('placeholder', args[key]);
break;
}
}
str = str.replace(key, args[key]);
}
return str;
return Drupal.stringReplace(str, args, null);
};
/**
* Replace substring.
*
* The longest keys will be tried first. Once a substring has been replaced,
* its new value will not be searched again.
*
* @param {String} str
* A string with placeholders.
* @param {Object} args
* Key-value pairs.
* @param {Array|null} keys
* Array of keys from the "args". Internal use only.
*
* @return {String}
* Returns the replaced string.
*/
Drupal.stringReplace = function (str, args, keys) {
if (str.length === 0) {
return str;
}
// If the array of keys is not passed then collect the keys from the args.
if (!$.isArray(keys)) {
keys = [];
for (var k in args) {
if (args.hasOwnProperty(k)) {
keys.push(k);
}
}
// Order the keys by the character length. The shortest one is the first.
keys.sort(function (a, b) { return a.length - b.length; });
}
if (keys.length === 0) {
return str;
}
// Take next longest one from the end.
var key = keys.pop();
var fragments = str.split(key);
if (keys.length) {
for (var i = 0; i < fragments.length; i++) {
// Process each fragment with a copy of remaining keys.
fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0));
}
}
return fragments.join(args[key]);
};
/**
@@ -251,7 +340,7 @@ Drupal.t = function (str, args, options) {
* A translated string.
*/
Drupal.formatPlural = function (count, singular, plural, args, options) {
var args = args || {};
args = args || {};
args['@count'] = count;
// Determine the index of the plural form.
var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
@@ -413,6 +502,29 @@ Drupal.getSelection = function (element) {
return { 'start': element.selectionStart, 'end': element.selectionEnd };
};
/**
* Add a global variable which determines if the window is being unloaded.
*
* This is primarily used by Drupal.displayAjaxError().
*/
Drupal.beforeUnloadCalled = false;
$(window).bind('beforeunload pagehide', function () {
Drupal.beforeUnloadCalled = true;
});
/**
* Displays a JavaScript error from an Ajax response when appropriate to do so.
*/
Drupal.displayAjaxError = function (message) {
// Skip displaying the message if the user deliberately aborted (for example,
// by reloading the page or navigating to a different page) while the Ajax
// request was still ongoing. See, for example, the discussion at
// http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-clicks-refresh.
if (!Drupal.beforeUnloadCalled) {
alert(message);
}
};
/**
* Build an error message from an Ajax response.
*/
+5 -1
View File
@@ -493,7 +493,11 @@ $(document).bind('state:disabled', function(e) {
$(document).bind('state:required', function(e) {
if (e.trigger) {
if (e.value) {
$(e.target).closest('.form-item, .form-wrapper').find('label').append('<span class="form-required">*</span>');
var $label = $(e.target).closest('.form-item, .form-wrapper').find('label');
// Avoids duplicate required markers on initialization.
if (!$label.find('.form-required').length) {
$label.append('<span class="form-required">*</span>');
}
}
else {
$(e.target).closest('.form-item, .form-wrapper').find('label .form-required').remove();
+18 -5
View File
@@ -106,8 +106,10 @@ Drupal.tableDrag = function (table, tableSettings) {
// Add mouse bindings to the document. The self variable is passed along
// as event handlers do not have direct access to the tableDrag object.
$(document).bind('mousemove', function (event) { return self.dragRow(event, self); });
$(document).bind('mouseup', function (event) { return self.dropRow(event, self); });
$(document).bind('mousemove pointermove', function (event) { return self.dragRow(event, self); });
$(document).bind('mouseup pointerup', function (event) { return self.dropRow(event, self); });
$(document).bind('touchmove', function (event) { return self.dragRow(event.originalEvent.touches[0], self); });
$(document).bind('touchend', function (event) { return self.dropRow(event.originalEvent.touches[0], self); });
};
/**
@@ -274,7 +276,10 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) {
});
// Add the mousedown action for the handle.
handle.mousedown(function (event) {
handle.bind('mousedown touchstart pointerdown', function (event) {
if (event.originalEvent.type == "touchstart") {
event = event.originalEvent.touches[0];
}
// Create a new dragObject recording the event information.
self.dragObject = {};
self.dragObject.initMouseOffset = self.getMouseOffset(item, event);
@@ -575,12 +580,20 @@ Drupal.tableDrag.prototype.dropRow = function (event, self) {
* Get the mouse coordinates from the event (allowing for browser differences).
*/
Drupal.tableDrag.prototype.mouseCoords = function (event) {
// Complete support for pointer events was only introduced to jQuery in
// version 1.11.1; between versions 1.7 and 1.11.0 pointer events have the
// clientX and clientY properties undefined. In those cases, the properties
// must be retrieved from the event.originalEvent object instead.
var clientX = event.clientX || event.originalEvent.clientX;
var clientY = event.clientY || event.originalEvent.clientY;
if (event.pageX || event.pageY) {
return { x: event.pageX, y: event.pageY };
}
return {
x: event.clientX + document.body.scrollLeft - document.body.clientLeft,
y: event.clientY + document.body.scrollTop - document.body.clientTop
x: clientX + document.body.scrollLeft - document.body.clientLeft,
y: clientY + document.body.scrollTop - document.body.clientTop
};
};
+3 -3
View File
@@ -7,8 +7,8 @@ files[] = aggregator.test
configure = admin/config/services/aggregator/settings
stylesheets[all][] = aggregator.css
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+8
View File
@@ -455,6 +455,14 @@ function aggregator_save_category($edit) {
db_delete('aggregator_category')
->condition('cid', $edit['cid'])
->execute();
// Remove category from feeds.
db_delete('aggregator_category_feed')
->condition('cid', $edit['cid'])
->execute();
// Remove category from feed items.
db_delete('aggregator_category_item')
->condition('cid', $edit['cid'])
->execute();
// Make sure there is no active block for this category.
if (module_exists('block')) {
db_delete('block')
+1 -1
View File
@@ -72,7 +72,7 @@ function aggregator_aggregator_remove($feed) {
*/
function aggregator_form_aggregator_admin_form_alter(&$form, $form_state) {
if (in_array('aggregator', variable_get('aggregator_processors', array('aggregator')))) {
$info = module_invoke('aggregator', 'aggregator_process', 'info');
$info = module_invoke('aggregator', 'aggregator_process_info');
$items = drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items');
$period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
$period[AGGREGATOR_CLEAR_NEVER] = t('Never');
+37 -1
View File
@@ -418,7 +418,7 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
}
/**
* Creates a feed and makes sure you can add more than one category to it.
* Creates a feed and makes sure you can add/delete categories to it.
*/
function testCategorizeFeed() {
@@ -448,7 +448,31 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
// Assert the feed has two categories.
$this->getFeedCategories($db_feed);
$this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
// Use aggregator_save_feed() to delete a category.
$category = reset($categories);
aggregator_save_category(array('cid' => $category->cid));
// Assert that category is deleted.
$db_category = db_query("SELECT COUNT(*) FROM {aggregator_category} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField();
$this->assertFalse($db_category, format_string('The category %title has been deleted.', array('%title' => $category->title)));
// Assert that category has been removed from feed.
$categorized_feeds = db_query("SELECT COUNT(*) FROM {aggregator_category_feed} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField();
$this->assertFalse($categorized_feeds, format_string('The category %title has been removed from feed %feed_title.', array('%title' => $category->title, '%feed_title' => $feed['title'])));
// Assert that no broken links (associated with the deleted category)
// appear on one of the other category pages.
$this->createSampleNodes();
$this->drupalGet('admin/config/services/aggregator');
$this->clickLink('update items');
$categories = $this->getCategories();
$category = reset($categories);
$this->drupalGet('aggregator/categories/' . $category->cid);
global $base_path;
$this->assertNoRaw('<a href="' . $base_path . 'aggregator/categories/"></a>,');
}
}
/**
@@ -685,9 +709,21 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase {
}
}
// Delete category from feed items when category is deleted.
$cid = reset($feed->categories);
$categories = $this->getCategories();
$category_title = $categories[$cid]->title;
// Delete category.
aggregator_save_category(array('cid' => $cid));
// Assert category has been removed from feed items.
$categorized_count = db_query("SELECT COUNT(*) FROM {aggregator_category_item} WHERE cid = :cid", array(':cid' => $cid))->fetchField();
$this->assertFalse($categorized_count, format_string('The category %title has been removed from feed items.', array('%title' => $category_title)));
// Delete feed.
$this->deleteFeed($feed);
}
}
/**
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+25
View File
@@ -363,6 +363,31 @@ function hook_block_list_alter(&$blocks) {
}
}
/**
* Act on block cache ID (cid) parts before the cid is generated.
*
* This hook allows you to add, remove or modify the custom keys used to
* generate a block cache ID (by default, these keys are set to the block
* module and delta). These keys will be combined with the standard ones
* provided by drupal_render_cid_parts() to generate the final block cache ID.
*
* To change the cache granularity used by drupal_render_cid_parts(), this hook
* cannot be used; instead, set the 'cache' key in the block's definition in
* hook_block_info().
*
* @params $cid_parts
* An array of elements used to build the cid.
* @param $block
* The block object being acted on.
*
* @see _block_get_cache_id()
*/
function hook_block_cid_parts_alter(&$cid_parts, $block) {
global $user;
// This example shows how to cache a block based on the user's timezone.
$cid_parts[] = $user->timezone;
}
/**
* @} End of "addtogroup hooks".
*/
+3 -3
View File
@@ -6,8 +6,8 @@ core = 7.x
files[] = block.test
configure = admin/structure/block
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -24,7 +24,7 @@ Drupal.behaviors.blockSettingsSummary = {
$('fieldset#edit-node-type', context).drupalSetSummary(function (context) {
var vals = [];
$('input[type="checkbox"]:checked', context).each(function () {
vals.push($.trim($(this).next('label').text()));
vals.push($.trim($(this).next('label').html()));
});
if (!vals.length) {
vals.push(Drupal.t('Not restricted'));
@@ -35,7 +35,7 @@ Drupal.behaviors.blockSettingsSummary = {
$('fieldset#edit-role', context).drupalSetSummary(function (context) {
var vals = [];
$('input[type="checkbox"]:checked', context).each(function () {
vals.push($.trim($(this).next('label').text()));
vals.push($.trim($(this).next('label').html()));
});
if (!vals.length) {
vals.push(Drupal.t('Not restricted'));
@@ -49,7 +49,7 @@ Drupal.behaviors.blockSettingsSummary = {
return Drupal.t('Not customizable');
}
else {
return $radio.next('label').text();
return $radio.next('label').html();
}
});
}
+38 -29
View File
@@ -16,7 +16,7 @@ define('BLOCK_REGION_NONE', -1);
define('BLOCK_CUSTOM_FIXED', 0);
/**
* Shows this block by default, but lets individual users hide it.
* Shows this block by default, but lets individual users hide it.
*/
define('BLOCK_CUSTOM_ENABLED', 1);
@@ -59,6 +59,7 @@ function block_help($path, $arg) {
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can <a href="@block-add">add custom blocks</a>, which are then listed on the <a href="@blocks">Blocks administration page</a>. Once created, custom blocks behave just like default and module-generated blocks.', array('@blocks' => url('admin/structure/block'), '@block-add' => url('admin/structure/block/add'))) . '</dd>';
$output .= '</dl>';
return $output;
case 'admin/structure/block/add':
return '<p>' . t('Use this page to create a new custom block.') . '</p>';
}
@@ -189,6 +190,7 @@ function _block_themes_access($theme) {
* @param $theme
* The theme whose blocks are being configured. If not set, the default theme
* is assumed.
*
* @return
* The theme that should be used for the block configuration page, or NULL
* to indicate that the default theme should be used.
@@ -283,8 +285,7 @@ function block_page_build(&$page) {
// Append region description if we are rendering the regions demo page.
$item = menu_get_item();
if ($item['path'] == 'admin/structure/block/demo/' . $theme) {
$visible_regions = array_keys(system_region_list($theme, REGIONS_VISIBLE));
foreach ($visible_regions as $region) {
foreach (system_region_list($theme, REGIONS_VISIBLE, FALSE) as $region) {
$description = '<div class="block-region">' . $all_regions[$region] . '</div>';
$page[$region]['block_description'] = array(
'#markup' => $description,
@@ -343,14 +344,17 @@ function _block_get_renderable_array($list = array()) {
// to perform contextual actions on the help block, and the links needlessly
// draw attention on it.
if ($key != 'system_main' && $key != 'system_help') {
$build[$key]['#contextual_links']['block'] = array('admin/structure/block/manage', array($block->module, $block->delta));
$build[$key]['#contextual_links']['block'] = array(
'admin/structure/block/manage',
array($block->module, $block->delta),
);
}
$build[$key] += array(
'#block' => $block,
'#weight' => ++$weight,
);
$build[$key]['#theme_wrappers'][] ='block';
$build[$key]['#theme_wrappers'][] = 'block';
}
$build['#sorted'] = TRUE;
return $build;
@@ -386,18 +390,20 @@ function _block_rehash($theme = NULL) {
// Gather the blocks defined by modules.
foreach (module_implements('block_info') as $module) {
$module_blocks = module_invoke($module, 'block_info');
$delta_list = array();
foreach ($module_blocks as $delta => $block) {
// Compile a condition to retrieve this block from the database.
$condition = db_and()
->condition('module', $module)
->condition('delta', $delta);
$or->condition($condition);
// Add identifiers.
$delta_list[] = $delta;
$block['module'] = $module;
$block['delta'] = $delta;
$block['theme'] = $theme;
$block['delta'] = $delta;
$block['theme'] = $theme;
$current_blocks[$module][$delta] = $block;
}
if (!empty($delta_list)) {
$condition = db_and()->condition('module', $module)->condition('delta', $delta_list);
$or->condition($condition);
}
}
// Save the blocks defined in code for alter context.
$code_blocks = $current_blocks;
@@ -426,23 +432,20 @@ function _block_rehash($theme = NULL) {
drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
foreach ($current_blocks as $module => $module_blocks) {
foreach ($module_blocks as $delta => $block) {
if (!isset($block['pages'])) {
// {block}.pages is type 'text', so it cannot have a
// default value, and not null, so we need to provide
// value if the module did not.
$block['pages'] = '';
}
// Make sure weight is set.
if (!isset($block['weight'])) {
$block['weight'] = 0;
}
// Make sure certain attributes are set.
$block += array(
'pages' => '',
'weight' => 0,
'status' => 0,
);
// Check for active blocks in regions that are not available.
if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) {
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning');
// Disabled modules are moved into the BLOCK_REGION_NONE later so no
// need to move the block to another region.
$block['status'] = 0;
}
// Set region to none if not enabled and make sure status is set.
// Set region to none if not enabled.
if (empty($block['status'])) {
$block['status'] = 0;
$block['region'] = BLOCK_REGION_NONE;
@@ -644,7 +647,8 @@ function block_theme_initialize($theme) {
$regions = system_region_list($theme, REGIONS_VISIBLE);
$result = db_query("SELECT * FROM {block} WHERE theme = :theme", array(':theme' => $default_theme), array('fetch' => PDO::FETCH_ASSOC));
foreach ($result as $block) {
// If the region isn't supported by the theme, assign the block to the theme's default region.
// If the region isn't supported by the theme, assign the block to the
// theme's default region.
if ($block['status'] && !isset($regions[$block['region']])) {
$block['region'] = system_default_region($theme);
}
@@ -812,17 +816,18 @@ function block_block_list_alter(&$blocks) {
// with different case. Ex: /Page, /page, /PAGE.
$pages = drupal_strtolower($block->pages);
if ($block->visibility < BLOCK_VISIBILITY_PHP) {
// Convert the Drupal path to lowercase
// Convert the Drupal path to lowercase.
$path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
// Compare the lowercase internal and lowercase path alias (if any).
$page_match = drupal_match_path($path, $pages);
if ($path != $_GET['q']) {
$page_match = $page_match || drupal_match_path($_GET['q'], $pages);
}
// When $block->visibility has a value of 0 (BLOCK_VISIBILITY_NOTLISTED),
// the block is displayed on all pages except those listed in $block->pages.
// When set to 1 (BLOCK_VISIBILITY_LISTED), it is displayed only on those
// pages listed in $block->pages.
// When $block->visibility has a value of 0
// (BLOCK_VISIBILITY_NOTLISTED), the block is displayed on all pages
// except those listed in $block->pages. When set to 1
// (BLOCK_VISIBILITY_LISTED), it is displayed only on those pages
// listed in $block->pages.
$page_match = !($block->visibility xor $page_match);
}
elseif (module_exists('php')) {
@@ -845,7 +850,8 @@ function block_block_list_alter(&$blocks) {
* Render the content and subject for a set of blocks.
*
* @param $region_blocks
* An array of block objects such as returned for one region by _block_load_blocks().
* An array of block objects such as returned for one region by
* _block_load_blocks().
*
* @return
* An array of visible blocks as expected by drupal_render().
@@ -953,6 +959,8 @@ function _block_render_blocks($region_blocks) {
* Theme and language contexts are automatically differentiated.
*
* @param $block
* The block to get the cache_id from.
*
* @return
* The string used as cache_id for the block.
*/
@@ -967,6 +975,7 @@ function _block_get_cache_id($block) {
// Start with common sub-patterns: block identification, theme, language.
$cid_parts[] = $block->module;
$cid_parts[] = $block->delta;
drupal_alter('block_cid_parts', $cid_parts, $block);
$cid_parts = array_merge($cid_parts, drupal_render_cid_parts($block->cache));
return implode(':', $cid_parts);
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
@@ -13,8 +13,8 @@ regions[footer] = Footer
regions[highlighted] = Highlighted
regions[help] = Help
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = blog.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+1 -1
View File
@@ -152,7 +152,7 @@ function blog_menu_local_tasks_alter(&$data, $router_item, $root_path) {
}
}
// Provide a helper action link to the author on the 'blog/%' page.
elseif ($root_path == 'blog/%' && $router_item['page_arguments'][0]->uid == $user->uid) {
elseif ($root_path == 'blog/%' && isset($router_item['page_arguments'][0]->uid) && $router_item['page_arguments'][0]->uid == $user->uid) {
$data['actions']['output']['blog'] = array(
'#theme' => 'menu_local_action',
);
+3 -3
View File
@@ -7,8 +7,8 @@ files[] = book.test
configure = admin/content/book/settings
stylesheets[all][] = book.css
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = color.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+1 -1
View File
@@ -122,7 +122,7 @@ class ColorTestCase extends DrupalWebTestCase {
$edit['palette[bg]'] = $color;
$this->drupalPost($settings_path, $edit, t('Save configuration'));
if($is_valid) {
if ($is_valid) {
$this->assertText('The configuration options have been saved.');
}
else {
+3 -3
View File
@@ -9,8 +9,8 @@ files[] = comment.test
configure = admin/content/comment
stylesheets[all][] = comment.css
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+9 -3
View File
@@ -11,9 +11,15 @@ class CommentHelperCase extends DrupalWebTestCase {
protected $node;
function setUp() {
parent::setUp('comment', 'search');
$modules = func_get_args();
if (isset($modules[0]) && is_array($modules[0])) {
$modules = $modules[0];
}
$modules[] = 'comment';
parent::setUp($modules);
// Create users and test node.
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks', 'administer actions'));
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks', 'administer actions', 'administer fields'));
$this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid));
}
@@ -1490,7 +1496,7 @@ class CommentNodeAccessTest extends CommentHelperCase {
}
function setUp() {
DrupalWebTestCase::setUp('comment', 'search', 'node_access_test');
parent::setUp('search', 'node_access_test');
node_access_rebuild();
// Create users and test node.
+3 -3
View File
@@ -6,8 +6,8 @@ core = 7.x
files[] = contact.test
configure = admin/structure/contact
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+8 -1
View File
@@ -234,7 +234,14 @@ function contact_form_user_profile_form_alter(&$form, &$form_state) {
* Implements hook_user_presave().
*/
function contact_user_presave(&$edit, $account, $category) {
$edit['data']['contact'] = isset($edit['contact']) ? $edit['contact'] : variable_get('contact_default_status', 1);
if (isset($edit['contact'])) {
// Set new value.
$edit['data']['contact'] = $edit['contact'];
}
elseif (!isset($account->data['contact'])) {
// Use default if none has been set.
$edit['data']['contact'] = variable_get('contact_default_status', 1);
}
}
/**
+22
View File
@@ -346,6 +346,28 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
$this->assertResponse(200);
// Test that users can disable their contact form.
$this->drupalLogin($this->contact_user);
$edit = array('contact' => FALSE);
$this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save');
$this->drupalLogout();
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
$this->assertResponse(403);
// Test that user's contact status stays disabled when saving.
$contact_user_temp = user_load($this->contact_user->uid, TRUE);
user_save($contact_user_temp);
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
$this->assertResponse(403);
// Test that users can enable their contact form.
$this->drupalLogin($this->contact_user);
$edit = array('contact' => TRUE);
$this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save');
$this->drupalLogout();
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
$this->assertResponse(200);
// Revoke the personal contact permission for the anonymous user.
user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = contextual.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -7,8 +7,8 @@ files[] = dashboard.test
dependencies[] = block
configure = admin/dashboard/customize
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+9 -2
View File
@@ -294,11 +294,18 @@ function theme_dblog_message($variables) {
else {
$output = t($event->message, unserialize($event->variables));
}
// If the output is expected to be a link, strip all the tags and
// special characters by using filter_xss() without any allowed tags.
// If not, use filter_xss_admin() to allow some tags.
if ($variables['link'] && isset($event->wid)) {
// Truncate message to 56 chars.
// Truncate message to 56 chars after stripping all the tags.
$output = truncate_utf8(filter_xss($output, array()), 56, TRUE, TRUE);
$output = l($output, 'admin/reports/event/' . $event->wid, array('html' => TRUE));
}
else {
// Prevent XSS in log detail pages.
$output = filter_xss_admin($output);
}
}
return $output;
}
@@ -413,6 +420,6 @@ function dblog_clear_log_form($form) {
*/
function dblog_clear_log_submit() {
$_SESSION['dblog_overview_filter'] = array();
db_delete('watchdog')->execute();
db_truncate('watchdog')->execute();
drupal_set_message(t('Database log cleared.'));
}
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = dblog.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+9
View File
@@ -154,6 +154,15 @@ function dblog_update_7002() {
db_add_index('watchdog', 'severity', array('severity'));
}
/**
* Account for possible legacy systems where dblog was not installed.
*/
function dblog_update_7003() {
if (!db_table_exists('watchdog')) {
db_create_table('watchdog', drupal_get_schema_unprocessed('dblog', 'watchdog'));
}
}
/**
* @} End of "addtogroup updates-7.x-extra".
*/
+24 -14
View File
@@ -144,20 +144,30 @@ function _dblog_get_message_types() {
* Note: Some values may be truncated to meet database column size restrictions.
*/
function dblog_watchdog(array $log_entry) {
Database::getConnection('default', 'default')->insert('watchdog')
->fields(array(
'uid' => $log_entry['uid'],
'type' => substr($log_entry['type'], 0, 64),
'message' => $log_entry['message'],
'variables' => serialize($log_entry['variables']),
'severity' => $log_entry['severity'],
'link' => substr($log_entry['link'], 0, 255),
'location' => $log_entry['request_uri'],
'referer' => $log_entry['referer'],
'hostname' => substr($log_entry['ip'], 0, 128),
'timestamp' => $log_entry['timestamp'],
))
->execute();
if (!function_exists('drupal_substr')) {
require_once DRUPAL_ROOT . '/includes/unicode.inc';
}
try {
Database::getConnection('default', 'default')->insert('watchdog')
->fields(array(
'uid' => $log_entry['uid'],
'type' => drupal_substr($log_entry['type'], 0, 64),
'message' => $log_entry['message'],
'variables' => serialize($log_entry['variables']),
'severity' => $log_entry['severity'],
'link' => drupal_substr($log_entry['link'], 0, 255),
'location' => $log_entry['request_uri'],
'referer' => $log_entry['referer'],
'hostname' => drupal_substr($log_entry['ip'], 0, 128),
'timestamp' => $log_entry['timestamp'],
))
->execute();
}
catch (Exception $e) {
// Exception is ignored so that watchdog does not break pages during the
// installation process or is not able to create the watchdog table during
// installation.
}
}
/**
+61 -2
View File
@@ -119,13 +119,18 @@ class DBLogTestCase extends DrupalWebTestCase {
private function generateLogEntries($count, $type = 'custom', $severity = WATCHDOG_NOTICE) {
global $base_root;
// This long URL makes it just a little bit harder to pass the link part of
// the test with a mix of English words and a repeating series of random
// percent-encoded Chinese characters.
$link = urldecode('/content/xo%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A%E9%85%B1%E5%87%89%E6%8B%8C%E7%B4%A0%E9%B8%A1%E7%85%A7%E7%83%A7%E9%B8%A1%E9%BB%84%E7%8E%AB%E7%91%B0-%E7%A7%91%E5%B7%9E%E7%9A%84%E5%B0%8F%E4%B9%9D%E5%AF%A8%E6%B2%9F%E7%BB%9D%E7%BE%8E%E9%AB%98%E5%B1%B1%E6%B9%96%E6%B3%8A-lake-isabelle');
// Prepare the fields to be logged
$log = array(
'type' => $type,
'message' => 'Log entry added to test the dblog row limit.',
'variables' => array(),
'severity' => $severity,
'link' => NULL,
'link' => $link,
'user' => $this->big_user,
'uid' => isset($this->big_user->uid) ? $this->big_user->uid : 0,
'request_uri' => $base_root . request_uri(),
@@ -515,6 +520,33 @@ class DBLogTestCase extends DrupalWebTestCase {
$this->assertText(t('Database log cleared.'), 'Confirmation message found');
}
/**
* Verifies that exceptions are caught in dblog_watchdog().
*/
protected function testDBLogException() {
$log = array(
'type' => 'custom',
'message' => 'Log entry added to test watchdog handling of Exceptions.',
'variables' => array(),
'severity' => WATCHDOG_NOTICE,
'link' => NULL,
'user' => $this->big_user,
'uid' => isset($this->big_user->uid) ? $this->big_user->uid : 0,
'request_uri' => request_uri(),
'referer' => $_SERVER['HTTP_REFERER'],
'ip' => ip_address(),
'timestamp' => REQUEST_TIME,
);
// Remove watchdog table temporarily to simulate it missing during
// installation.
db_query("DROP TABLE {watchdog}");
// Add a watchdog entry.
// This should not throw an Exception, but fail silently.
dblog_watchdog($log);
}
/**
* Gets the database log event information from the browser page.
*
@@ -633,5 +665,32 @@ class DBLogTestCase extends DrupalWebTestCase {
// Document Object Model (DOM).
$this->assertLink(html_entity_decode($message_text), 0, $message);
}
}
/**
* Make sure HTML tags are filtered out in the log detail page.
*/
public function testLogMessageSanitized() {
$this->drupalLogin($this->big_user);
// Make sure dangerous HTML tags are filtered out in log detail page.
$log = array(
'uid' => 0,
'type' => 'custom',
'message' => "<script>alert('foo');</script> <strong>Lorem ipsum</strong>",
'variables' => NULL,
'severity' => WATCHDOG_NOTICE,
'link' => 'foo/bar',
'request_uri' => 'http://example.com?dblog=1',
'referer' => 'http://example.org?dblog=2',
'ip' => '0.0.1.0',
'timestamp' => REQUEST_TIME,
);
dblog_watchdog($log);
$wid = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
$this->drupalGet('admin/reports/event/' . $wid);
$this->assertResponse(200);
$this->assertNoRaw("<script>alert('foo');</script>");
$this->assertRaw("alert('foo'); <strong>Lorem ipsum</strong>");
}
}
+3 -3
View File
@@ -189,7 +189,7 @@ function field_create_field($field) {
}
// Clear caches
field_cache_clear(TRUE);
field_cache_clear();
// Invoke external hooks after the cache is cleared for API consistency.
module_invoke_all('field_create_field', $field);
@@ -288,7 +288,7 @@ function field_update_field($field) {
drupal_write_record('field_config', $field, $primary_key);
// Clear caches
field_cache_clear(TRUE);
field_cache_clear();
// Invoke external hooks after the cache is cleared for API consistency.
module_invoke_all('field_update_field', $field, $prior_field, $has_data);
@@ -430,7 +430,7 @@ function field_delete_field($field_name) {
->execute();
// Clear the cache.
field_cache_clear(TRUE);
field_cache_clear();
module_invoke_all('field_delete_field', $field);
}
+3 -3
View File
@@ -11,8 +11,8 @@ dependencies[] = field_sql_storage
required = TRUE
stylesheets[all][] = theme/field.css
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -1
View File
@@ -612,10 +612,12 @@ class FieldInfo {
// Fill in default values.
$display += array(
'label' => 'above',
'type' => $field_type_info['default_formatter'],
'settings' => array(),
'weight' => 0,
);
if (empty($display['type'])) {
$display['type'] = $field_type_info['default_formatter'];
}
if ($display['type'] != 'hidden') {
$formatter_type_info = field_info_formatter_types($display['type']);
// Fall back to default formatter if formatter type is not available.
+21
View File
@@ -467,6 +467,27 @@ function field_update_7003() {
// Empty update to force a rebuild of the registry.
}
/**
* Grant the new "administer fields" permission to trusted users.
*/
function field_update_7004() {
// Assign the permission to anyone that already has a trusted core permission
// that would have previously let them administer fields on an entity type.
$rids = array();
$permissions = array(
'administer site configuration',
'administer content types',
'administer users',
);
foreach ($permissions as $permission) {
$rids = array_merge($rids, array_keys(user_roles(FALSE, $permission)));
}
$rids = array_unique($rids);
foreach ($rids as $rid) {
_update_7000_user_role_grant_permissions($rid, array('administer fields'), 'field');
}
}
/**
* @} End of "addtogroup updates-7.x-extra".
*/
+15
View File
@@ -316,6 +316,21 @@ function field_help($path, $arg) {
}
}
/**
* Implements hook_permission().
*/
function field_permission() {
return array(
'administer fields' => array(
'title' => t('Administer fields'),
'description' => t('Additional permissions are required based on what the fields are attached to (for example, <a href="@url">administer content types</a> to manage fields attached to content).', array(
'@url' => '#module-node',
)),
'restrict access' => TRUE,
),
);
}
/**
* Implements hook_theme().
*/
@@ -7,8 +7,8 @@ dependencies[] = field
files[] = field_sql_storage.test
required = TRUE
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -7,8 +7,8 @@ dependencies[] = field
dependencies[] = options
files[] = tests/list.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+1 -1
View File
@@ -212,7 +212,7 @@ class ListFieldUITestCase extends FieldTestCase {
parent::setUp('field_test', 'field_ui');
// Create test user.
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer fields'));
$this->drupalLogin($admin_user);
// Create content type, with underscores.
@@ -5,8 +5,8 @@ package = Testing
version = VERSION
hidden = TRUE
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+3 -3
View File
@@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = number.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+13 -2
View File
@@ -164,6 +164,15 @@ function number_field_presave($entity_type, $entity, $field, $instance, $langcod
}
}
}
if ($field['type'] == 'number_float') {
// Remove the decimal point from float values with decimal
// point but no decimal numbers.
foreach ($items as $delta => $item) {
if (isset($item['value'])) {
$items[$delta]['value'] = floatval($item['value']);
}
}
}
}
/**
@@ -188,7 +197,7 @@ function number_field_formatter_info() {
'label' => t('Default'),
'field types' => array('number_integer'),
'settings' => array(
'thousand_separator' => ' ',
'thousand_separator' => '',
// The 'decimal_separator' and 'scale' settings are not configurable
// through the UI, and will therefore keep their default values. They
// are only present so that the 'number_integer' and 'number_decimal'
@@ -202,7 +211,7 @@ function number_field_formatter_info() {
'label' => t('Default'),
'field types' => array('number_decimal', 'number_float'),
'settings' => array(
'thousand_separator' => ' ',
'thousand_separator' => '',
'decimal_separator' => '.',
'scale' => 2,
'prefix_suffix' => TRUE,
@@ -222,6 +231,8 @@ function number_field_formatter_settings_form($field, $instance, $view_mode, $fo
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'number_decimal' || $display['type'] == 'number_integer') {
$options = array(
'' => t('<none>'),
+47 -1
View File
@@ -23,7 +23,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
function setUp() {
parent::setUp('field_test');
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer content types'));
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer content types', 'administer fields'));
$this->drupalLogin($this->web_user);
}
@@ -152,4 +152,50 @@ class NumberFieldTestCase extends DrupalWebTestCase {
);
$this->drupalPost(NULL, $edit, t('Save'));
}
/**
* Test number_float field.
*/
function testNumberFloatField() {
$this->field = array(
'field_name' => drupal_strtolower($this->randomName()),
'type' => 'number_float',
'settings' => array(
'precision' => 8, 'scale' => 4, 'decimal_separator' => '.',
)
);
field_create_field($this->field);
$this->instance = array(
'field_name' => $this->field['field_name'],
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
'widget' => array(
'type' => 'number',
),
'display' => array(
'default' => array(
'type' => 'number_float',
),
),
);
field_create_instance($this->instance);
$langcode = LANGUAGE_NONE;
$value = array(
'9.' => '9',
'.' => '0',
'123.55' => '123.55',
'.55' => '0.55',
'-0.55' => '-0.55',
);
foreach($value as $key => $value) {
$edit = array(
"{$this->field['field_name']}[$langcode][0][value]" => $key,
);
$this->drupalPost('test-entity/add/test-bundle', $edit, t('Save'));
$this->assertNoText("PDOException");
$this->assertRaw($value, 'Correct value is displayed.');
}
}
}
+3 -3
View File
@@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = options.test
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+9 -1
View File
@@ -185,6 +185,7 @@ function _options_properties($type, $multiple, $required, $has_value) {
$base = array(
'filter_xss' => FALSE,
'strip_tags' => FALSE,
'strip_tags_and_unescape' => FALSE,
'empty_option' => FALSE,
'optgroups' => FALSE,
);
@@ -195,7 +196,7 @@ function _options_properties($type, $multiple, $required, $has_value) {
case 'select':
$properties = array(
// Select boxes do not support any HTML tag.
'strip_tags' => TRUE,
'strip_tags_and_unescape' => TRUE,
'optgroups' => TRUE,
);
if ($multiple) {
@@ -271,9 +272,16 @@ function _options_prepare_options(&$options, $properties) {
_options_prepare_options($options[$value], $properties);
}
else {
// The 'strip_tags' option is deprecated. Use 'strip_tags_and_unescape'
// when plain text is required (and where the output will be run through
// check_plain() before being inserted back into HTML) or 'filter_xss'
// when HTML is required.
if ($properties['strip_tags']) {
$options[$value] = strip_tags($label);
}
if ($properties['strip_tags_and_unescape']) {
$options[$value] = decode_entities(strip_tags($label));
}
if ($properties['filter_xss']) {
$options[$value] = field_filter_xss($label);
}
+25 -8
View File
@@ -23,8 +23,15 @@ class OptionsWidgetsTestCase extends FieldTestCase {
'type' => 'list_integer',
'cardinality' => 1,
'settings' => array(
// Make sure that 0 works as an option.
'allowed_values' => array(0 => 'Zero', 1 => 'One', 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
'allowed_values' => array(
// Make sure that 0 works as an option.
0 => 'Zero',
1 => 'One',
// Make sure that option text is properly sanitized.
2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
// Make sure that HTML entities in option text are not double-encoded.
3 => 'Some HTML encoded markup with &lt; &amp; &gt;',
),
),
);
$this->card_1 = field_create_field($this->card_1);
@@ -35,8 +42,13 @@ class OptionsWidgetsTestCase extends FieldTestCase {
'type' => 'list_integer',
'cardinality' => 2,
'settings' => array(
// Make sure that 0 works as an option.
'allowed_values' => array(0 => 'Zero', 1 => 'One', 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
'allowed_values' => array(
// Make sure that 0 works as an option.
0 => 'Zero',
1 => 'One',
// Make sure that option text is properly sanitized.
2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
),
),
);
$this->card_2 = field_create_field($this->card_2);
@@ -47,14 +59,18 @@ class OptionsWidgetsTestCase extends FieldTestCase {
'type' => 'list_boolean',
'cardinality' => 1,
'settings' => array(
// Make sure that 0 works as a 'on' value'.
'allowed_values' => array(1 => 'Zero', 0 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>'),
'allowed_values' => array(
// Make sure that 1 works as a 'on' value'.
1 => 'Zero',
// Make sure that option text is properly sanitized.
0 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
),
),
);
$this->bool = field_create_field($this->bool);
// Create a web user.
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
$this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer fields'));
$this->drupalLogin($this->web_user);
}
@@ -233,6 +249,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
$this->assertNoOptionSelected("edit-card-1-$langcode", 1);
$this->assertNoOptionSelected("edit-card-1-$langcode", 2);
$this->assertRaw('Some dangerous &amp; unescaped markup', 'Option text was properly filtered.');
$this->assertRaw('Some HTML encoded markup with &lt; &amp; &gt;', 'HTML entities in option text were properly handled and not double-encoded');
// Submit form: select invalid 'none' option.
$edit = array("card_1[$langcode]" => '_none');
@@ -459,7 +476,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
$this->assertNoFieldChecked("edit-bool-$langcode");
// Create admin user.
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer fields'));
$this->drupalLogin($admin_user);
// Create a test field instance.
+3 -3
View File
@@ -7,8 +7,8 @@ dependencies[] = field
files[] = text.test
required = TRUE
; Information added by Drupal.org packaging script on 2015-08-19
version = "7.39"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1440020197"
datestamp = "1522264019"
+4 -2
View File
@@ -223,11 +223,13 @@ function text_field_formatter_settings_form($field, $instance, $view_mode, $form
if (strpos($display['type'], '_trimmed') !== FALSE) {
$element['trim_length'] = array(
'#title' => t('Trim length'),
'#title' => t('Trimmed limit'),
'#type' => 'textfield',
'#field_suffix' => t('characters'),
'#size' => 10,
'#default_value' => $settings['trim_length'],
'#element_validate' => array('element_validate_integer_positive'),
'#description' => t('If the summary is not set, the trimmed %label field will be shorter than this character limit.', array('%label' => $instance['label'])),
'#required' => TRUE,
);
}
@@ -245,7 +247,7 @@ function text_field_formatter_settings_summary($field, $instance, $view_mode) {
$summary = '';
if (strpos($display['type'], '_trimmed') !== FALSE) {
$summary = t('Trim length') . ': ' . check_plain($settings['trim_length']);
$summary = t('Trimmed limit: @trim_length characters', array('@trim_length' => $settings['trim_length']));
}
return $summary;

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