Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d8adc672 | ||
|
|
138b68ac98 | ||
|
|
026a9bc241 | ||
|
|
adb1437a44 | ||
|
|
5d17730143 | ||
|
|
1ec80dc60e | ||
|
|
5423f6d3bc | ||
|
|
1ccc5d07d6 | ||
|
|
597e6c9159 | ||
|
|
b26db27098 | ||
|
|
b9ac935de6 | ||
|
|
091c01ce81 | ||
|
|
039f49aded | ||
|
|
cc295255a1 | ||
|
|
fedd8f4216 | ||
|
|
73f871cbcc | ||
|
|
0f286a2d78 | ||
|
|
ac87a57196 | ||
|
|
b00f897952 | ||
|
|
99f92edb37 | ||
|
|
d0566a6155 | ||
|
|
0bf7b4a1c8 | ||
|
|
2f02bb6485 | ||
|
|
a477dbb8ec | ||
|
|
d4fee57337 | ||
|
|
c97d1d7f75 | ||
|
|
c7e2de9e8b | ||
|
|
cc000ce3d6 | ||
|
|
7abf64be00 | ||
|
|
e8cadc31e1 | ||
|
|
7011e6c691 | ||
|
|
c70a4bed11 | ||
|
|
252abe9b0e | ||
|
|
773e7fbddd | ||
|
|
8d24211bf5 | ||
|
|
86c993f638 | ||
|
|
08127672d6 | ||
|
|
66fa1d419d | ||
|
|
0521608bb7 | ||
|
|
fdefc824d8 | ||
|
|
2b028cf376 | ||
|
|
d1963312a6 | ||
|
|
3b6c7b914d | ||
|
|
0bb339fc99 | ||
|
|
3413d81bb8 | ||
|
|
7aeabebddf | ||
|
|
2e0abeed03 | ||
|
|
82bb633c3e | ||
|
|
104fcaf970 | ||
|
|
34649ab98b | ||
|
|
9c43ba2fc6 | ||
|
|
1f780c974e | ||
|
|
2ed8b48636 | ||
|
|
d712e5881a | ||
|
|
253524c527 | ||
|
|
ae7349e811 | ||
|
|
c64b25b261 | ||
|
|
992c9a552a | ||
|
|
a2db826449 | ||
|
|
b11abbed59 | ||
|
|
f6f7fd575f | ||
|
|
610760bedf | ||
|
|
54399b169a | ||
|
|
598f3e8292 | ||
|
|
0347c5cb99 | ||
|
|
1f5092fb45 | ||
|
|
31d638cff7 | ||
|
|
31409daed2 | ||
|
|
42347006ff | ||
|
|
dd95b24f5b | ||
|
|
507402d07b | ||
|
|
e310490c7f | ||
|
|
918b4cd5e1 | ||
|
|
deae7e0b59 | ||
|
|
c64551f50c | ||
|
|
73793c9ba9 | ||
|
|
d38e929be5 | ||
|
|
266fb10083 | ||
|
|
6fee348360 | ||
|
|
74f8c52af3 | ||
|
|
9c97849d78 | ||
|
|
2ca9694d84 | ||
|
|
422322c96d | ||
|
|
aea9683c77 | ||
|
|
e2fde76aff | ||
|
|
fb0666538c | ||
|
|
3a55dcea49 | ||
|
|
39dc81ad14 | ||
|
|
7b11f2794e | ||
|
|
c23706f745 | ||
|
|
c47d792cd1 | ||
|
|
d7697f0f76 | ||
|
|
b27aabe359 | ||
|
|
8fb9c70e42 | ||
|
|
1658e609f8 | ||
|
|
e36279d8b1 | ||
|
|
0b6e0c10cb | ||
|
|
ba1ec7113e | ||
|
|
deb2bff572 | ||
|
|
538c791bae | ||
|
|
df107a0443 | ||
|
|
c9b16289ef | ||
|
|
b4acd7d8bb | ||
|
|
3af02617b4 | ||
|
|
0fdb4abd71 | ||
|
|
90be34eef1 | ||
|
|
3e984dc6c5 | ||
|
|
a0cb0b2171 | ||
|
|
f6346b0195 | ||
|
|
300f698989 | ||
|
|
8cbb5f8c4c | ||
|
|
a106b98209 | ||
|
|
8fe92dbcc7 | ||
|
|
60f2c5c7fa | ||
|
|
d96c17454b | ||
|
|
ed6ae84181 | ||
|
|
35e914df58 | ||
|
|
6b46869a16 | ||
|
|
892dba801f | ||
|
|
50dfd2d89b | ||
|
|
9a18821b7e | ||
|
|
82bf36a5eb | ||
|
|
3eb20676ca | ||
|
|
2155a66eb1 | ||
|
|
62fef652fc | ||
|
|
951c9114a2 | ||
|
|
edba04f103 | ||
|
|
26ab9aa56b | ||
|
|
5716acf5bb | ||
|
|
12fe570fbd | ||
|
|
66ee9c6657 | ||
|
|
ca5231f1fe | ||
|
|
b9a8db8140 | ||
|
|
d25e7428bc | ||
|
|
3027b3985b | ||
|
|
d214a44291 | ||
|
|
fc7753f7a0 | ||
|
|
7c51b255fb | ||
|
|
5e099d48de | ||
|
|
bf84ac06cd | ||
|
|
87beabee92 | ||
|
|
f6ee366a71 | ||
|
|
b216e30f28 | ||
|
|
0a863fc1bb | ||
|
|
a5edc41323 | ||
|
|
1cc2c9af75 | ||
|
|
cc653b73be | ||
|
|
73993a539b | ||
|
|
d7e7410950 | ||
|
|
7298235d4f | ||
|
|
fc0a779214 | ||
|
|
248c5ed3e1 | ||
|
|
ace9de07e2 | ||
|
|
7ad1f5dc67 | ||
|
|
d5628cc78e | ||
|
|
81371521c7 | ||
|
|
eb699f528d | ||
|
|
0ba0c21bb9 | ||
|
|
50c3e1c7d7 | ||
|
|
f0cb6175c1 | ||
|
|
e004b7a238 | ||
|
|
f7cd9c0858 | ||
|
|
5d30d9bcee | ||
|
|
c4f2e62697 | ||
|
|
a99f2d7aa6 | ||
|
|
4e8346e5e3 | ||
|
|
5b281024a5 | ||
|
|
96903cab02 | ||
|
|
ce20bb3f0f | ||
|
|
19d3d90743 | ||
|
|
62fec82217 | ||
|
|
f0295847f9 | ||
|
|
cc657eaec4 | ||
|
|
54f496acad | ||
|
|
feef7951cd | ||
|
|
8def2961ac | ||
|
|
1c38e1b72a | ||
|
|
0446c17ad1 | ||
|
|
459335fee1 | ||
|
|
408251fd28 | ||
|
|
98d1b5cb03 | ||
|
|
141d1f4b5c | ||
|
|
100dce022a | ||
|
|
3220ed8e4b | ||
|
|
22146c2778 | ||
|
|
f4b8bfa249 | ||
|
|
4c32c73321 | ||
|
|
09d1f06552 | ||
|
|
ade4a41f76 | ||
|
|
19b1d49a22 | ||
|
|
4264a271b4 | ||
|
|
de040b46ea | ||
|
|
aa323869c3 | ||
|
|
22e93d650e | ||
|
|
2664d2fcfd | ||
|
|
feb93503b6 | ||
|
|
2d5be00cf1 | ||
|
|
a84cd67456 | ||
|
|
8a1f5cd116 | ||
|
|
65c7ab92b6 | ||
|
|
1c1de98039 | ||
|
|
2e4a069036 | ||
|
|
cc8306bc14 | ||
|
|
d107702f86 | ||
|
|
f9144db774 | ||
|
|
1ca1912fe2 | ||
|
|
1657634e1a | ||
|
|
a908bb02ca | ||
|
|
4eadc1b771 | ||
|
|
ce2f811278 | ||
|
|
1c42c93c54 | ||
|
|
71744db508 | ||
|
|
3add8f6b96 | ||
|
|
678343b0e9 | ||
|
|
5485f80dae | ||
|
|
6df0ebfa53 | ||
|
|
9521fc1ce5 | ||
|
|
1f1247a226 | ||
|
|
b05c9a53c5 | ||
|
|
b2d9b7dbf7 | ||
|
|
98bc1dfef8 | ||
|
|
d35191a96e | ||
|
|
2fd09f23e9 | ||
|
|
181a28cd85 | ||
|
|
d5155b3b31 | ||
|
|
32f26b4bf5 | ||
|
|
1b9752f495 | ||
|
|
afd3a90538 | ||
|
|
96aef8c128 | ||
|
|
73741839ca | ||
|
|
8a8ed4f929 | ||
|
|
e12a664fa5 | ||
|
|
6ceb7d6534 | ||
|
|
3ffbc09c10 | ||
|
|
49004d7fee | ||
|
|
706c96d663 | ||
|
|
c9f8dc21ed | ||
|
|
59cec97bcf | ||
|
|
c2a05d8ab3 | ||
|
|
f75cb5562c | ||
|
|
342655bf2b | ||
|
|
f9f0ce54ec | ||
|
|
0c29476b3f | ||
|
|
c183a0b0dd | ||
|
|
ea423f2146 | ||
|
|
580c97dc49 | ||
|
|
95cbb13821 | ||
|
|
ddae683ff3 | ||
|
|
c90787212b | ||
|
|
81ea02bb3e | ||
|
|
d9f6370962 | ||
|
|
40e4643644 | ||
|
|
76c59dc2a9 | ||
|
|
ae3b3d3895 | ||
|
|
d858f00e17 | ||
|
|
f28719a994 | ||
|
|
922a2da1e5 | ||
|
|
26bb2de5b8 | ||
|
|
e4b76f4756 | ||
|
|
2686166df2 | ||
|
|
1f211d5348 | ||
|
|
b3c85e79c6 | ||
|
|
2ffa37fefa | ||
|
|
70151f23e1 | ||
|
|
79bd95aeec | ||
|
|
3a53525bf9 | ||
|
|
54787232fb | ||
|
|
69c5b7ee5c | ||
|
|
8d141a61e0 | ||
|
|
19a68f970e | ||
|
|
de8f5e4ccc | ||
|
|
442d89c948 | ||
|
|
3adb83ccf7 | ||
|
|
68b11d7a9b | ||
|
|
58e171be01 | ||
|
|
da4d135279 | ||
|
|
1313e1f0e2 | ||
|
|
e4885c3a5d | ||
|
|
f8a18606ba | ||
|
|
23b96ab26f | ||
|
|
8c920e81df | ||
|
|
202993e68e | ||
|
|
8589ce7c28 | ||
|
|
17580e8eba | ||
|
|
ca9530466a | ||
|
|
31ede7287a | ||
|
|
be2054c163 | ||
|
|
a20d86efbf | ||
|
|
0795a2a514 | ||
|
|
c92d7ed737 | ||
|
|
923b407498 | ||
|
|
ceeefdd109 | ||
|
|
a1fd56580b | ||
|
|
23c085213e | ||
|
|
0ba300fe22 | ||
|
|
7763d08111 | ||
|
|
e1819172e9 | ||
|
|
08b4b2dbbb | ||
|
|
42940e2cff | ||
|
|
9dfbaeb05a | ||
|
|
d69e29e3be | ||
|
|
b85dc130d6 | ||
|
|
d8626dbb2d | ||
|
|
4d3a184a81 | ||
|
|
eeb0df349d | ||
|
|
785dee0639 | ||
|
|
9afc105c7e | ||
|
|
0cd6215a32 | ||
|
|
c5028bffd3 | ||
|
|
ca9413af4d | ||
|
|
d3dcf44a1e | ||
|
|
6737f9faa1 | ||
|
|
322dd995bf | ||
|
|
cde7b73a73 | ||
|
|
2121a356b3 | ||
|
|
55b23a2cec | ||
|
|
134c8b8338 | ||
|
|
7c85261e56 | ||
|
|
37fbabab56 | ||
|
|
6a8d30db08 | ||
|
|
d5a03170e4 | ||
|
|
36b5937b9e | ||
|
|
49f9128c96 | ||
|
|
46b448c2a2 | ||
|
|
73186732c3 | ||
|
|
f71bfe281e | ||
|
|
9de02bab38 | ||
|
|
6719ca32c7 | ||
|
|
e89afbf603 | ||
|
|
a1856277e5 | ||
|
|
7becdeff92 | ||
|
|
f55c541343 | ||
|
|
1f82c4ef9b | ||
|
|
c0af9037e9 | ||
|
|
b3221c71e2 | ||
|
|
802ec0c6f3 | ||
|
|
6de56c702c | ||
|
|
f2b8ace9b7 | ||
|
|
7b6bd36fea | ||
|
|
8dc0b20c89 | ||
|
|
87f453cf20 | ||
|
|
5594bacfa9 | ||
|
|
8d74b0bb06 | ||
|
|
b285de8b3a | ||
|
|
775d25dbcc | ||
|
|
a181091a14 | ||
|
|
72cf8934c3 | ||
|
|
627216cb77 | ||
|
|
8ff8fcd8da | ||
|
|
178cfe05d0 | ||
|
|
879cd137d5 | ||
|
|
7b975a5cab | ||
|
|
ad76968844 | ||
|
|
c2252c8f9a | ||
|
|
1be1c89407 | ||
|
|
aceb299147 | ||
|
|
404757203b | ||
|
|
f0531608b7 | ||
|
|
28db07faf7 | ||
|
|
88c1012c48 | ||
|
|
a494bb4627 | ||
|
|
894a4849e0 | ||
|
|
886114f49b | ||
|
|
ae12eada47 | ||
|
|
51cc1bb7b2 | ||
|
|
f63556f674 | ||
|
|
29079eeb84 | ||
|
|
bf88fdf0b9 | ||
|
|
265c4ab336 | ||
|
|
c36797f2bb | ||
|
|
e5b63e455f | ||
|
|
ab1e9ae0ff | ||
|
|
6b3f29142b | ||
|
|
77450f1aad | ||
|
|
11617ec99c | ||
|
|
d1b96a77a6 | ||
|
|
077d83613e | ||
|
|
d2cffdeddd | ||
|
|
4237cb8edb | ||
|
|
88d4cf09dc | ||
|
|
1cc9a63c46 | ||
|
|
0bba2d0657 | ||
|
|
8e138e1153 | ||
|
|
ccb121e83a | ||
|
|
8f54fcd944 | ||
|
|
98f738f951 | ||
|
|
ef50154a49 | ||
|
|
982122065e | ||
|
|
80e491f1d8 | ||
|
|
c5f5eb4f64 | ||
|
|
7d410e8393 | ||
|
|
afce4662bd | ||
|
|
ab40bcf861 | ||
|
|
497a0108ae | ||
|
|
9f3444676a | ||
|
|
0545fabe49 | ||
|
|
37ac75fc59 | ||
|
|
6fdb4e0dc9 | ||
|
|
124e1a7bc2 | ||
|
|
7ee6c9dc12 | ||
|
|
e9a136db4c | ||
|
|
f515e148f4 | ||
|
|
aed0b98da2 | ||
|
|
ccd86a08a4 | ||
|
|
8f32d4e98b | ||
|
|
e82e3250b3 | ||
|
|
2e1e0cc05b | ||
|
|
488d4c19aa | ||
|
|
ce18a79a80 | ||
|
|
41e7f80383 | ||
|
|
8aabfe2592 | ||
|
|
847eb41741 | ||
|
|
6c4d1ed8f5 | ||
|
|
854a6cc680 | ||
|
|
4691968631 | ||
|
|
10c50db9e2 | ||
|
|
a645ef87b4 | ||
|
|
d214a86eeb | ||
|
|
5cbbf7cbf5 | ||
|
|
3310c6fad6 | ||
|
|
4756fdaf77 | ||
|
|
7580376050 | ||
|
|
acaa381d3d | ||
|
|
c3011cef61 | ||
|
|
5835745cc2 | ||
|
|
bf41479abc | ||
|
|
f4ae3c9055 | ||
|
|
28deeac474 | ||
|
|
0c71144833 | ||
|
|
f881f8b638 | ||
|
|
1eb8bb9de8 | ||
|
|
5b26e36355 | ||
|
|
9df43555ac | ||
|
|
e2183f0a0d | ||
|
|
c4d8c34e1a | ||
|
|
748548f8f4 | ||
|
|
5d0c233fec | ||
|
|
05a41ebf3a | ||
|
|
a08a5287fc | ||
|
|
ae72f70488 | ||
|
|
c8a37f4255 | ||
|
|
df548917f6 | ||
|
|
40fe76b2cf | ||
|
|
5b7b67573f | ||
|
|
a613426482 | ||
|
|
e371e746ff | ||
|
|
148e2db56e | ||
|
|
332c17c25c | ||
|
|
a64d6e34d8 | ||
|
|
6394330226 | ||
|
|
76efcb0778 | ||
|
|
f6d5c40ae2 | ||
|
|
9d2fee4ddd | ||
|
|
d7dddd5764 | ||
|
|
4d0605604f | ||
|
|
100abc9a3a | ||
|
|
094eb50691 | ||
|
|
7b99c14d96 | ||
|
|
c06be9a44e | ||
|
|
6ccf2ddb91 | ||
|
|
3757a19ce7 | ||
|
|
891166f86e | ||
|
|
85251183d6 | ||
|
|
54ee5c7b3a | ||
|
|
6402fc7ab8 | ||
|
|
d7303905a0 | ||
|
|
cf03e9ca52 | ||
|
|
60cc747699 | ||
|
|
d9298146fa | ||
|
|
1cc99f26e1 | ||
|
|
5cde537e0a | ||
|
|
0799729429 | ||
|
|
3fe3dde8c2 | ||
|
|
5d6f96ed0e | ||
|
|
983f51e711 | ||
|
|
85be86a9e4 | ||
|
|
ffff23584e | ||
|
|
770e2155bb | ||
|
|
90c6d5e6e9 | ||
|
|
e1a04d9b8e | ||
|
|
3d36e980af | ||
|
|
acb87f238a | ||
|
|
7230dafd5f | ||
|
|
9af55b03bd | ||
|
|
10de06dd70 | ||
|
|
572f88b950 | ||
|
|
52d0c3b77e | ||
|
|
794ccba61a | ||
|
|
925324448b | ||
|
|
64ebb28c01 | ||
|
|
d35f79e2cf | ||
|
|
c3c0c71945 | ||
|
|
91c826322e | ||
|
|
ab51102cd0 | ||
|
|
77414c7cb9 | ||
|
|
7aa6dfe191 | ||
|
|
ca6c5bd4fa | ||
|
|
e960755e20 | ||
|
|
09d80d2c63 | ||
|
|
5daabaaf5a | ||
|
|
8909491a12 | ||
|
|
051455cd71 | ||
|
|
235e57d8e9 | ||
|
|
ca63b9bbca | ||
|
|
cb791f03ff | ||
|
|
7a46e22394 | ||
|
|
3bdbc68690 | ||
|
|
33ce5d0e40 | ||
|
|
8e478340a2 | ||
|
|
78fa0756a9 | ||
|
|
176b1c05d9 | ||
|
|
acbf965c77 | ||
|
|
bd98c3d7f6 | ||
|
|
1c56076189 | ||
|
|
e0ab0fd0d5 | ||
|
|
b58a00a4c8 | ||
|
|
4d81ea318d | ||
|
|
77cb87b49d | ||
|
|
5203118606 | ||
|
|
39759425ce | ||
|
|
62b7436183 | ||
|
|
d8237ffb99 | ||
|
|
a30917d1d2 | ||
|
|
e6aed1cba0 | ||
|
|
16ed68abf6 | ||
|
|
128640cd15 | ||
|
|
7e3ef32d18 | ||
|
|
d4d5acf837 | ||
|
|
2b45f07449 | ||
|
|
9faad4a27d | ||
|
|
32e4448773 | ||
|
|
e539e701f8 | ||
|
|
db5f70501a | ||
|
|
f47c978520 | ||
|
|
4362f6dc23 | ||
|
|
eeccd6a4d2 | ||
|
|
8672e5eb9f | ||
|
|
f1c9615e4a | ||
|
|
9eb6fe8360 | ||
|
|
2d18c524eb | ||
|
|
afd4de26e7 | ||
|
|
7c486da7c5 | ||
|
|
0ccaf2eeeb | ||
|
|
5fd46660b9 | ||
|
|
70b4f2279f | ||
|
|
2f95c828e6 | ||
|
|
1923036d97 | ||
|
|
49db4b90be | ||
|
|
6c85be6c6d | ||
|
|
ee27274830 | ||
|
|
84542b241d | ||
|
|
e99ac67b73 | ||
|
|
5a4cadabf6 | ||
|
|
df0ec71ac7 | ||
|
|
93c278c5e8 | ||
|
|
13d6d3b95b | ||
|
|
e0ae80791b | ||
|
|
dfe36ba913 | ||
|
|
caf3bf662c | ||
|
|
66e87e0bf4 | ||
|
|
b2873ad5b1 | ||
|
|
f43260082d | ||
|
|
bef27e8258 | ||
|
|
443e4fc138 | ||
|
|
09ac2a24ac | ||
|
|
789d8708bf | ||
|
|
578adab53b | ||
|
|
10c9d53c31 | ||
|
|
29f7711833 | ||
|
|
9cc5ba4cfa | ||
|
|
644b7db597 | ||
|
|
779d42d9bb | ||
|
|
78b816920d | ||
|
|
f5e39e1209 | ||
|
|
c9912105d5 | ||
|
|
6a402551d7 | ||
|
|
5b845da277 | ||
|
|
763ce99b95 | ||
|
|
f207e56b2d | ||
|
|
06a4d254c2 | ||
|
|
de59738907 | ||
|
|
a575bce275 | ||
|
|
2fdd8fb95c | ||
|
|
e573564b93 | ||
|
|
454adf9478 | ||
|
|
b181133e60 | ||
|
|
e7d0e34651 | ||
|
|
f0f9635e8b | ||
|
|
7a3ee63d15 | ||
|
|
8f492c8b4e | ||
|
|
108f77c73d | ||
|
|
0db5022c47 | ||
|
|
d01d0a2a7e | ||
|
|
2b137c6a19 | ||
|
|
cb6963919c | ||
|
|
39db0ed16d | ||
|
|
87edb46954 | ||
|
|
f9a60fe62d | ||
|
|
c60696ba2b | ||
|
|
90adf0ad52 | ||
|
|
2506c8b8ac | ||
|
|
d6bc2debdf | ||
|
|
438ebb75ad | ||
|
|
cb5ba1c633 | ||
|
|
432b8ee65e | ||
|
|
72e2d8a7f4 | ||
|
|
2fff41d01d | ||
|
|
83fbaa4669 | ||
|
|
184a808558 | ||
|
|
63465d9076 | ||
|
|
ca2ebbf0c8 | ||
|
|
a59e01d581 | ||
|
|
5a82c8394d | ||
|
|
1f9bef33b9 | ||
|
|
1e40a74e1a | ||
|
|
b8b7044eb3 | ||
|
|
739f52c1df | ||
|
|
64bf6b3fa2 | ||
|
|
df986ba09a | ||
|
|
1377500ccc | ||
|
|
7bd9dd6d80 | ||
|
|
e1d0639eee | ||
|
|
618d68bd70 | ||
|
|
1bcda42052 | ||
|
|
89e7b9de6e | ||
|
|
4caa0c442b | ||
|
|
18eea497c3 | ||
|
|
c3f366a045 | ||
|
|
fc0253d9c2 | ||
|
|
a6f0f199b5 | ||
|
|
b20b38f514 | ||
|
|
feae2e1f34 | ||
|
|
b0f5c3eae0 | ||
|
|
bcf209570a | ||
|
|
b7ab35d6aa | ||
|
|
3b2eb43c8f | ||
|
|
4ef59776b0 | ||
|
|
f276e09115 | ||
|
|
3eaa5817e0 | ||
|
|
0600bf6674 | ||
|
|
1cd7c773a5 | ||
|
|
2601c718c2 | ||
|
|
61c83b5a75 | ||
|
|
a2b9816e52 | ||
|
|
f3be35fe5e | ||
|
|
707403f8e7 | ||
|
|
d2285db42a | ||
|
|
7dafe10be1 | ||
|
|
d97c0a2e45 | ||
|
|
63df1c8f3a | ||
|
|
6793ae61a6 | ||
|
|
d3b84b7733 | ||
|
|
0e49c6cedf | ||
|
|
948913bc82 | ||
|
|
b1bf1c9387 | ||
|
|
1d11663ec4 | ||
|
|
df2c715315 | ||
|
|
d77d7e5ef7 | ||
|
|
8e956c857b | ||
|
|
ef943eba75 | ||
|
|
b750ae41c4 | ||
|
|
761ffba48d | ||
|
|
e218aeb4da | ||
|
|
493d3bf780 | ||
|
|
f8af96a85b | ||
|
|
2248bfd12e | ||
|
|
65ea77dea2 | ||
|
|
edc3e1f685 | ||
|
|
7022567394 | ||
|
|
4b1685af04 | ||
|
|
7884444ec6 | ||
|
|
aff5ecb650 | ||
|
|
9a18131bcf | ||
|
|
ce04398f78 | ||
|
|
6022c4547f | ||
|
|
a981ba0fcd | ||
|
|
a3196f9486 | ||
|
|
c259bc4543 | ||
|
|
04d628c609 | ||
|
|
3faebabce1 | ||
|
|
a7b1a91c6f | ||
|
|
900155d078 | ||
|
|
aa8698232d | ||
|
|
2543d32599 | ||
|
|
3b4f1e024f | ||
|
|
476ccd94fe | ||
|
|
86d0eb03f5 | ||
|
|
789a40d106 | ||
|
|
2697ba8675 | ||
|
|
c811ffcb26 | ||
|
|
c952bd330f | ||
|
|
6c13226969 | ||
|
|
3ca910cf34 | ||
|
|
40b0b8bae2 | ||
|
|
0370c6233d | ||
|
|
fb30fe966e | ||
|
|
68126583b1 | ||
|
|
2030a6f810 | ||
|
|
256475e716 | ||
|
|
5e63575d94 | ||
|
|
ad7809415c | ||
|
|
0685b2dc63 | ||
|
|
0ed294ff52 | ||
|
|
addf98f5ab | ||
|
|
89159da2cf | ||
|
|
4cf9d7b2c6 | ||
|
|
35a5eb3a60 | ||
|
|
c0a9653975 | ||
|
|
b920153c13 | ||
|
|
18982b6700 | ||
|
|
7ce8d94ed9 | ||
|
|
45c41b319d | ||
|
|
461c93d48a | ||
|
|
47348748c4 | ||
|
|
e31dc0d4fc | ||
|
|
9e85e7a105 | ||
|
|
b861d2da15 | ||
|
|
2a9aca944c | ||
|
|
1896d11e80 | ||
|
|
b4b346b8a5 | ||
|
|
93b7db54fe | ||
|
|
760047e9fc | ||
|
|
94bf329b91 | ||
|
|
93b353922e | ||
|
|
df91706e57 | ||
|
|
4eda04b2f0 | ||
|
|
f4fc36431c | ||
|
|
292f704f37 | ||
|
|
420f792a08 | ||
|
|
4a958da4df | ||
|
|
5b16446d2f | ||
|
|
f62d12ba55 | ||
|
|
8b5f7c5ccb | ||
|
|
11d4a60bfc | ||
|
|
6a13522171 | ||
|
|
9d97a0b7b7 | ||
|
|
746109f079 | ||
|
|
20ad82694b | ||
|
|
49bdef396b | ||
|
|
9d10e145b4 | ||
|
|
e0eae18f29 | ||
|
|
6ab6fc916b | ||
|
|
dcd5bf483e | ||
|
|
0a062a5297 | ||
|
|
f50849a3a3 | ||
|
|
7f1b21c912 | ||
|
|
fbaa166db8 | ||
|
|
60518fcfc2 | ||
|
|
747fef9a0a | ||
|
|
0c65f95fbb | ||
|
|
4fc8e542c3 | ||
|
|
8690f4a165 | ||
|
|
26591bf350 | ||
|
|
66ff837039 | ||
|
|
40f34e2191 | ||
|
|
f83a0b9aee | ||
|
|
626ec7eabc | ||
|
|
c22eb6bc11 | ||
|
|
01aecdfd57 | ||
|
|
d84e570b3c | ||
|
|
7351bc66a0 | ||
|
|
691ecd7d61 | ||
|
|
930913e764 | ||
|
|
09bea7c003 | ||
|
|
d23f6ab12d | ||
|
|
aa857c3a40 | ||
|
|
ad30a381f9 | ||
|
|
951be207ab | ||
|
|
8ec280d5fa | ||
|
|
072342016d | ||
|
|
5427717666 | ||
|
|
a19cf5aae0 | ||
|
|
000cc37f2f | ||
|
|
4d9851e410 | ||
|
|
9cdd779930 | ||
|
|
e3e87a93d7 | ||
|
|
ea30728ec8 | ||
|
|
8a187e010b | ||
|
|
03cc8469dc | ||
|
|
4430806082 | ||
|
|
d9f856a075 | ||
|
|
b50c953eeb | ||
|
|
5109e619cc | ||
|
|
d5ce155335 | ||
|
|
de47d2f980 | ||
|
|
b8566401fd | ||
|
|
8008cecb85 | ||
|
|
2281eac5c1 | ||
|
|
202280fa6b | ||
|
|
c198b6f75f | ||
|
|
13e221324c | ||
|
|
f3409f422e | ||
|
|
1e627725ac | ||
|
|
18f4b720a8 | ||
|
|
b21bbdb14f | ||
|
|
0dbc7d7df4 | ||
|
|
b2b3f7f0b4 | ||
|
|
5c42f3c952 | ||
|
|
cc52ea5af6 | ||
|
|
a570618597 | ||
|
|
b6333de34e | ||
|
|
cc43fb6fa3 | ||
|
|
53a2bce0bd | ||
|
|
a42aa98302 | ||
|
|
c98cff88e7 | ||
|
|
c3abc04ce2 | ||
|
|
d8f75a77e1 | ||
|
|
23a553dc8b | ||
|
|
d45e0979fa | ||
|
|
f0db5b9d05 | ||
|
|
2f6f865e33 | ||
|
|
ebdc82203b | ||
|
|
f55e651074 | ||
|
|
5ef33d2fa2 | ||
|
|
f3935ae423 | ||
|
|
0dd46f5214 | ||
|
|
5c6bec1d8a | ||
|
|
67bf2e51ad | ||
|
|
71f74b5565 | ||
|
|
f9b542c391 | ||
|
|
57a7629b29 | ||
|
|
ebb1ab6ce1 | ||
|
|
3d8955fb48 | ||
|
|
36d7d5cf37 | ||
|
|
778c49b92e | ||
|
|
31259736e3 | ||
|
|
08fe6616f9 | ||
|
|
3ce126eb48 | ||
|
|
d32378cf35 | ||
|
|
2ca8cc7e56 | ||
|
|
53f9178ff0 | ||
|
|
a5276dfe41 | ||
|
|
21563d09ce | ||
|
|
4d03934230 | ||
|
|
ec97ad2402 | ||
|
|
ccd2494fb7 | ||
|
|
6b915cda88 | ||
|
|
eb09ab5342 | ||
|
|
cd38617398 | ||
|
|
659a21255a | ||
|
|
4687549e89 | ||
|
|
ba3b8e51d1 | ||
|
|
6085946d1d | ||
|
|
a5022b38fc | ||
|
|
831fbf4e0f | ||
|
|
7bbcc73ae8 | ||
|
|
6f6aef2e67 | ||
|
|
cb22790246 | ||
|
|
cca7f982e4 | ||
|
|
50807fe40f | ||
|
|
60cc6ae1a3 | ||
|
|
1ed6151591 | ||
|
|
0c661bcbd4 | ||
|
|
1251927952 | ||
|
|
5ca8a4fc6c | ||
|
|
44e1fc9296 | ||
|
|
24bb9a57bb | ||
|
|
911791b362 | ||
|
|
44264836be |
@@ -1,13 +1,26 @@
|
||||
# Ignore configuration files that may contain sensitive information.
|
||||
sites/*/settings*.php
|
||||
sites/*/drushrc*
|
||||
|
||||
# Ignore paths that contain user-generated content.
|
||||
sites/*
|
||||
#sites/*/files
|
||||
#sites/*/private
|
||||
#sites/*
|
||||
sites/*/files
|
||||
sites/*/private
|
||||
sites/all/translations/*
|
||||
|
||||
_base_d7.tmproj
|
||||
/_materio.sublime-project
|
||||
/_materio.sublime-workspace
|
||||
/_solr.sublime-project
|
||||
/_solr.sublime-workspace
|
||||
/_solr.sublime-workspace
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.sublime-project*
|
||||
|
||||
node_modules
|
||||
|
||||
.sass-cache
|
||||
typescript
|
||||
.directory
|
||||
|
||||
*.old_patched
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# Protect files and directories from prying eyes.
|
||||
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$">
|
||||
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
|
||||
Order allow,deny
|
||||
</FilesMatch>
|
||||
|
||||
@@ -20,7 +20,7 @@ ErrorDocument 404 /index.php
|
||||
DirectoryIndex index.php index.html index.htm
|
||||
|
||||
# Override PHP settings that cannot be changed at runtime. See
|
||||
# sites/default/default.settings.php and drupal_initialize_variables() in
|
||||
# sites/default/default.settings.php and drupal_environment_initialize() in
|
||||
# includes/bootstrap.inc for settings that can be changed at runtime.
|
||||
|
||||
# PHP 5, Apache 1 and 2.
|
||||
@@ -56,6 +56,17 @@ DirectoryIndex index.php index.html index.htm
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
|
||||
# Set "protossl" to "s" if we were accessed via https://. This is used later
|
||||
# if you enable "www." stripping or enforcement, in order to ensure that
|
||||
# you don't bounce between http and https.
|
||||
RewriteRule ^ - [E=protossl]
|
||||
RewriteCond %{HTTPS} on
|
||||
RewriteRule ^ - [E=protossl:s]
|
||||
|
||||
# Make sure Authorization HTTP header is available to PHP
|
||||
# even when running as CGI or FastCGI.
|
||||
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
||||
# Block access to "hidden" directories whose names begin with a period. This
|
||||
# includes directories used by version control systems such as Subversion or
|
||||
# Git to store control files. Files whose names begin with a period, as well
|
||||
@@ -71,18 +82,6 @@ DirectoryIndex index.php index.html index.htm
|
||||
# downloaded.
|
||||
RewriteRule "(^|/)\." - [F]
|
||||
|
||||
# custom
|
||||
RewriteCond %{HTTP_HOST} ^basebeta\.materio\.com [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.com [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.fr [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.fr [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.net [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.net [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.eu [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.eu [NC]
|
||||
RewriteRule ^ http://www.materio.com%{REQUEST_URI} [L,R=301]
|
||||
|
||||
|
||||
# If your site can be accessed both with and without the 'www.' prefix, you
|
||||
# can use one of the following settings to redirect users to your preferred
|
||||
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
|
||||
@@ -90,14 +89,32 @@ DirectoryIndex index.php index.html index.htm
|
||||
# To redirect all users to access the site WITH the 'www.' prefix,
|
||||
# (http://example.com/... will be redirected to http://www.example.com/...)
|
||||
# uncomment the following:
|
||||
# RewriteCond %{HTTP_HOST} .
|
||||
# RewriteCond %{HTTP_HOST} !^www\. [NC]
|
||||
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
#
|
||||
# RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# To redirect all users to access the site WITHOUT the 'www.' prefix,
|
||||
# (http://www.example.com/... will be redirected to http://example.com/...)
|
||||
# uncomment the following:
|
||||
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
|
||||
# RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301]
|
||||
# RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# redirect all materiau domains to materio.com
|
||||
RewriteCond %{HTTP_HOST} ^basebeta\.materio\.com [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.fr [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.fr [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.net [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.net [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.eu [OR]
|
||||
RewriteCond %{HTTP_HOST} ^materio\.eu [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.materio\.com
|
||||
# RewriteRule ^ http%{ENV:protossl}://materio.com%{REQUEST_URI} [L,R=301]
|
||||
RewriteRule ^ https://materio.com%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# Redirect to HTTPS
|
||||
# RewriteCond %{HTTPS} off
|
||||
# RewriteCond %{HTTP:X-Forwarded-Proto} !https
|
||||
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
|
||||
# VirtualDocumentRoot and the rewrite rules are not working properly.
|
||||
@@ -107,7 +124,7 @@ DirectoryIndex index.php index.html index.htm
|
||||
#
|
||||
# If your site is running in a VirtualDocumentRoot at http://example.com/,
|
||||
# uncomment the following line:
|
||||
# RewriteBase /
|
||||
RewriteBase /
|
||||
|
||||
# Pass all requests not referring directly to files in the filesystem to
|
||||
# index.php. Clean URLs are handled in drupal_environment_initialize().
|
||||
@@ -142,95 +159,138 @@ DirectoryIndex index.php index.html index.htm
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
# Add headers to all responses.
|
||||
<IfModule mod_headers.c>
|
||||
# Disable content sniffing, since it's an attack vector.
|
||||
Header always set X-Content-Type-Options nosniff
|
||||
</IfModule>
|
||||
|
||||
# from boiler plate V5.02
|
||||
|
||||
# FROM Html5 BoilerPlate 4.0
|
||||
# ######################################################################
|
||||
# # MEDIA TYPES AND CHARACTER ENCODINGS #
|
||||
# ######################################################################
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Proper MIME type for all files
|
||||
# | Media types |
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# JavaScript
|
||||
# Normalize to standard type (it's sniffed in IE anyways)
|
||||
# tools.ietf.org/html/rfc4329#section-7.2
|
||||
AddType application/javascript js jsonp
|
||||
AddType application/json json
|
||||
# Serve resources with the proper media types (f.k.a. MIME types).
|
||||
#
|
||||
# https://www.iana.org/assignments/media-types/media-types.xhtml
|
||||
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addtype
|
||||
|
||||
# Audio
|
||||
AddType audio/ogg oga ogg
|
||||
AddType audio/mp4 m4a f4a f4b
|
||||
<IfModule mod_mime.c>
|
||||
|
||||
# Video
|
||||
AddType video/ogg ogv
|
||||
AddType video/mp4 mp4 m4v f4v f4p
|
||||
AddType video/webm webm
|
||||
AddType video/x-flv flv
|
||||
# Data interchange
|
||||
|
||||
# SVG
|
||||
# Required for svg webfonts on iPad
|
||||
# twitter.com/FontSquirrel/status/14855840545
|
||||
AddType image/svg+xml svg svgz
|
||||
AddEncoding gzip svgz
|
||||
|
||||
# Webfonts
|
||||
AddType application/vnd.ms-fontobject eot
|
||||
AddType application/x-font-ttf ttf ttc
|
||||
AddType font/opentype otf
|
||||
AddType application/x-font-woff woff
|
||||
|
||||
# Assorted types
|
||||
AddType image/x-icon ico
|
||||
AddType image/webp webp
|
||||
AddType text/cache-manifest appcache manifest
|
||||
AddType text/x-component htc
|
||||
AddType application/xml rss atom xml rdf
|
||||
AddType application/x-chrome-extension crx
|
||||
AddType application/x-opera-extension oex
|
||||
AddType application/x-xpinstall xpi
|
||||
AddType application/octet-stream safariextz
|
||||
AddType application/x-web-app-manifest+json webapp
|
||||
AddType text/x-vcard vcf
|
||||
AddType application/x-shockwave-flash swf
|
||||
AddType text/vtt vtt
|
||||
AddType application/atom+xml atom
|
||||
AddType application/json json map topojson
|
||||
AddType application/ld+json jsonld
|
||||
AddType application/rss+xml rss
|
||||
AddType application/vnd.geo+json geojson
|
||||
AddType application/xml rdf xml
|
||||
|
||||
|
||||
# JavaScript
|
||||
|
||||
# Normalize to standard type.
|
||||
# https://tools.ietf.org/html/rfc4329#section-7.2
|
||||
|
||||
AddType application/javascript js
|
||||
|
||||
|
||||
# Manifest files
|
||||
|
||||
AddType application/manifest+json webmanifest
|
||||
AddType application/x-web-app-manifest+json webapp
|
||||
AddType text/cache-manifest appcache
|
||||
|
||||
|
||||
# Media files
|
||||
|
||||
AddType audio/mp4 f4a f4b m4a
|
||||
AddType audio/ogg oga ogg opus
|
||||
AddType image/bmp bmp
|
||||
AddType image/svg+xml svg svgz
|
||||
AddType image/webp webp
|
||||
AddType video/mp4 f4v f4p m4v mp4
|
||||
AddType video/ogg ogv
|
||||
AddType video/webm webm
|
||||
AddType video/x-flv flv
|
||||
|
||||
# Serving `.ico` image files with a different media type
|
||||
# prevents Internet Explorer from displaying then as images:
|
||||
# https://github.com/h5bp/html5-boilerplate/commit/37b5fec090d00f38de64b591bcddcb205aadf8ee
|
||||
|
||||
AddType image/x-icon cur ico
|
||||
|
||||
|
||||
# Web fonts
|
||||
|
||||
AddType application/font-woff woff
|
||||
AddType application/font-woff2 woff2
|
||||
AddType application/vnd.ms-fontobject eot
|
||||
|
||||
# Browsers usually ignore the font media types and simply sniff
|
||||
# the bytes to figure out the font type.
|
||||
# https://mimesniff.spec.whatwg.org/#matching-a-font-type-pattern
|
||||
#
|
||||
# However, Blink and WebKit based browsers will show a warning
|
||||
# in the console if the following font types are served with any
|
||||
# other media types.
|
||||
|
||||
AddType application/x-font-ttf ttc ttf
|
||||
AddType font/opentype otf
|
||||
|
||||
|
||||
# Other
|
||||
|
||||
AddType application/octet-stream safariextz
|
||||
AddType application/x-bb-appworld bbaw
|
||||
AddType application/x-chrome-extension crx
|
||||
AddType application/x-opera-extension oex
|
||||
AddType application/x-xpinstall xpi
|
||||
AddType text/vcard vcard vcf
|
||||
AddType text/vnd.rim.location.xloc xloc
|
||||
AddType text/vtt vtt
|
||||
AddType text/x-component htc
|
||||
|
||||
</IfModule>
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# UTF-8 encoding
|
||||
# | Character encodings |
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Use UTF-8 encoding for anything served text/plain or text/html
|
||||
# Serve all resources labeled as `text/html` or `text/plain`
|
||||
# with the media type `charset` parameter set to `UTF-8`.
|
||||
#
|
||||
# https://httpd.apache.org/docs/current/mod/core.html#adddefaultcharset
|
||||
|
||||
AddDefaultCharset utf-8
|
||||
|
||||
# Force UTF-8 for a number of file formats
|
||||
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
# Serve the following file types with the media type `charset`
|
||||
# parameter set to `UTF-8`.
|
||||
#
|
||||
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# A little more security
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# Block access to "hidden" directories or files whose names begin with a
|
||||
# period. This includes directories used by version control systems such as
|
||||
# Subversion or Git.
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteCond %{SCRIPT_FILENAME} -d [OR]
|
||||
RewriteCond %{SCRIPT_FILENAME} -f
|
||||
RewriteRule "(^|/)\." - [F]
|
||||
</IfModule>
|
||||
|
||||
# Block access to backup and source files. These files may be left by some
|
||||
# text/html editors and pose a great security danger, when anyone can access
|
||||
# them.
|
||||
<FilesMatch "(\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy All
|
||||
</FilesMatch>
|
||||
|
||||
# Increase cookie security
|
||||
<IfModule php5_module>
|
||||
php_value session.cookie_httponly true
|
||||
<IfModule mod_mime.c>
|
||||
AddCharset utf-8 .atom \
|
||||
.bbaw \
|
||||
.css \
|
||||
.geojson \
|
||||
.js \
|
||||
.json \
|
||||
.jsonld \
|
||||
.manifest \
|
||||
.rdf \
|
||||
.rss \
|
||||
.topojson \
|
||||
.vtt \
|
||||
.webapp \
|
||||
.webmanifest \
|
||||
.xloc \
|
||||
.xml
|
||||
</IfModule>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From 1f82c4ef9b474a12d160813f767128d645f524cc Mon Sep 17 00:00:00 2001
|
||||
From: Bachir Soussi Chiadmi <bachir@g-u-i.me>
|
||||
Date: Sun, 19 Apr 2015 21:04:36 +0200
|
||||
Subject: [PATCH] repatched entityrefeerence module
|
||||
|
||||
---
|
||||
...ityReference_SelectionHandler_Generic.class.php | 43 +++++++++++++++++++---
|
||||
1 file changed, 38 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sites/all/modules/contrib/fields/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php b/sites/all/modules/contrib/fields/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
|
||||
index 444a74c..660fe3d 100644
|
||||
--- a/sites/all/modules/contrib/fields/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
|
||||
+++ b/sites/all/modules/contrib/fields/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
|
||||
@@ -370,6 +370,28 @@ class EntityReference_SelectionHandler_Generic_node extends EntityReference_Sele
|
||||
* This only exists to workaround core bugs.
|
||||
*/
|
||||
class EntityReference_SelectionHandler_Generic_user extends EntityReference_SelectionHandler_Generic {
|
||||
+
|
||||
+ /**
|
||||
+ * Implements EntityReferenceHandler::settingsForm().
|
||||
+ */
|
||||
+ public static function settingsForm($field, $instance) {
|
||||
+ $settings = $field['settings']['handler_settings'];
|
||||
+ $form = parent::settingsForm($field, $instance);
|
||||
+ $form['referenceable_roles'] = array(
|
||||
+ '#type' => 'checkboxes',
|
||||
+ '#title' => t('User roles that can be referenced'),
|
||||
+ '#default_value' => isset($settings['referenceable_roles']) ? array_filter($settings['referenceable_roles']) : array(),
|
||||
+ '#options' => user_roles(TRUE),
|
||||
+ );
|
||||
+ $form['referenceable_status'] = array(
|
||||
+ '#type' => 'checkboxes',
|
||||
+ '#title' => t('User status that can be referenced'),
|
||||
+ '#default_value' => isset($settings['referenceable_status']) ? array_filter($settings['referenceable_status']) : array('active' => 'active'),
|
||||
+ '#options' => array('active' => t('Active'), 'blocked' => t('Blocked')),
|
||||
+ );
|
||||
+ return $form;
|
||||
+ }
|
||||
+
|
||||
public function buildEntityFieldQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityFieldQuery($match, $match_operator);
|
||||
|
||||
@@ -378,11 +400,22 @@ class EntityReference_SelectionHandler_Generic_user extends EntityReference_Sele
|
||||
$query->propertyCondition('name', $match, $match_operator);
|
||||
}
|
||||
|
||||
- // Adding the 'user_access' tag is sadly insufficient for users: core
|
||||
- // requires us to also know about the concept of 'blocked' and
|
||||
- // 'active'.
|
||||
- if (!user_access('administer users')) {
|
||||
- $query->propertyCondition('status', 1);
|
||||
+ $field = $this->field;
|
||||
+ $settings = $field['settings']['handler_settings'];
|
||||
+ $referenceable_roles = isset($settings['referenceable_roles']) ? array_filter($settings['referenceable_roles']) : array();
|
||||
+ $referenceable_status = isset($settings['referenceable_status']) ? array_filter($settings['referenceable_status']) : array('active' => 'active');
|
||||
+
|
||||
+ // If this filter is not filled, use the users access permissions.
|
||||
+ if (empty($referenceable_status)) {
|
||||
+ // Adding the 'user_access' tag is sadly insufficient for users: core
|
||||
+ // requires us to also know about the concept of 'blocked' and 'active'.
|
||||
+ if (!user_access('administer users')) {
|
||||
+ $query->propertyCondition('status', 1);
|
||||
+ }
|
||||
+ }
|
||||
+ elseif (count($referenceable_status) == 1) {
|
||||
+ $values = array('active' => 1, 'blocked' => 0);
|
||||
+ $query->propertyCondition('status', $values[key($referenceable_status)]);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
--
|
||||
2.3.5
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 7becdeff922748fb65a320903b0ee37268895dd1 Mon Sep 17 00:00:00 2001
|
||||
From: Bachir Soussi Chiadmi <bachir@g-u-i.me>
|
||||
Date: Sun, 19 Apr 2015 21:13:38 +0200
|
||||
Subject: [PATCH] repatched views module
|
||||
|
||||
---
|
||||
sites/all/modules/contrib/views/views/handlers/views_handler_field.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc b/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
|
||||
index 65210d9..c04fd46 100644
|
||||
--- a/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
|
||||
+++ b/sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
|
||||
@@ -372,7 +372,7 @@ class views_handler_field extends views_handler {
|
||||
* Optional name of the field where the value is stored.
|
||||
*/
|
||||
function get_value($values, $field = NULL) {
|
||||
- $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
|
||||
+ $alias = isset($field) && isset($this->aliases[$field]) ? $this->aliases[$field] : $this->field_alias;
|
||||
if (isset($values->{$alias})) {
|
||||
return $values->{$alias};
|
||||
}
|
||||
--
|
||||
2.3.5
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
diff --git a/modules/user/user.module b/modules/user/user.module
|
||||
index 47ac642..c204f6d 100644
|
||||
index bdfd36f..d33a528 100644
|
||||
--- a/modules/user/user.module
|
||||
+++ b/modules/user/user.module
|
||||
@@ -2286,14 +2286,26 @@ function user_external_login_register($name, $module) {
|
||||
*
|
||||
* @param object $account
|
||||
* An object containing the user account.
|
||||
@@ -2328,14 +2328,26 @@ function user_external_login_register($name, $module) {
|
||||
* following properties:
|
||||
* - uid: The user ID number.
|
||||
* - login: The UNIX timestamp of the user's last login.
|
||||
+ * @param array $options
|
||||
+ * (optional) A keyed array of settings. Supported options are:
|
||||
+ * - langcode: A language code to be used when generating locale-sensitive
|
||||
@@ -18,7 +18,7 @@ index 47ac642..c204f6d 100644
|
||||
-function user_pass_reset_url($account) {
|
||||
+function user_pass_reset_url($account, $options = array()) {
|
||||
$timestamp = REQUEST_TIME;
|
||||
- return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));
|
||||
- return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), array('absolute' => TRUE));
|
||||
+ $url_options = array('absolute' => TRUE);
|
||||
+ if (isset($options['langcode'])) {
|
||||
+ $languages = language_list();
|
||||
@@ -27,29 +27,29 @@ index 47ac642..c204f6d 100644
|
||||
+ else {
|
||||
+ $url_options['language'] = user_preferred_language($account);
|
||||
+ }
|
||||
+ return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), $url_options);
|
||||
+ return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), $url_options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2305,6 +2317,10 @@ function user_pass_reset_url($account) {
|
||||
* - uid: The user uid number.
|
||||
@@ -2347,6 +2359,10 @@ function user_pass_reset_url($account) {
|
||||
* - uid: The user ID number.
|
||||
* - pass: The hashed user password string.
|
||||
* - login: The user login name.
|
||||
* - login: The UNIX timestamp of the user's last login.
|
||||
+ * @param array $options
|
||||
+ * (optional) A keyed array of settings. Supported options are:
|
||||
+ * - langcode: A language code to be used when generating locale-sensitive
|
||||
+ * urls. If langcode is NULL the users preferred language is used.
|
||||
+ * urls. If langcode is NULL the users preferred language is used.
|
||||
*
|
||||
* @return
|
||||
* A unique URL that may be used to confirm the cancellation of the user
|
||||
@@ -2313,9 +2329,17 @@ function user_pass_reset_url($account) {
|
||||
@@ -2355,9 +2371,17 @@ function user_pass_reset_url($account) {
|
||||
* @see user_mail_tokens()
|
||||
* @see user_cancel_confirm()
|
||||
*/
|
||||
-function user_cancel_url($account) {
|
||||
+function user_cancel_url($account, $options = array()) {
|
||||
$timestamp = REQUEST_TIME;
|
||||
- return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));
|
||||
- return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), array('absolute' => TRUE));
|
||||
+ $url_options = array('absolute' => TRUE);
|
||||
+ if (isset($options['langcode'])) {
|
||||
+ $languages = language_list();
|
||||
@@ -58,20 +58,20 @@ index 47ac642..c204f6d 100644
|
||||
+ else {
|
||||
+ $url_options['language'] = user_preferred_language($account);
|
||||
+ }
|
||||
+ return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), $url_options);
|
||||
+ return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), $url_options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2752,7 +2776,7 @@ Your account on [site:name] has been canceled.
|
||||
@@ -2843,7 +2867,7 @@ Your account on [site:name] has been canceled.
|
||||
if ($replace) {
|
||||
// We do not sanitize the token replacement, since the output of this
|
||||
// replacement is intended for an e-mail message, not a web browser.
|
||||
- return token_replace($text, $variables, array('language' => $language, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
+ return token_replace($text, $variables, array('langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
+ return token_replace($text, $variables, array('language' => $language, 'langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
}
|
||||
|
||||
return $text;
|
||||
@@ -2779,8 +2803,8 @@ Your account on [site:name] has been canceled.
|
||||
@@ -2870,8 +2894,8 @@ Your account on [site:name] has been canceled.
|
||||
*/
|
||||
function user_mail_tokens(&$replacements, $data, $options) {
|
||||
if (isset($data['user'])) {
|
||||
@@ -83,10 +83,10 @@ index 47ac642..c204f6d 100644
|
||||
}
|
||||
|
||||
diff --git a/modules/user/user.test b/modules/user/user.test
|
||||
index b53db07..0417642 100644
|
||||
index 07be4c2..4536e0c 100644
|
||||
--- a/modules/user/user.test
|
||||
+++ b/modules/user/user.test
|
||||
@@ -2012,6 +2012,26 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
@@ -2145,6 +2145,26 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,9 +113,9 @@ index b53db07..0417642 100644
|
||||
/**
|
||||
* Creates a user, then tests the tokens generated from it.
|
||||
*/
|
||||
@@ -2062,6 +2082,39 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
@@ -2195,6 +2215,39 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
$output = token_replace($input, array('user' => $account), array('language' => $language, 'sanitize' => FALSE));
|
||||
$this->assertEqual($output, $expected, t('Unsanitized user token %token replaced.', array('%token' => $input)));
|
||||
$this->assertEqual($output, $expected, format_string('Unsanitized user token %token replaced.', array('%token' => $input)));
|
||||
}
|
||||
+
|
||||
+ $languages = language_list();
|
||||
@@ -1,4 +1,545 @@
|
||||
|
||||
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.
|
||||
|
||||
Drupal 7.38, 2015-06-17
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2015-002.
|
||||
|
||||
Drupal 7.37, 2015-05-07
|
||||
-----------------------
|
||||
- Fixed a regression in Drupal 7.36 which caused certain kinds of content types
|
||||
to become disabled if they were defined by a no-longer-enabled module.
|
||||
- Removed a confusing description regarding automatic time zone detection from
|
||||
the user account form (minor UI and data structure change).
|
||||
- Allowed custom HTML tags with a dash in the name to pass through filter_xss()
|
||||
when specified in the list of allowed tags.
|
||||
- Allowed hook_field_schema() implementations to specify indexes for fields
|
||||
based on a fixed-length column prefix (rather than the entire column), as was
|
||||
already allowed in hook_schema() implementations.
|
||||
- Fixed PDO exceptions on PostgreSQL when accessing invalid entity URLs.
|
||||
- Added a sites/all/libraries folder to the codebase, with instructions for
|
||||
using it.
|
||||
- Added a description to the "Administer text formats and filters" permission
|
||||
on the Permissions page (string change).
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.36, 2015-04-01
|
||||
-----------------------
|
||||
- Added a 'file_public_schema' variable which allows modules that define
|
||||
publicly-accessible streams in hook_stream_wrappers() to bypass file download
|
||||
access checks when processing managed file upload fields.
|
||||
- Fixed a bug that caused database query tags not to be added to search-related
|
||||
database queries under many circumstances, and which prevented the
|
||||
corresponding hook_query_TAG_alter() implementations from being called.
|
||||
- Fixed the "for" attribute on managed file upload field labels to improve
|
||||
accessibility (minor markup change).
|
||||
- Added a 'javascript_always_use_jquery' variable which can be set to FALSE by
|
||||
sites that may not need jQuery loaded on all pages, and a 'requires_jquery'
|
||||
option to drupal_add_js() which modules can set to FALSE when adding
|
||||
JavaScript files that have no dependency on jQuery (API addition:
|
||||
https://www.drupal.org/node/2462717).
|
||||
- Fixed incorrect foreign keys in the User module's role_permission and
|
||||
users_roles database tables.
|
||||
- Changed permission descriptions throughout Drupal core to consistently link
|
||||
to relevant administrative pages, regardless of whether the user viewing the
|
||||
Permissions page can view the page being linked to (minor UI change).
|
||||
- Fixed the drupal_add_region_content() function so that it actually adds
|
||||
content to the page.
|
||||
- Added an 'image_suppress_itok_output' variable to allow sites already using
|
||||
the existing 'image_allow_insecure_derivatives' variable to also prevent
|
||||
security tokens from appearing in image derivative URLs.
|
||||
- Fixed double-escaping of theme names in the Block module administrative
|
||||
interface (minor string change).
|
||||
- Added basic support for Xdebug when running automated tests.
|
||||
- Fixed a bug which caused previewing a node to remove elements from the node
|
||||
being edited. With this fix, calling node_preview() will no longer modify the
|
||||
passed-in node object (minor API change).
|
||||
- Added a user_has_role() function to check whether a user has a particular
|
||||
role (API addition: https://www.drupal.org/node/2462411).
|
||||
- Fixed installation failures when an opcode cache is enabled.
|
||||
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused private
|
||||
files to be inaccessible.
|
||||
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused user
|
||||
pictures to be lost.
|
||||
- Fixed missing language code in hook_field_attach_view_alter() when it is
|
||||
invoked from field_view_field().
|
||||
- Stopped sending ETag and Last-Modified headers for uncached page requests,
|
||||
since they break caching for certain Varnish and Nginx configurations.
|
||||
- Changed the Simpletest module to allow PSR-4 test classes to be used in
|
||||
Drupal 7.
|
||||
- Fixed a fatal error that occurred when using the Comment module's "Unpublish
|
||||
comment containing keyword(s)" action.
|
||||
- Changed the "lang" attribute on language links to "xml:lang" so it validates
|
||||
as XHTML (minor markup change).
|
||||
- Prevented the form API from allowing arrays to be submitted for various form
|
||||
elements, such as textfields, textareas, and password fields (API change:
|
||||
https://www.drupal.org/node/2462723).
|
||||
- Fixed a bug in the Contact module which caused the global user object to have
|
||||
the incorrect name and e-mail address during the remainder of the page
|
||||
request after the contact form is submitted.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- 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
|
||||
-----------------------
|
||||
- Began storing the file modification time of each module and theme in the
|
||||
{system} database table so that contributed modules can use it to identify
|
||||
recently changed modules and themes (minor data structure change to the
|
||||
return value of system_get_info() and other related functions).
|
||||
- Added a "Did you mean?" feature to the run-tests.sh script for running
|
||||
automated tests from the command line, to help developers who are attempting
|
||||
to run a particular test class or group.
|
||||
- Changed the date format used in various HTTP headers output by Drupal core
|
||||
from RFC 1123 format to RFC 7231 format.
|
||||
- Added a "block_cache_bypass_node_grants" variable to allow sites which have
|
||||
node access modules enabled to use the block cache if desired (API addition).
|
||||
- Made image derivative generation HTTP requests return a 404 error (rather
|
||||
than a 500 error) when the source image does not exist.
|
||||
- Fixed a bug which caused user pictures to be removed from the user object
|
||||
after saving, and resulted in data loss if the user account was subsequently
|
||||
re-saved.
|
||||
- Fixed a bug in which field_has_data() did not return TRUE for fields that
|
||||
only had data in older entity revisions, leading to loss of the field's data
|
||||
when the field configuration was edited.
|
||||
- Fixed a bug which caused the Ajax progress throbber to appear misaligned in
|
||||
many situatons (minor styling change).
|
||||
- Prevented the Bartik theme from lower-casing the "Permalink" link on
|
||||
comments, for improved multilingual support (minor UI change).
|
||||
- Added a "preferred_menu_links" tag to the database query that is used by
|
||||
menu_link_get_preferred() to find the preferred menu link for a given path,
|
||||
to make it easier to alter.
|
||||
- Increased the maximum allowed length of block titles to 255 characters
|
||||
(database schema change to the {block} table).
|
||||
- Removed the Field module's field_modules_uninstalled() function, since it did
|
||||
not do anything when it was invoked.
|
||||
- Added a "theme_hook_original" variable to templates and theme functions and
|
||||
an optional sitewide theme debug mode, to provide contextual information in
|
||||
the page's HTML to theme developers. The theme debug mode is based on the one
|
||||
used with Twig in Drupal 8 and can be accessed by setting the "theme_debug"
|
||||
variable to TRUE (API addition).
|
||||
- Added an entity_view_mode_prepare() API function to allow entity-defining
|
||||
modules to properly invoke hook_entity_view_mode_alter(), and used it
|
||||
throughout Drupal core to fix bugs with the invocation of that hook (API
|
||||
change: https://www.drupal.org/node/2369141).
|
||||
- Security improvement: Made the database API's orderBy() method sanitize the
|
||||
sort direction ("ASC" or "DESC") for queries built with db_select(), so that
|
||||
calling code does not have to.
|
||||
- Changed the RDF module to consistently output RDF metadata for nodes and
|
||||
comments near where the node is rendered in the HTML (minor markup and data
|
||||
structure change).
|
||||
- Added an HTML class to RDFa metatags throughout Drupal to prevent them from
|
||||
accidentally affecting the site appearance (minor markup change).
|
||||
- Fixed a bug in the Unicode requirements check which prevented installing
|
||||
Drupal on PHP 5.6.
|
||||
- Fixed a bug which caused drupal_get_bootstrap_phase() to abort the bootstrap
|
||||
when called early in the page request.
|
||||
- Renamed the "Search result" view mode to "Search result highlighting input"
|
||||
to better reflect how it is used (UI change).
|
||||
- Improved database queries generated by EntityFieldQuery in the case where
|
||||
delta or language condition groups are used, to reduce the number of INNER
|
||||
JOINs (this is a minor data structure change affecting code which implements
|
||||
hook_query_alter() on these queries).
|
||||
- Removed special-case behavior for file uploads which allowed user #1 to
|
||||
bypass maximum file size and user quota limits.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- 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
|
||||
-----------------------
|
||||
- Fixed a regression introduced in Drupal 7.29 that caused files or images
|
||||
attached to taxonomy terms to be deleted when the taxonomy term was edited
|
||||
and resaved (and other related bugs with contributed and custom modules).
|
||||
- Added a warning on the permissions page to recommend restricting access to
|
||||
the "View site reports" permission to trusted administrators. See
|
||||
DRUPAL-PSA-2014-002.
|
||||
- Numerous API documentation improvements.
|
||||
- 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
|
||||
-----------------------
|
||||
- Fixed a regression introduced in Drupal 7.27 that caused JavaScript to break
|
||||
on older browsers (such as Internet Explorer 8 and earlier) when Ajax was
|
||||
used.
|
||||
- Increased the timeout used by the Update Manager module when it fetches data
|
||||
from drupal.org (from 5 seconds to 30 seconds), to work around a problem
|
||||
which causes incomplete information about security updates to be presented to
|
||||
site administrators. This fix may lead to a performance slowdown on the
|
||||
Update Manager administration pages, when installing Drupal distributions,
|
||||
and (for sites that use the automated cron feature) on occasional page loads
|
||||
by site visitors.
|
||||
- Fixed the behavior of the token system's "[node:summary]" token when the body
|
||||
field does not have a manual summary.
|
||||
- Changed the behavior of db_query_temporary() so that it works on SELECT
|
||||
queries even when they have leading comments/whitespace. A side effect of
|
||||
this fix is that db_query_temporary() will now fail with an error if it is
|
||||
ever used on non-SELECT queries.
|
||||
- Added a "node_admin_filter" tag to the database query used to build the list
|
||||
of nodes on the content administration page, to make it easier to alter.
|
||||
- Made the cron queue system log any exceptions that are thrown while an item
|
||||
in the queue is being processed, rather than stopping the entire PHP request.
|
||||
- Improved screen reader support by adding an aria-live HTML attribute to file
|
||||
upload fields when there is an error uploading the file (minor markup
|
||||
change).
|
||||
- Made the pager on the Tracker module listing pages show the same number of
|
||||
items as other pagers throughout Drupal core (minor UI change).
|
||||
- Fixed a bug which caused caches not to be properly cleared when a file entity
|
||||
was saved or deleted.
|
||||
- Added several missing countries to the default list returned by
|
||||
country_get_list() (string change).
|
||||
- Replaced the term "weight" with "influence" in the content ranking settings
|
||||
for search, and added help text for administrators (string change).
|
||||
- Fixed untranslatable text strings in the administrative interface for the
|
||||
"Crop" effect provided by the Image module (minor string change).
|
||||
- Fixed a bug in the Taxonomy module update function introduced in Drupal 7.26
|
||||
that caused memory and CPU problems on sites with very large numbers of
|
||||
unpublished nodes.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- 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
|
||||
-----------------------
|
||||
- Fixed a bug in node_save() which prevented the saved node from being updated
|
||||
in hook_node_insert() and other similar hooks.
|
||||
- Added a meta tag to install.php to prevent it from being indexed by search
|
||||
engines even when Drupal is installed in a subfolder (minor markup change).
|
||||
- Fixed a bug in the database API that caused frequent deadlock errors when
|
||||
running merge queries on some servers.
|
||||
- Performance improvement: Prevented block rehashing from writing blocks to the
|
||||
database on every cache clear and cron run when the blocks have not changed.
|
||||
This fix results in an extra 'saved' key which is added and set to TRUE for
|
||||
each block returned by _block_rehash() that actually is saved to the database
|
||||
(data structure change).
|
||||
- Added an optional 'skip on cron' parameter to hook_cron_queue_info() to allow
|
||||
queues to avoid being automatically processed on cron runs (API addition).
|
||||
- Fixed a bug which caused hook_block_view_MODULE_DELTA_alter() to never be
|
||||
invoked if the block delta had a hyphen in it. To implement the hook when the
|
||||
block delta has a hyphen, modules should now replace hyphens with underscores
|
||||
when constructing the function name for the hook implementation.
|
||||
- Fixed a bug which caused cached pages to sometimes be sent to the browser
|
||||
with incorrect compression. The fix adds a new 'page_compressed' key to the
|
||||
$cache->data array returned by drupal_page_get_cache() (minor data structure
|
||||
change).
|
||||
- Fixed broken tests on PHP 5.5.
|
||||
- Made the File and Image modules more robust when saving entities that have
|
||||
deleted files attached. The code in file_field_presave() will now remove the
|
||||
record of the deleted file from the entity before saving (minor data
|
||||
structure change).
|
||||
- Standardized menu callback functions throughout Drupal core to return
|
||||
MENU_NOT_FOUND and MENU_ACCESS_DENIED rather than printing their own "page
|
||||
not found" or "access denied" pages (minor API change in the return value of
|
||||
these functions under some circumstances).
|
||||
- Fixed a bug in which caches were not properly cleared when a node was deleted
|
||||
via the administrative interface.
|
||||
- Changed the Bartik theme to render content contained in <pre>, <code> and
|
||||
similar tags in a larger font size, so it is easier to read.
|
||||
- Fixed a bug in the Search module that caused exceptions to be thrown during
|
||||
searches if the server was not configured to represent decimal points as a
|
||||
period.
|
||||
- Fixed a regression in the Image module that made image_style_url() not work
|
||||
when a relative path (rather than a complete file URI) was passed to it.
|
||||
- Added an optional feature to the Statistics module to allow node views to be
|
||||
tracked by Ajax requests rather than during the server-side generation of the
|
||||
page. This allows the node counter to work on sites that use external page
|
||||
caches (string change and new administrative option:
|
||||
https://drupal.org/node/2164069).
|
||||
- Added a link to the drupal.org documentation page for cron to the Cron
|
||||
settings page (string change).
|
||||
- Added a 'drupal_anonymous_user_object' variable to allow the anonymous user
|
||||
object returned by drupal_anonymous_user() to be overridden with a classed
|
||||
object (API addition).
|
||||
- Changed the database API to allow inserts based on a SELECT * query to work
|
||||
correctly.
|
||||
- Changed the database schema of the {file_managed} table to allow Drupal to
|
||||
manage files larger than 4 GB.
|
||||
- Changed the File module's hook_field_load() implementation to prevent file
|
||||
entity properties which have the same name as file or image field properties
|
||||
from overwriting the field properties (minor API change).
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- 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
|
||||
-----------------------
|
||||
- Fixed a fatal error on PostgreSQL databases when updating the Taxonomy module
|
||||
from Drupal 6 to Drupal 7.
|
||||
- Fixed the default ordering of CSS files for sites using right-to-left
|
||||
languages, to consistently place the right-to-left override file immediately
|
||||
after the CSS it is overriding (API change: https://drupal.org/node/2058463).
|
||||
- Added a drupal_check_memory_limit() API function to allow the memory limit to
|
||||
be checked consistently (API addition).
|
||||
- Changed the default web.config file for IIS servers to allow favicon.ico
|
||||
files which are present in the filesystem to be accessed.
|
||||
- Fixed inconsistent support for the 'tel' protocol in Drupal's URL filtering
|
||||
functions.
|
||||
- Performance improvement: Allowed all hooks to be included in the
|
||||
module_implements() cache, even those that are only invoked on HTTP POST
|
||||
requests.
|
||||
- Made the database system replace truncate queries with delete queries when
|
||||
inside a transaction, to fix issues with PostgreSQL and other databases.
|
||||
- Fixed a bug which caused nested contextual links to display improperly.
|
||||
- Fixed a bug which prevented cached image derivatives from being flushed for
|
||||
private files and other non-default file schemes.
|
||||
- Fixed drupal_render() to always return an empty string when there is no
|
||||
output, rather than sometimes returning NULL (minor API change).
|
||||
- Added protection to cache_clear_all() to ensure that non-cache tables cannot
|
||||
be truncated (API addition: a new isValidBin() method has been added to the
|
||||
default database cache implementation).
|
||||
- Changed the default .htaccess file to support HTTP authorization in CGI
|
||||
environments.
|
||||
- Changed the password reset form to pre-fill the username when requested via a
|
||||
URL query parameter, and used this in the error message that appears after a
|
||||
failed login attempt (minor data structure and behavior change).
|
||||
- Fixed broken support for foreign keys in the field API.
|
||||
- Fixed "No active batch" error when a user cancels their own account.
|
||||
- Added a description to the "access content overview" permission on the
|
||||
permissions page (string change).
|
||||
- Added a drupal_array_diff_assoc_recursive() function to allow associative
|
||||
arrays to be compared recursively (API addition).
|
||||
- Added human-readable labels to image styles, in addition to the existing
|
||||
machine-readable name (API change: https://drupal.org/node/2058503).
|
||||
- Moved the drupal_get_hash_salt() function to bootstrap.inc and used it in
|
||||
additional places in the code, for added security in the case where there is
|
||||
no hash salt in settings.php.
|
||||
- Fixed a regression in Drupal 7.22 that caused internal server errors for
|
||||
sites running on very old Apache 1.x web servers.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.22, 2013-04-03
|
||||
-----------------------
|
||||
- Allowed the drupal_http_request() function to be overridden so that
|
||||
@@ -53,7 +594,7 @@ Drupal 7.22, 2013-04-03
|
||||
downloaded via the Update Manager (UI change).
|
||||
- Added an optional "exclusive" flag to installation profile .info files which
|
||||
allows Drupal distributions to force a profile to be selected during
|
||||
installation (API addition).
|
||||
installation (API addition: http://drupal.org/node/1961012).
|
||||
- Fixed a bug which caused the database API to not properly close database
|
||||
connections.
|
||||
- Added a link to the URL for running cron from outside the site to the Cron
|
||||
@@ -202,8 +743,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.
|
||||
@@ -251,12 +792,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.
|
||||
@@ -290,11 +831,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
|
||||
@@ -647,7 +1188,7 @@ Drupal 7.0, 2011-01-05
|
||||
requests.
|
||||
|
||||
Drupal 6.23-dev, xxxx-xx-xx (development release)
|
||||
-----------------------
|
||||
---------------------------
|
||||
|
||||
Drupal 6.22, 2011-05-25
|
||||
-----------------------
|
||||
@@ -657,25 +1198,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
|
||||
@@ -684,7 +1225,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.
|
||||
@@ -696,12 +1237,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
|
||||
@@ -710,18 +1251,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
|
||||
@@ -729,7 +1270,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.
|
||||
@@ -1125,7 +1666,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
|
||||
@@ -1238,7 +1779,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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
All Drupal code is Copyright 2001 - 2012 by the original authors.
|
||||
All Drupal code is Copyright 2001 - 2013 by the original authors.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
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
|
||||
ON databasename.*
|
||||
TO 'username'@'localhost' IDENTIFIED BY 'password';
|
||||
|
||||
where
|
||||
|
||||
'databasename' is the name of your database
|
||||
'username@localhost' is the username of your MySQL account
|
||||
'password' is the password required for that username
|
||||
|
||||
Note: Unless your database user has all of the privileges listed above, you will
|
||||
not be able to 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.
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
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.
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
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.
|
||||
@@ -1,398 +0,0 @@
|
||||
|
||||
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.
|
||||
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
|
||||
- SQLite 3.4.2 (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.
|
||||
@@ -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,150 +10,155 @@ 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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
|
||||
|
||||
Database update system
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
|
||||
Security
|
||||
- Greg Knaddison 'greggles' http://drupal.org/user/36762
|
||||
- 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://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 https://www.drupal.org/security-team for more information.
|
||||
The security team lead is:
|
||||
|
||||
- Michael Hess 'mlhess' https://www.drupal.org/u/mlhess
|
||||
|
||||
|
||||
Module maintainers
|
||||
------------------
|
||||
@@ -161,143 +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
|
||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
||||
- 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
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Core Patches :
|
||||
- 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
|
||||
|
||||
|
||||
# Modules :
|
||||
|
||||
link : allow any tld (https://www.drupal.org/node/2299657#comment-11414075)
|
||||
cer
|
||||
contentadminrelink
|
||||
// entity_translation_search_api
|
||||
entityreference
|
||||
feedback
|
||||
// field_group
|
||||
filter_path_alias
|
||||
// flag_lists
|
||||
// nodeformcols
|
||||
// search_api
|
||||
// search_api_page
|
||||
// search_api_solr
|
||||
termreferencetree
|
||||
views
|
||||
wysiwyg
|
||||
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
|
||||
@@ -71,12 +71,12 @@ profiles/your_site_profile/themes respectively to restrict their usage to only
|
||||
sites that were installed with that specific profile.
|
||||
|
||||
More about installation profiles and distributions:
|
||||
* Read about the difference between installation profiles and distributions:
|
||||
http://drupal.org/node/1089736
|
||||
* Download contributed installation profiles and distributions:
|
||||
http://drupal.org/project/distributions
|
||||
* Develop your own installation profile or distribution:
|
||||
http://drupal.org/developing/distributions
|
||||
* Read about the difference between installation profiles and distributions:
|
||||
http://drupal.org/node/1089736
|
||||
* Download contributed installation profiles and distributions:
|
||||
http://drupal.org/project/distributions
|
||||
* Develop your own installation profile or distribution:
|
||||
http://drupal.org/developing/distributions
|
||||
|
||||
APPEARANCE
|
||||
----------
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
diff --git a/misc/autocomplete.js b/misc/autocomplete.js
|
||||
index 8f7ac60..5679081 100644
|
||||
--- a/misc/autocomplete.js
|
||||
+++ b/misc/autocomplete.js
|
||||
@@ -114,6 +114,7 @@ Drupal.jsAC.prototype.onkeyup = function (input, e) {
|
||||
*/
|
||||
Drupal.jsAC.prototype.select = function (node) {
|
||||
this.input.value = $(node).data('autocompleteValue');
|
||||
+ $(this.input).trigger('autocompleteSelect', [node]);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -167,7 +168,7 @@ Drupal.jsAC.prototype.unhighlight = function (node) {
|
||||
Drupal.jsAC.prototype.hidePopup = function (keycode) {
|
||||
// Select item if the right key or mousebutton was pressed.
|
||||
if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
|
||||
- this.input.value = $(this.selected).data('autocompleteValue');
|
||||
+ this.select(this.selected);
|
||||
}
|
||||
// Hide popup.
|
||||
var popup = this.popup;
|
||||
@@ -220,7 +221,7 @@ Drupal.jsAC.prototype.found = function (matches) {
|
||||
for (key in matches) {
|
||||
$('<li></li>')
|
||||
.html($('<div></div>').html(matches[key]))
|
||||
- .mousedown(function () { ac.select(this); })
|
||||
+ .mousedown(function () { ac.hidePopup(this); })
|
||||
.mouseover(function () { ac.highlight(this); })
|
||||
.mouseout(function () { ac.unhighlight(this); })
|
||||
.data('autocompleteValue', key)
|
||||
@@ -0,0 +1,23 @@
|
||||
diff --git a/includes/entity.inc b/includes/entity.inc
|
||||
index 2fefd59..0b80d53 100644
|
||||
--- a/includes/entity.inc
|
||||
+++ b/includes/entity.inc
|
||||
@@ -159,6 +159,18 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
*/
|
||||
public function load($ids = array(), $conditions = array()) {
|
||||
$entities = array();
|
||||
+
|
||||
+ # PATCH http://drupal.org/node/1003788#comment-5195682
|
||||
+ // Clean the $ids array to remove non-integer values that can be passed
|
||||
+ // in from various sources, including menu callbacks.
|
||||
+ if (is_array($ids)) {
|
||||
+ foreach ($ids as $key => $id) {
|
||||
+ if (empty($id) || ((string) $id !== (string) (int) $id)) {
|
||||
+ unset($ids[$key]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ # endpatch
|
||||
|
||||
// Revisions are not statically cached, and require a different query to
|
||||
// other conditions, so separate the revision id into its own variable.
|
||||
@@ -0,0 +1,4 @@
|
||||
#! /bin/bash
|
||||
|
||||
sudo chown -R $USER:http sites/all/modules/features/
|
||||
sudo chmod -R g+w sites/all/modules/features/
|
||||
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 862 B |
@@ -211,7 +211,7 @@
|
||||
*
|
||||
* When returning an Ajax command array, it is often useful to have
|
||||
* status messages rendered along with other tasks in the command array.
|
||||
* In that case the the Ajax commands array may be constructed like this:
|
||||
* In that case the Ajax commands array may be constructed like this:
|
||||
* @code
|
||||
* $commands = array();
|
||||
* $commands[] = ajax_command_replace(NULL, $output);
|
||||
@@ -230,6 +230,10 @@
|
||||
* functions.
|
||||
*/
|
||||
function ajax_render($commands = array()) {
|
||||
// Although ajax_deliver() does this, some contributed and custom modules
|
||||
// render Ajax responses without using that delivery callback.
|
||||
ajax_set_verification_header();
|
||||
|
||||
// Ajax responses aren't rendered with html.tpl.php, so we have to call
|
||||
// drupal_get_css() and drupal_get_js() here, in order to have new files added
|
||||
// during this request to be loaded by the page. We only want to send back
|
||||
@@ -276,7 +280,7 @@ function ajax_render($commands = array()) {
|
||||
|
||||
$extra_commands = array();
|
||||
if (!empty($styles)) {
|
||||
$extra_commands[] = ajax_command_prepend('head', $styles);
|
||||
$extra_commands[] = ajax_command_add_css($styles);
|
||||
}
|
||||
if (!empty($scripts_header)) {
|
||||
$extra_commands[] = ajax_command_prepend('head', $scripts_header);
|
||||
@@ -292,7 +296,7 @@ function ajax_render($commands = array()) {
|
||||
$scripts = drupal_add_js();
|
||||
if (!empty($scripts['settings'])) {
|
||||
$settings = $scripts['settings'];
|
||||
array_unshift($commands, ajax_command_settings(call_user_func_array('array_merge_recursive', $settings['data']), TRUE));
|
||||
array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
|
||||
}
|
||||
|
||||
// Allow modules to alter any Ajax response.
|
||||
@@ -308,10 +312,11 @@ function ajax_render($commands = array()) {
|
||||
* pulls the form info from $_POST.
|
||||
*
|
||||
* @return
|
||||
* An array containing the $form and $form_state. Use the list() function
|
||||
* to break these apart:
|
||||
* An array containing the $form, $form_state, $form_id, $form_build_id and an
|
||||
* initial list of Ajax $commands. Use the list() function to break these
|
||||
* apart:
|
||||
* @code
|
||||
* list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
|
||||
* list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
|
||||
* @endcode
|
||||
*/
|
||||
function ajax_get_form() {
|
||||
@@ -331,6 +336,17 @@ function ajax_get_form() {
|
||||
drupal_exit();
|
||||
}
|
||||
|
||||
// When a page level cache is enabled, the form-build id might have been
|
||||
// replaced from within form_get_cache. If this is the case, it is also
|
||||
// necessary to update it in the browser by issuing an appropriate Ajax
|
||||
// command.
|
||||
$commands = array();
|
||||
if (isset($form['#build_id_old']) && $form['#build_id_old'] != $form['#build_id']) {
|
||||
// If the form build ID has changed, issue an Ajax command to update it.
|
||||
$commands[] = ajax_command_update_build_id($form);
|
||||
$form_build_id = $form['#build_id'];
|
||||
}
|
||||
|
||||
// Since some of the submit handlers are run, redirects need to be disabled.
|
||||
$form_state['no_redirect'] = TRUE;
|
||||
|
||||
@@ -345,7 +361,7 @@ function ajax_get_form() {
|
||||
$form_state['input'] = $_POST;
|
||||
$form_id = $form['#form_id'];
|
||||
|
||||
return array($form, $form_state, $form_id, $form_build_id);
|
||||
return array($form, $form_state, $form_id, $form_build_id, $commands);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,7 +382,7 @@ function ajax_get_form() {
|
||||
* @see system_menu()
|
||||
*/
|
||||
function ajax_form_callback() {
|
||||
list($form, $form_state) = ajax_get_form();
|
||||
list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
|
||||
drupal_process_form($form['#form_id'], $form, $form_state);
|
||||
|
||||
// We need to return the part of the form (or some other content) that needs
|
||||
@@ -378,8 +394,20 @@ function ajax_form_callback() {
|
||||
if (!empty($form_state['triggering_element'])) {
|
||||
$callback = $form_state['triggering_element']['#ajax']['callback'];
|
||||
}
|
||||
if (!empty($callback) && function_exists($callback)) {
|
||||
return $callback($form, $form_state);
|
||||
if (!empty($callback) && is_callable($callback)) {
|
||||
$result = $callback($form, $form_state);
|
||||
|
||||
if (!(is_array($result) && isset($result['#type']) && $result['#type'] == 'ajax')) {
|
||||
// Turn the response into a #type=ajax array if it isn't one already.
|
||||
$result = array(
|
||||
'#type' => 'ajax',
|
||||
'#commands' => ajax_prepare_response($result),
|
||||
);
|
||||
}
|
||||
|
||||
$result['#commands'] = array_merge($commands, $result['#commands']);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,6 +491,9 @@ function ajax_deliver($page_callback_result) {
|
||||
}
|
||||
}
|
||||
|
||||
// Let ajax.js know that this response is safe to process.
|
||||
ajax_set_verification_header();
|
||||
|
||||
// Print the response.
|
||||
$commands = ajax_prepare_response($page_callback_result);
|
||||
$json = ajax_render($commands);
|
||||
@@ -552,6 +583,29 @@ function ajax_prepare_response($page_callback_result) {
|
||||
return $commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a response header for ajax.js to trust the response body.
|
||||
*
|
||||
* It is not safe to invoke Ajax commands within user-uploaded files, so this
|
||||
* header protects against those being invoked.
|
||||
*
|
||||
* @see Drupal.ajax.options.success()
|
||||
*/
|
||||
function ajax_set_verification_header() {
|
||||
$added = &drupal_static(__FUNCTION__);
|
||||
|
||||
// User-uploaded files cannot set any response headers, so a custom header is
|
||||
// used to indicate to ajax.js that this response is safe. Note that most
|
||||
// Ajax requests bound using the Form API will be protected by having the URL
|
||||
// flagged as trusted in Drupal.settings, so this header is used only for
|
||||
// things like custom markup that gets Ajax behaviors attached.
|
||||
if (empty($added)) {
|
||||
drupal_add_http_header('X-Drupal-Ajax-Token', '1');
|
||||
// Avoid sending the header twice.
|
||||
$added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs end-of-Ajax-request tasks.
|
||||
*
|
||||
@@ -740,7 +794,12 @@ function ajax_pre_render_element($element) {
|
||||
|
||||
$element['#attached']['js'][] = array(
|
||||
'type' => 'setting',
|
||||
'data' => array('ajax' => array($element['#id'] => $settings)),
|
||||
'data' => array(
|
||||
'ajax' => array($element['#id'] => $settings),
|
||||
'urlIsAjaxTrusted' => array(
|
||||
$settings['url'] => TRUE,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Indicate that Ajax processing was successful.
|
||||
@@ -1210,3 +1269,49 @@ function ajax_command_restripe($selector) {
|
||||
'selector' => $selector,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Drupal Ajax 'update_build_id' command.
|
||||
*
|
||||
* This command updates the value of a hidden form_build_id input element on a
|
||||
* form. It requires the form passed in to have keys for both the old build ID
|
||||
* in #build_id_old and the new build ID in #build_id.
|
||||
*
|
||||
* The primary use case for this Ajax command is to serve a new build ID to a
|
||||
* form served from the cache to an anonymous user, preventing one anonymous
|
||||
* user from accessing the form state of another anonymous users on Ajax enabled
|
||||
* forms.
|
||||
*
|
||||
* @param $form
|
||||
* The form array representing the form whose build ID should be updated.
|
||||
*/
|
||||
function ajax_command_update_build_id($form) {
|
||||
return array(
|
||||
'command' => 'updateBuildId',
|
||||
'old' => $form['#build_id_old'],
|
||||
'new' => $form['#build_id'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Drupal Ajax 'add_css' command.
|
||||
*
|
||||
* This method will add css via ajax in a cross-browser compatible way.
|
||||
*
|
||||
* This command is implemented by Drupal.ajax.prototype.commands.add_css()
|
||||
* defined in misc/ajax.js.
|
||||
*
|
||||
* @param $styles
|
||||
* A string that contains the styles to be added.
|
||||
*
|
||||
* @return
|
||||
* An array suitable for use with the ajax_render() function.
|
||||
*
|
||||
* @see misc/ajax.js
|
||||
*/
|
||||
function ajax_command_add_css($styles) {
|
||||
return array(
|
||||
'command' => 'add_css',
|
||||
'data' => $styles,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -98,9 +99,11 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
||||
* @param $data
|
||||
* The data to store in the cache. Complex data types will be automatically
|
||||
* serialized before insertion. Strings will be stored as plain text and are
|
||||
* not serialized.
|
||||
* not serialized. Some storage engines only allow objects up to a maximum of
|
||||
* 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 $bin
|
||||
* The cache bin to store the data in. Valid core values are:
|
||||
* (optional) The cache bin to store the data in. Valid core values are:
|
||||
* - cache: (default) Generic cache storage bin (used for theme registry,
|
||||
* locale date, list of simpletest tests, etc.).
|
||||
* - cache_block: Stores the content of various blocks.
|
||||
@@ -119,7 +122,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
||||
* the administrator panel.
|
||||
* - cache_path: Stores the system paths that have an alias.
|
||||
* @param $expire
|
||||
* One of the following values:
|
||||
* (optional) 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
|
||||
@@ -137,18 +140,20 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
||||
/**
|
||||
* Expires data from the cache.
|
||||
*
|
||||
* If called without arguments, expirable entries will be cleared from the
|
||||
* cache_page and cache_block bins.
|
||||
* If called with the arguments $cid and $bin set to NULL or omitted, then
|
||||
* expirable entries will be cleared from the cache_page and cache_block bins,
|
||||
* and the $wildcard argument is ignored.
|
||||
*
|
||||
* @param $cid
|
||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
||||
* expire are deleted.
|
||||
* If set, the cache ID or an array of cache IDs. Otherwise, all cache entries
|
||||
* that can expire are deleted. The $wildcard argument will be ignored if set
|
||||
* to NULL.
|
||||
* @param $bin
|
||||
* If set, the cache bin to delete from. Mandatory argument if $cid is set.
|
||||
* @param $wildcard
|
||||
* If TRUE, cache IDs starting with $cid are deleted in addition to the
|
||||
* exact cache ID specified by $cid. If $wildcard is TRUE and $cid is '*',
|
||||
* the entire cache bin is emptied.
|
||||
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||
* starting with $cid are deleted in addition to the exact cache ID specified
|
||||
* by $cid. If $wildcard is TRUE and $cid is '*', the entire cache is emptied.
|
||||
*/
|
||||
function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
|
||||
if (!isset($cid) && !isset($bin)) {
|
||||
@@ -217,13 +222,6 @@ function cache_is_empty($bin) {
|
||||
* @see DrupalDatabaseCache
|
||||
*/
|
||||
interface DrupalCacheInterface {
|
||||
/**
|
||||
* Constructs a new cache interface.
|
||||
*
|
||||
* @param $bin
|
||||
* The cache bin for which the object is created.
|
||||
*/
|
||||
function __construct($bin);
|
||||
|
||||
/**
|
||||
* Returns data from the persistent cache.
|
||||
@@ -259,10 +257,12 @@ interface DrupalCacheInterface {
|
||||
* The cache ID of the data to store.
|
||||
* @param $data
|
||||
* The data to store in the cache. Complex data types will be automatically
|
||||
* serialized before insertion.
|
||||
* Strings will be stored as plain text and not serialized.
|
||||
* serialized before insertion. Strings will be stored as plain text and not
|
||||
* serialized. Some storage engines only allow objects up to a maximum of
|
||||
* 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
|
||||
* One of the following values:
|
||||
* (optional) 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
|
||||
@@ -280,12 +280,14 @@ interface DrupalCacheInterface {
|
||||
* cache_page and cache_block bins.
|
||||
*
|
||||
* @param $cid
|
||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
||||
* expire are deleted.
|
||||
* If set, the cache ID or an array of cache IDs. Otherwise, all cache
|
||||
* entries that can expire are deleted. The $wildcard argument will be
|
||||
* ignored if set to NULL.
|
||||
* @param $wildcard
|
||||
* If set to TRUE, the $cid is treated as a substring
|
||||
* to match rather than a complete ID. The match is a right hand
|
||||
* match. If '*' is given as $cid, the bin $bin will be emptied.
|
||||
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||
* starting with $cid are deleted in addition to the exact cache ID
|
||||
* specified by $cid. If $wildcard is TRUE and $cid is '*', the entire
|
||||
* cache is emptied.
|
||||
*/
|
||||
function clear($cid = NULL, $wildcard = FALSE);
|
||||
|
||||
@@ -311,7 +313,10 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
protected $bin;
|
||||
|
||||
/**
|
||||
* Constructs a new DrupalDatabaseCache object.
|
||||
* Constructs a DrupalDatabaseCache object.
|
||||
*
|
||||
* @param $bin
|
||||
* The cache bin for which the object is created.
|
||||
*/
|
||||
function __construct($bin) {
|
||||
$this->bin = $bin;
|
||||
@@ -505,7 +510,16 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
else {
|
||||
if ($wildcard) {
|
||||
if ($cid == '*') {
|
||||
db_truncate($this->bin)->execute();
|
||||
// Check if $this->bin is a cache table before truncating. Other
|
||||
// cache_clear_all() operations throw a PDO error in this situation,
|
||||
// so we don't need to verify them first. This ensures that non-cache
|
||||
// tables cannot be truncated accidentally.
|
||||
if ($this->isValidBin()) {
|
||||
db_truncate($this->bin)->execute();
|
||||
}
|
||||
else {
|
||||
throw new Exception(t('Invalid or missing cache bin specified: %bin', array('%bin' => $this->bin)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
db_delete($this->bin)
|
||||
@@ -542,4 +556,25 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
->fetchField();
|
||||
return empty($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if $this->bin represents a valid cache table.
|
||||
*
|
||||
* This check is required to ensure that non-cache tables are not truncated
|
||||
* accidentally when calling cache_clear_all().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function isValidBin() {
|
||||
if ($this->bin == 'cache' || substr($this->bin, 0, 6) == 'cache_') {
|
||||
// Skip schema check for bins with standard table names.
|
||||
return TRUE;
|
||||
}
|
||||
// These fields are required for any cache table.
|
||||
$fields = array('cid', 'data', 'expire', 'created', 'serialized');
|
||||
// Load the table schema.
|
||||
$schema = drupal_get_schema($this->bin);
|
||||
// Confirm that all fields are present.
|
||||
return isset($schema['fields']) && !array_diff($fields, array_keys($schema['fields']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,18 +28,21 @@
|
||||
* Most Drupal database SELECT queries are performed by a call to db_query() or
|
||||
* db_query_range(). Module authors should also consider using the PagerDefault
|
||||
* Extender for queries that return results that need to be presented on
|
||||
* multiple pages, and the Tablesort Extender for generating appropriate queries
|
||||
* for sortable tables.
|
||||
* multiple pages (see https://drupal.org/node/508796), and the TableSort
|
||||
* Extender for generating appropriate queries for sortable tables
|
||||
* (see https://drupal.org/node/1848372).
|
||||
*
|
||||
* For example, one might wish to return a list of the most recent 10 nodes
|
||||
* authored by a given user. Instead of directly issuing the SQL query
|
||||
* @code
|
||||
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT 0, 10;
|
||||
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid
|
||||
* ORDER BY n.created DESC LIMIT 0, 10;
|
||||
* @endcode
|
||||
* one would instead call the Drupal functions:
|
||||
* @code
|
||||
* $result = db_query_range('SELECT n.nid, n.title, n.created
|
||||
* FROM {node} n WHERE n.uid = :uid', 0, 10, array(':uid' => $uid));
|
||||
* FROM {node} n WHERE n.uid = :uid
|
||||
* ORDER BY n.created DESC', 0, 10, array(':uid' => $uid));
|
||||
* foreach ($result as $record) {
|
||||
* // Perform operations on $record->title, etc. here.
|
||||
* }
|
||||
@@ -179,7 +182,7 @@
|
||||
* concrete implementation of it to support special handling required by that
|
||||
* database.
|
||||
*
|
||||
* @see http://php.net/manual/en/book.pdo.php
|
||||
* @see http://php.net/manual/book.pdo.php
|
||||
*/
|
||||
abstract class DatabaseConnection extends PDO {
|
||||
|
||||
@@ -293,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'] : '');
|
||||
@@ -623,7 +640,7 @@ abstract class DatabaseConnection extends PDO {
|
||||
* A sanitized version of the query comment string.
|
||||
*/
|
||||
protected function filterComment($comment = '') {
|
||||
return preg_replace('/(\/\*\s*)|(\s*\*\/)/', '', $comment);
|
||||
return strtr($comment, array('*' => ' * '));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,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
|
||||
@@ -733,7 +750,7 @@ abstract class DatabaseConnection extends PDO {
|
||||
// to expand it out into a comma-delimited set of placeholders.
|
||||
foreach (array_filter($args, 'is_array') as $key => $data) {
|
||||
$new_keys = array();
|
||||
foreach ($data as $i => $value) {
|
||||
foreach (array_values($data) as $i => $value) {
|
||||
// This assumes that there are no other placeholders that use the same
|
||||
// name. For example, if the array placeholder is defined as :example
|
||||
// and there is already an :example_2 placeholder, this will generate
|
||||
@@ -916,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -930,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -945,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1310,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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1986,7 +2045,7 @@ interface DatabaseStatementInterface extends Traversable {
|
||||
/**
|
||||
* Sets the default fetch mode for this statement.
|
||||
*
|
||||
* See http://php.net/manual/en/pdo.constants.php for the definition of the
|
||||
* See http://php.net/manual/pdo.constants.php for the definition of the
|
||||
* constants used.
|
||||
*
|
||||
* @param $mode
|
||||
@@ -2005,7 +2064,7 @@ interface DatabaseStatementInterface extends Traversable {
|
||||
/**
|
||||
* Fetches the next row from a result set.
|
||||
*
|
||||
* See http://php.net/manual/en/pdo.constants.php for the definition of the
|
||||
* See http://php.net/manual/pdo.constants.php for the definition of the
|
||||
* constants used.
|
||||
*
|
||||
* @param $mode
|
||||
@@ -2380,14 +2439,14 @@ function db_query_range($query, $from, $count, array $args = array(), array $opt
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a query string and saves the result set to a temporary table.
|
||||
* Executes a SELECT query string and saves the result set to a temporary table.
|
||||
*
|
||||
* The execution of the query string happens against the active database.
|
||||
*
|
||||
* @param $query
|
||||
* The prepared statement query to run. Although it will accept both named and
|
||||
* unnamed placeholders, named placeholders are strongly preferred as they are
|
||||
* more self-documenting.
|
||||
* The prepared SELECT statement query to run. Although it will accept both
|
||||
* named and unnamed placeholders, named placeholders are strongly preferred
|
||||
* as they are more self-documenting.
|
||||
* @param $args
|
||||
* An array of values to substitute into the query. If the query uses named
|
||||
* placeholders, this is an associative array in any order. If the query uses
|
||||
@@ -2829,7 +2888,7 @@ function db_drop_table($table) {
|
||||
* will be set to the value of the key in all rows. This is most useful for
|
||||
* creating NOT NULL columns with no default value in existing tables.
|
||||
* @param $keys_new
|
||||
* Optional keys and indexes specification to be created on the table along
|
||||
* (optional) Keys and indexes specification to be created on the table along
|
||||
* with adding the field. The format is the same as a table specification, but
|
||||
* without the 'fields' element. If you are adding a type 'serial' field, you
|
||||
* MUST specify at least one key or index including it in this array. See
|
||||
@@ -3009,7 +3068,7 @@ function db_drop_index($table, $name) {
|
||||
* @param $spec
|
||||
* The field specification for the new field.
|
||||
* @param $keys_new
|
||||
* Optional keys and indexes specification to be created on the table along
|
||||
* (optional) Keys and indexes specification to be created on the table along
|
||||
* with changing the field. The format is the same as a table specification
|
||||
* but without the 'fields' element.
|
||||
*/
|
||||
|
||||
@@ -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'];
|
||||
@@ -36,6 +42,10 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
||||
// Default to TCP connection on port 3306.
|
||||
$dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
|
||||
}
|
||||
// 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=' . $charset;
|
||||
$dsn .= ';dbname=' . $connection_options['database'];
|
||||
// Allow PDO options to be overridden.
|
||||
$connection_options += array(
|
||||
@@ -47,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']);
|
||||
|
||||
@@ -54,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
|
||||
@@ -72,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() {
|
||||
@@ -90,7 +107,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
||||
|
||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||
$tablename = $this->generateTemporaryTableName();
|
||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY SELECT', $query), $args, $options);
|
||||
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY ' . $query, $args, $options);
|
||||
return $tablename;
|
||||
}
|
||||
|
||||
@@ -195,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ class InsertQuery_mysql extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
if (!empty($this->fromQuery)) {
|
||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
|
||||
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
|
||||
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||
}
|
||||
|
||||
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
||||
@@ -86,21 +87,7 @@ class InsertQuery_mysql extends InsertQuery {
|
||||
}
|
||||
}
|
||||
|
||||
class TruncateQuery_mysql extends TruncateQuery {
|
||||
public function __toString() {
|
||||
// TRUNCATE is actually a DDL statement on MySQL, and DDL statements are
|
||||
// not transactional, and result in an implicit COMMIT. When we are in a
|
||||
// transaction, fallback to the slower, but transactional, DELETE.
|
||||
if ($this->connection->inTransaction()) {
|
||||
// Create a comment string to prepend to the query.
|
||||
$comments = $this->connection->makeComment($this->comments);
|
||||
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
|
||||
}
|
||||
else {
|
||||
return parent::__toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
class TruncateQuery_mysql extends TruncateQuery { }
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup database".
|
||||
|
||||
@@ -39,8 +39,8 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
$info['table'] = substr($table, ++$pos);
|
||||
}
|
||||
else {
|
||||
$db_info = Database::getConnectionInfo();
|
||||
$info['database'] = $db_info['default']['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);
|
||||
@@ -301,10 +309,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function renameTable($table, $new_name) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
if ($this->tableExists($new_name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
|
||||
$info = $this->getPrefixInfo($new_name);
|
||||
@@ -322,10 +330,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function addField($table, $field, $spec, $keys_new = array()) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
if ($this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
|
||||
$fixnull = FALSE;
|
||||
@@ -361,7 +369,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function fieldSetDefault($table, $field, $default) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
if (!isset($default)) {
|
||||
@@ -376,7 +384,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function fieldSetNoDefault($table, $field) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` DROP DEFAULT');
|
||||
@@ -391,10 +399,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function addPrimaryKey($table, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||
}
|
||||
if ($this->indexExists($table, 'PRIMARY')) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
|
||||
@@ -411,10 +419,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function addUniqueKey($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->indexExists($table, $name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD UNIQUE KEY `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
||||
@@ -431,10 +439,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function addIndex($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->indexExists($table, $name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
||||
@@ -451,10 +459,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
||||
|
||||
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||
}
|
||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||
}
|
||||
|
||||
$sql = 'ALTER TABLE {' . $table . '} CHANGE `' . $field . '` ' . $this->createFieldSql($field_new, $this->processField($spec));
|
||||
|
||||
@@ -146,7 +146,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
|
||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||
$tablename = $this->generateTemporaryTableName();
|
||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} AS SELECT', $query), $args, $options);
|
||||
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} AS ' . $query, $args, $options);
|
||||
return $tablename;
|
||||
}
|
||||
|
||||
@@ -216,6 +216,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function utf8mb4IsActive() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function utf8mb4IsSupported() {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,7 +112,8 @@ class InsertQuery_pgsql extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
if (!empty($this->fromQuery)) {
|
||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
|
||||
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
|
||||
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||
}
|
||||
|
||||
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
||||
|
||||
@@ -314,10 +314,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
function renameTable($table, $new_name) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
if ($this->tableExists($new_name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
|
||||
// Get the schema and tablename for the old table.
|
||||
@@ -351,10 +351,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function addField($table, $field, $spec, $new_keys = array()) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
if ($this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
|
||||
$fixnull = FALSE;
|
||||
@@ -393,7 +393,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function fieldSetDefault($table, $field, $default) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
if (!isset($default)) {
|
||||
@@ -408,7 +408,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function fieldSetNoDefault($table, $field) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" DROP DEFAULT');
|
||||
@@ -435,10 +435,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function addPrimaryKey($table, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||
}
|
||||
if ($this->constraintExists($table, 'pkey')) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . implode(',', $fields) . ')');
|
||||
@@ -455,10 +455,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
function addUniqueKey($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->constraintExists($table, $name . '_key')) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
|
||||
@@ -475,10 +475,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function addIndex($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->indexExists($table, $name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$this->connection->query($this->_createIndexSql($table, $name, $fields));
|
||||
@@ -495,10 +495,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
||||
|
||||
public function changeField($table, $field, $field_new, $spec, $new_keys = array()) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||
}
|
||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||
}
|
||||
|
||||
$spec = $this->processField($spec);
|
||||
|
||||
@@ -83,7 +83,7 @@ interface QueryConditionInterface {
|
||||
|
||||
/**
|
||||
* Sets a condition that the specified subquery returns values.
|
||||
*
|
||||
*
|
||||
* @param SelectQueryInterface $select
|
||||
* The subquery that must contain results.
|
||||
*
|
||||
@@ -91,10 +91,10 @@ interface QueryConditionInterface {
|
||||
* The called object.
|
||||
*/
|
||||
public function exists(SelectQueryInterface $select);
|
||||
|
||||
|
||||
/**
|
||||
* Sets a condition that the specified subquery returns no values.
|
||||
*
|
||||
*
|
||||
* @param SelectQueryInterface $select
|
||||
* The subquery that must not contain results.
|
||||
*
|
||||
@@ -102,7 +102,7 @@ interface QueryConditionInterface {
|
||||
* The called object.
|
||||
*/
|
||||
public function notExists(SelectQueryInterface $select);
|
||||
|
||||
|
||||
/**
|
||||
* Gets a complete list of all conditions in this conditional clause.
|
||||
*
|
||||
@@ -283,14 +283,14 @@ abstract class Query implements QueryPlaceholderInterface {
|
||||
|
||||
/**
|
||||
* The target of the connection object.
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $connectionTarget;
|
||||
|
||||
/**
|
||||
* The key of the connection object.
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $connectionKey;
|
||||
@@ -710,10 +710,11 @@ class InsertQuery extends Query {
|
||||
// first call to fields() does have an effect.
|
||||
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
|
||||
}
|
||||
|
||||
// Don't execute query without fields.
|
||||
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
||||
throw new NoFieldsException('There are no fields available to insert with.');
|
||||
else {
|
||||
// Don't execute query without fields.
|
||||
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
||||
throw new NoFieldsException('There are no fields available to insert with.');
|
||||
}
|
||||
}
|
||||
|
||||
// If no values have been added, silently ignore this query. This can happen
|
||||
@@ -804,7 +805,7 @@ class DeleteQuery extends Query implements QueryConditionInterface {
|
||||
$this->condition->notExists($select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -942,7 +943,17 @@ class TruncateQuery extends Query {
|
||||
// Create a sanitized comment string to prepend to the query.
|
||||
$comments = $this->connection->makeComment($this->comments);
|
||||
|
||||
return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
|
||||
// In most cases, TRUNCATE is not a transaction safe statement as it is a
|
||||
// DDL statement which results in an implicit COMMIT. When we are in a
|
||||
// transaction, fallback to the slower, but transactional, DELETE.
|
||||
// PostgreSQL also locks the entire table for a TRUNCATE strongly reducing
|
||||
// the concurrency with other transactions.
|
||||
if ($this->connection->inTransaction()) {
|
||||
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
|
||||
}
|
||||
else {
|
||||
return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,7 +1064,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
|
||||
$this->condition->notExists($select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -1545,7 +1556,7 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
||||
$this->condition->notExists($select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -1595,55 +1606,43 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
// Wrap multiple queries in a transaction, if the database supports it.
|
||||
$transaction = $this->connection->startTransaction();
|
||||
try {
|
||||
if (!count($this->condition)) {
|
||||
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
||||
if (!count($this->condition)) {
|
||||
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
||||
}
|
||||
$select = $this->connection->select($this->conditionTable)
|
||||
->condition($this->condition);
|
||||
$select->addExpression('1');
|
||||
if (!$select->execute()->fetchField()) {
|
||||
try {
|
||||
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
|
||||
if ($this->defaultFields) {
|
||||
$insert->useDefaults($this->defaultFields);
|
||||
}
|
||||
$insert->execute();
|
||||
return self::STATUS_INSERT;
|
||||
}
|
||||
$select = $this->connection->select($this->conditionTable)
|
||||
->condition($this->condition)
|
||||
->forUpdate();
|
||||
$select->addExpression('1');
|
||||
if (!$select->execute()->fetchField()) {
|
||||
try {
|
||||
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
|
||||
if ($this->defaultFields) {
|
||||
$insert->useDefaults($this->defaultFields);
|
||||
}
|
||||
$insert->execute();
|
||||
return MergeQuery::STATUS_INSERT;
|
||||
catch (Exception $e) {
|
||||
// The insert query failed, maybe it's because a racing insert query
|
||||
// beat us in inserting the same row. Retry the select query, if it
|
||||
// returns a row, ignore the error and continue with the update
|
||||
// query below.
|
||||
if (!$select->execute()->fetchField()) {
|
||||
throw $e;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
// The insert query failed, maybe it's because a racing insert query
|
||||
// beat us in inserting the same row. Retry the select query, if it
|
||||
// returns a row, ignore the error and continue with the update
|
||||
// query below.
|
||||
if (!$select->execute()->fetchField()) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->needsUpdate) {
|
||||
$update = $this->connection->update($this->table)
|
||||
->fields($this->updateFields)
|
||||
->condition($this->condition);
|
||||
if ($this->expressionFields) {
|
||||
foreach ($this->expressionFields as $field => $data) {
|
||||
$update->expression($field, $data['expression'], $data['arguments']);
|
||||
}
|
||||
}
|
||||
$update->execute();
|
||||
return MergeQuery::STATUS_UPDATE;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
// Something really wrong happened here, bubble up the exception to the
|
||||
// caller.
|
||||
$transaction->rollback();
|
||||
throw $e;
|
||||
}
|
||||
// Transaction commits here where $transaction looses scope.
|
||||
if ($this->needsUpdate) {
|
||||
$update = $this->connection->update($this->table)
|
||||
->fields($this->updateFields)
|
||||
->condition($this->condition);
|
||||
if ($this->expressionFields) {
|
||||
foreach ($this->expressionFields as $field => $data) {
|
||||
$update->expression($field, $data['expression'], $data['arguments']);
|
||||
}
|
||||
}
|
||||
$update->execute();
|
||||
return self::STATUS_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,7 +1694,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
||||
* Implements Countable::count().
|
||||
*
|
||||
* Returns the size of this conditional. The size of the conditional is the
|
||||
* size of its conditional array minus one, because one element is the the
|
||||
* size of its conditional array minus one, because one element is the
|
||||
* conjunction.
|
||||
*/
|
||||
public function count() {
|
||||
@@ -1762,14 +1761,14 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
||||
public function exists(SelectQueryInterface $select) {
|
||||
return $this->condition('', $select, 'EXISTS');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::notExists().
|
||||
*/
|
||||
public function notExists(SelectQueryInterface $select) {
|
||||
return $this->condition('', $select, 'NOT EXISTS');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
|
||||
@@ -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',
|
||||
@@ -416,7 +419,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||
* This is most useful for creating NOT NULL columns with no default
|
||||
* value in existing tables.
|
||||
* @param $keys_new
|
||||
* Optional keys and indexes specification to be created on the
|
||||
* (optional) Keys and indexes specification to be created on the
|
||||
* table along with adding the field. The format is the same as a
|
||||
* table specification but without the 'fields' element. If you are
|
||||
* adding a type 'serial' field, you MUST specify at least one key
|
||||
@@ -630,7 +633,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||
* @param $spec
|
||||
* The field specification for the new field.
|
||||
* @param $keys_new
|
||||
* Optional keys and indexes specification to be created on the
|
||||
* (optional) Keys and indexes specification to be created on the
|
||||
* table along with changing the field. The format is the same as a
|
||||
* table specification but without the 'fields' element.
|
||||
*
|
||||
@@ -654,7 +657,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||
*/
|
||||
public function createTable($name, $table) {
|
||||
if ($this->tableExists($name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t('Table %name already exists.', array('%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t('Table @name already exists.', array('@name' => $name)));
|
||||
}
|
||||
$statements = $this->createTableSql($name, $table);
|
||||
foreach ($statements as $statement) {
|
||||
|
||||
@@ -377,7 +377,8 @@ interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableIn
|
||||
* @param $field
|
||||
* The field on which to order.
|
||||
* @param $direction
|
||||
* The direction to sort. Legal values are "ASC" and "DESC".
|
||||
* The direction to sort. Legal values are "ASC" and "DESC". Any other value
|
||||
* will be converted to "ASC".
|
||||
* @return SelectQueryInterface
|
||||
* The called object.
|
||||
*/
|
||||
@@ -596,7 +597,7 @@ class SelectQueryExtender implements SelectQueryInterface {
|
||||
|
||||
public function hasAnyTag() {
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($this->query, 'hasAnyTags'), $args);
|
||||
return call_user_func_array(array($this->query, 'hasAnyTag'), $args);
|
||||
}
|
||||
|
||||
public function addMetaData($key, $object) {
|
||||
@@ -1384,6 +1385,8 @@ class SelectQuery extends Query implements SelectQueryInterface {
|
||||
}
|
||||
|
||||
public function orderBy($field, $direction = 'ASC') {
|
||||
// Only allow ASC and DESC, default to ASC.
|
||||
$direction = strtoupper($direction) == 'DESC' ? 'DESC' : 'ASC';
|
||||
$this->order[$field] = $direction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
|
||||
$prefixes[$tablename] = '';
|
||||
$this->setPrefix($prefixes);
|
||||
|
||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
|
||||
$this->query('CREATE TEMPORARY TABLE ' . $tablename . ' AS ' . $query, $args, $options);
|
||||
return $tablename;
|
||||
}
|
||||
|
||||
@@ -378,6 +378,14 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public function utf8mb4IsActive() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function utf8mb4IsSupported() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -41,7 +41,8 @@ class InsertQuery_sqlite extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
if (!empty($this->fromQuery)) {
|
||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
|
||||
$insert_fields_string = $this->insertFields ? ' (' . implode(', ', $this->insertFields) . ') ' : ' ';
|
||||
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||
}
|
||||
|
||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
|
||||
|
||||
@@ -232,10 +232,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function renameTable($table, $new_name) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
if ($this->tableExists($new_name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||
}
|
||||
|
||||
$schema = $this->introspectSchema($table);
|
||||
@@ -278,10 +278,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function addField($table, $field, $specification, $keys_new = array()) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
if ($this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||
}
|
||||
|
||||
// SQLite doesn't have a full-featured ALTER TABLE statement. It only
|
||||
@@ -494,10 +494,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||
}
|
||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||
}
|
||||
|
||||
$old_schema = $this->introspectSchema($table);
|
||||
@@ -559,10 +559,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function addIndex($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->indexExists($table, $name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$schema['indexes'][$name] = $fields;
|
||||
@@ -591,10 +591,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function addUniqueKey($table, $name, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
if ($this->indexExists($table, $name)) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||
}
|
||||
|
||||
$schema['unique keys'][$name] = $fields;
|
||||
@@ -617,14 +617,14 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function addPrimaryKey($table, $fields) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||
}
|
||||
|
||||
$old_schema = $this->introspectSchema($table);
|
||||
$new_schema = $old_schema;
|
||||
|
||||
if (!empty($new_schema['primary key'])) {
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||
}
|
||||
|
||||
$new_schema['primary key'] = $fields;
|
||||
@@ -646,7 +646,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function fieldSetDefault($table, $field, $default) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
$old_schema = $this->introspectSchema($table);
|
||||
@@ -658,7 +658,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
|
||||
public function fieldSetNoDefault($table, $field) {
|
||||
if (!$this->fieldExists($table, $field)) {
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||
}
|
||||
|
||||
$old_schema = $this->introspectSchema($table);
|
||||
|
||||
@@ -13,14 +13,6 @@
|
||||
*/
|
||||
interface DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType);
|
||||
|
||||
/**
|
||||
* Resets the internal, static entity cache.
|
||||
*
|
||||
@@ -36,7 +28,9 @@ interface DrupalEntityControllerInterface {
|
||||
* @param $ids
|
||||
* An array of entity IDs, or FALSE to load all entities.
|
||||
* @param $conditions
|
||||
* An array of conditions in the form 'field' => $value.
|
||||
* An array of conditions. Keys are field names on the entity's base table.
|
||||
* Values will be compared for equality. All the comparisons will be ANDed
|
||||
* together. This parameter is deprecated; use an EntityFieldQuery instead.
|
||||
*
|
||||
* @return
|
||||
* An array of entity objects indexed by their ids. When no results are
|
||||
@@ -54,7 +48,7 @@ interface DrupalEntityControllerInterface {
|
||||
class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Static cache of entities.
|
||||
* Static cache of entities, keyed by entity ID.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -119,6 +113,9 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructor: sets basic variables.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType) {
|
||||
$this->entityType = $entityType;
|
||||
@@ -186,6 +183,11 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure integer entity IDs are valid.
|
||||
if (!empty($ids)) {
|
||||
$this->cleanIds($ids);
|
||||
}
|
||||
|
||||
// Load any remaining entities from the database. This is the case if $ids
|
||||
// is set to FALSE (so we load all entities), if there are any ids left to
|
||||
// load, if loading a revision, or if $conditions was passed without $ids.
|
||||
@@ -226,6 +228,35 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures integer entity IDs are valid.
|
||||
*
|
||||
* The identifier sanitization provided by this method has been introduced
|
||||
* as Drupal used to rely on the database to facilitate this, which worked
|
||||
* correctly with MySQL but led to errors with other DBMS such as PostgreSQL.
|
||||
*
|
||||
* @param array $ids
|
||||
* The entity IDs to verify. Non-integer IDs are removed from this array if
|
||||
* the entity type requires IDs to be integers.
|
||||
*/
|
||||
protected function cleanIds(&$ids) {
|
||||
$entity_info = entity_get_info($this->entityType);
|
||||
if (isset($entity_info['base table field types'])) {
|
||||
$id_type = $entity_info['base table field types'][$this->idKey];
|
||||
if ($id_type == 'serial' || $id_type == 'int') {
|
||||
$ids = array_filter($ids, array($this, 'filterId'));
|
||||
$ids = array_map('intval', $ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for array_filter that removes non-integer IDs.
|
||||
*/
|
||||
protected function filterId($id) {
|
||||
return is_numeric($id) && $id == (int) $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the query to load the entity.
|
||||
*
|
||||
@@ -241,7 +272,9 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
* @param $ids
|
||||
* An array of entity IDs, or FALSE to load all entities.
|
||||
* @param $conditions
|
||||
* An array of conditions in the form 'field' => $value.
|
||||
* An array of conditions. Keys are field names on the entity's base table.
|
||||
* Values will be compared for equality. All the comparisons will be ANDed
|
||||
* together. This parameter is deprecated; use an EntityFieldQuery instead.
|
||||
* @param $revision_id
|
||||
* The ID of the revision to load, or FALSE if this query is asking for the
|
||||
* most current revision(s).
|
||||
@@ -365,9 +398,23 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
// This ensures the same behavior whether loading from memory or database.
|
||||
if ($conditions) {
|
||||
foreach ($entities as $entity) {
|
||||
$entity_values = (array) $entity;
|
||||
if (array_diff_assoc($conditions, $entity_values)) {
|
||||
unset($entities[$entity->{$this->idKey}]);
|
||||
// Iterate over all conditions and compare them to the entity
|
||||
// properties. We cannot use array_diff_assoc() here since the
|
||||
// conditions can be nested arrays, too.
|
||||
foreach ($conditions as $property_name => $condition) {
|
||||
if (is_array($condition)) {
|
||||
// Multiple condition values for one property are treated as OR
|
||||
// operation: only if the value is not at all in the condition array
|
||||
// we remove the entity.
|
||||
if (!in_array($entity->{$property_name}, $condition)) {
|
||||
unset($entities[$entity->{$this->idKey}]);
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
elseif ($condition != $entity->{$property_name}) {
|
||||
unset($entities[$entity->{$this->idKey}]);
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,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.
|
||||
@@ -634,21 +681,43 @@ class EntityFieldQuery {
|
||||
|
||||
/**
|
||||
* Adds a condition on field values.
|
||||
*
|
||||
*
|
||||
* Note that entities with empty field values will be excluded from the
|
||||
* EntityFieldQuery results when using this method.
|
||||
*
|
||||
* @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.
|
||||
@@ -723,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
|
||||
@@ -744,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.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Maps PHP error constants to watchdog severity levels.
|
||||
*
|
||||
* The error constants are documented at
|
||||
* http://php.net/manual/en/errorfunc.constants.php
|
||||
* http://php.net/manual/errorfunc.constants.php
|
||||
*
|
||||
* @ingroup logging_severity_levels
|
||||
*/
|
||||
@@ -169,7 +169,7 @@ function error_displayable($error = NULL) {
|
||||
* TRUE if the error is fatal.
|
||||
*/
|
||||
function _drupal_log_error($error, $fatal = FALSE) {
|
||||
// Initialize a maintenance theme if the boostrap was not complete.
|
||||
// Initialize a maintenance theme if the bootstrap was not complete.
|
||||
// Do it early because drupal_set_message() triggers a drupal_theme_initialize().
|
||||
if ($fatal && (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL)) {
|
||||
unset($GLOBALS['theme']);
|
||||
@@ -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)');
|
||||
|
||||
@@ -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);
|
||||
@@ -470,8 +472,11 @@ function file_ensure_htaccess() {
|
||||
* @param $private
|
||||
* FALSE indicates that $directory should be an open and public directory.
|
||||
* The default is TRUE which indicates a private and protected directory.
|
||||
* @param $force_overwrite
|
||||
* Set to TRUE to attempt to overwrite the existing .htaccess file if one is
|
||||
* already present. Defaults to FALSE.
|
||||
*/
|
||||
function file_create_htaccess($directory, $private = TRUE) {
|
||||
function file_create_htaccess($directory, $private = TRUE, $force_overwrite = FALSE) {
|
||||
if (file_uri_scheme($directory)) {
|
||||
$directory = file_stream_wrapper_uri_normalize($directory);
|
||||
}
|
||||
@@ -480,19 +485,12 @@ function file_create_htaccess($directory, $private = TRUE) {
|
||||
}
|
||||
$htaccess_path = $directory . '/.htaccess';
|
||||
|
||||
if (file_exists($htaccess_path)) {
|
||||
if (file_exists($htaccess_path) && !$force_overwrite) {
|
||||
// Short circuit if the .htaccess file already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($private) {
|
||||
// Private .htaccess file.
|
||||
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks";
|
||||
}
|
||||
else {
|
||||
// Public .htaccess file.
|
||||
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks";
|
||||
}
|
||||
$htaccess_lines = file_htaccess_lines($private);
|
||||
|
||||
// Write the .htaccess file.
|
||||
if (file_put_contents($htaccess_path, $htaccess_lines)) {
|
||||
@@ -504,6 +502,45 @@ function file_create_htaccess($directory, $private = TRUE) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard .htaccess lines that Drupal writes to file directories.
|
||||
*
|
||||
* @param $private
|
||||
* (Optional) Set to FALSE to return the .htaccess lines for an open and
|
||||
* public directory. The default is TRUE, which returns the .htaccess lines
|
||||
* for a private and protected directory.
|
||||
*
|
||||
* @return
|
||||
* A string representing the desired contents of the .htaccess file.
|
||||
*
|
||||
* @see file_create_htaccess()
|
||||
*/
|
||||
function file_htaccess_lines($private = TRUE) {
|
||||
$lines = <<<EOF
|
||||
# Turn off all options we don't need.
|
||||
Options None
|
||||
Options +FollowSymLinks
|
||||
|
||||
# Set the catch-all handler to prevent scripts from being executed.
|
||||
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
|
||||
<Files *>
|
||||
# Override the handler again if we're run later in the evaluation list.
|
||||
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
|
||||
</Files>
|
||||
|
||||
# If we know how to do it safely, disable the PHP engine entirely.
|
||||
<IfModule mod_php5.c>
|
||||
php_flag engine off
|
||||
</IfModule>
|
||||
EOF;
|
||||
|
||||
if ($private) {
|
||||
$lines = "Deny from all\n\n" . $lines;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads file objects from the database.
|
||||
*
|
||||
@@ -586,7 +623,11 @@ function file_save(stdClass $file) {
|
||||
module_invoke_all('entity_update', $file, 'file');
|
||||
}
|
||||
|
||||
// Clear internal properties.
|
||||
unset($file->original);
|
||||
// Clear the static loading cache.
|
||||
entity_get_controller('file')->resetCache(array($file->fid));
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
@@ -719,10 +760,11 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c
|
||||
* stored in the database. This is a powerful function that in many ways
|
||||
* performs like an advanced version of copy().
|
||||
* - Checks if $source and $destination are valid and readable/writable.
|
||||
* - Checks that $source is not equal to $destination; if they are an error
|
||||
* is reported.
|
||||
* - If file already exists in $destination either the call will error out,
|
||||
* replace the file or rename the file based on the $replace parameter.
|
||||
* - If the $source and $destination are equal, the behavior depends on the
|
||||
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
|
||||
* will rename the file until the $destination is unique.
|
||||
* - Adds the new file to the files database. If the source file is a
|
||||
* temporary file, the resulting file will also be a temporary file. See
|
||||
* file_save_upload() for details on temporary files.
|
||||
@@ -817,10 +859,11 @@ function file_valid_uri($uri) {
|
||||
* This is a powerful function that in many ways performs like an advanced
|
||||
* version of copy().
|
||||
* - Checks if $source and $destination are valid and readable/writable.
|
||||
* - Checks that $source is not equal to $destination; if they are an error
|
||||
* is reported.
|
||||
* - If file already exists in $destination either the call will error out,
|
||||
* replace the file or rename the file based on the $replace parameter.
|
||||
* - If the $source and $destination are equal, the behavior depends on the
|
||||
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
|
||||
* will rename the file until the $destination is unique.
|
||||
* - Provides a fallback using realpaths if the move fails using stream
|
||||
* wrappers. This can occur because PHP's copy() function does not properly
|
||||
* support streams if safe_mode or open_basedir are enabled. See
|
||||
@@ -1108,10 +1151,10 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
||||
|
||||
// Allow potentially insecure uploads for very savvy users and admin
|
||||
if (!variable_get('allow_insecure_uploads', 0)) {
|
||||
// Remove any null bytes. See http://php.net/manual/en/security.filesystem.nullbytes.php
|
||||
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
|
||||
$filename = str_replace(chr(0), '', $filename);
|
||||
|
||||
$whitelist = array_unique(explode(' ', trim($extensions)));
|
||||
$whitelist = array_unique(explode(' ', strtolower(trim($extensions))));
|
||||
|
||||
// Split the filename up by periods. The first part becomes the basename
|
||||
// the last part the final extension.
|
||||
@@ -1124,7 +1167,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
||||
// of allowed extensions.
|
||||
foreach ($filename_parts as $filename_part) {
|
||||
$new_filename .= '.' . $filename_part;
|
||||
if (!in_array($filename_part, $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
|
||||
if (!in_array(strtolower($filename_part), $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
|
||||
$new_filename .= '_';
|
||||
}
|
||||
}
|
||||
@@ -1256,6 +1299,7 @@ function file_delete(stdClass $file, $force = FALSE) {
|
||||
if (file_unmanaged_delete($file->uri)) {
|
||||
db_delete('file_managed')->condition('fid', $file->fid)->execute();
|
||||
db_delete('file_usage')->condition('fid', $file->fid)->execute();
|
||||
entity_get_controller('file')->resetCache();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1365,8 +1409,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
||||
* Temporary files are periodically cleaned. To make the file a permanent file,
|
||||
* assign the status and use file_save() to save the changes.
|
||||
*
|
||||
* @param $source
|
||||
* A string specifying the filepath or URI of the uploaded file to save.
|
||||
* @param $form_field_name
|
||||
* A string that is the associative array key of the upload form element in
|
||||
* the form array.
|
||||
* @param $validators
|
||||
* An optional, associative array of callback functions used to validate the
|
||||
* file. See file_validate() for a full discussion of the array format.
|
||||
@@ -1377,9 +1422,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
||||
* (Beware: this is not safe and should only be allowed for trusted users, if
|
||||
* at all).
|
||||
* @param $destination
|
||||
* A string containing the URI $source should be copied to.
|
||||
* This must be a stream wrapper URI. If this value is omitted, Drupal's
|
||||
* temporary files scheme will be used ("temporary://").
|
||||
* A string containing the URI that the file should be copied to. This must
|
||||
* be a stream wrapper URI. If this value is omitted, Drupal's temporary
|
||||
* files scheme will be used ("temporary://").
|
||||
* @param $replace
|
||||
* Replace behavior when the destination file already exists:
|
||||
* - FILE_EXISTS_REPLACE: Replace the existing file.
|
||||
@@ -1397,45 +1442,45 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
||||
* - source: Path to the file before it is moved.
|
||||
* - destination: Path to the file after it is moved (same as 'uri').
|
||||
*/
|
||||
function file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
|
||||
function file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
|
||||
global $user;
|
||||
static $upload_cache;
|
||||
|
||||
// Return cached objects without processing since the file will have
|
||||
// already been processed and the paths in _FILES will be invalid.
|
||||
if (isset($upload_cache[$source])) {
|
||||
return $upload_cache[$source];
|
||||
if (isset($upload_cache[$form_field_name])) {
|
||||
return $upload_cache[$form_field_name];
|
||||
}
|
||||
|
||||
// Make sure there's an upload to process.
|
||||
if (empty($_FILES['files']['name'][$source])) {
|
||||
if (empty($_FILES['files']['name'][$form_field_name])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check for file upload errors and return FALSE if a lower level system
|
||||
// error occurred. For a complete list of errors:
|
||||
// See http://php.net/manual/en/features.file-upload.errors.php.
|
||||
switch ($_FILES['files']['error'][$source]) {
|
||||
// See http://php.net/manual/features.file-upload.errors.php.
|
||||
switch ($_FILES['files']['error'][$form_field_name]) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))), 'error');
|
||||
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$form_field_name], '%maxsize' => format_size(file_upload_max_size()))), 'error');
|
||||
return FALSE;
|
||||
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])), 'error');
|
||||
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
|
||||
return FALSE;
|
||||
|
||||
case UPLOAD_ERR_OK:
|
||||
// Final check that this is a valid upload, if it isn't, use the
|
||||
// default error handler.
|
||||
if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
|
||||
if (is_uploaded_file($_FILES['files']['tmp_name'][$form_field_name])) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Unknown error
|
||||
default:
|
||||
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])), 'error');
|
||||
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1443,10 +1488,10 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
$file = new stdClass();
|
||||
$file->uid = $user->uid;
|
||||
$file->status = 0;
|
||||
$file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
|
||||
$file->uri = $_FILES['files']['tmp_name'][$source];
|
||||
$file->filename = trim(drupal_basename($_FILES['files']['name'][$form_field_name]), '.');
|
||||
$file->uri = $_FILES['files']['tmp_name'][$form_field_name];
|
||||
$file->filemime = file_get_mimetype($file->filename);
|
||||
$file->filesize = $_FILES['files']['size'][$source];
|
||||
$file->filesize = $_FILES['files']['size'][$form_field_name];
|
||||
|
||||
$extensions = '';
|
||||
if (isset($validators['file_validate_extensions'])) {
|
||||
@@ -1503,7 +1548,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$file->source = $source;
|
||||
$file->source = $form_field_name;
|
||||
// A URI may already have a trailing slash or look like "public://".
|
||||
if (substr($destination, -1) != '/') {
|
||||
$destination .= '/';
|
||||
@@ -1512,11 +1557,11 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
||||
// there's an existing file so we need to bail.
|
||||
if ($file->destination === FALSE) {
|
||||
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)), 'error');
|
||||
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)), 'error');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add in our check of the the file name length.
|
||||
// Add in our check of the file name length.
|
||||
$validators['file_validate_name_length'] = array();
|
||||
|
||||
// Call the validation functions specified by this function's caller.
|
||||
@@ -1531,7 +1576,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
else {
|
||||
$message .= ' ' . array_pop($errors);
|
||||
}
|
||||
form_set_error($source, $message);
|
||||
form_set_error($form_field_name, $message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1539,8 +1584,8 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
// directory. This overcomes open_basedir restrictions for future file
|
||||
// operations.
|
||||
$file->uri = $file->destination;
|
||||
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
|
||||
form_set_error($source, t('File upload error. Could not move uploaded file.'));
|
||||
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$form_field_name], $file->uri)) {
|
||||
form_set_error($form_field_name, t('File upload error. Could not move uploaded file.'));
|
||||
watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1560,7 +1605,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
// If we made it this far it's safe to record this file in the database.
|
||||
if ($file = file_save($file)) {
|
||||
// Add file to the cache.
|
||||
$upload_cache[$source] = $file;
|
||||
$upload_cache[$form_field_name] = $file;
|
||||
return $file;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1686,8 +1731,6 @@ function file_validate_extensions(stdClass $file, $extensions) {
|
||||
/**
|
||||
* Checks that the file's size is below certain limits.
|
||||
*
|
||||
* This check is not enforced for the user #1.
|
||||
*
|
||||
* @param $file
|
||||
* A Drupal file object.
|
||||
* @param $file_limit
|
||||
@@ -1705,20 +1748,17 @@ function file_validate_extensions(stdClass $file, $extensions) {
|
||||
*/
|
||||
function file_validate_size(stdClass $file, $file_limit = 0, $user_limit = 0) {
|
||||
global $user;
|
||||
|
||||
$errors = array();
|
||||
|
||||
// Bypass validation for uid = 1.
|
||||
if ($user->uid != 1) {
|
||||
if ($file_limit && $file->filesize > $file_limit) {
|
||||
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
|
||||
}
|
||||
|
||||
// Save a query by only calling file_space_used() when a limit is provided.
|
||||
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
|
||||
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
|
||||
}
|
||||
if ($file_limit && $file->filesize > $file_limit) {
|
||||
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
|
||||
}
|
||||
|
||||
// Save a query by only calling file_space_used() when a limit is provided.
|
||||
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
|
||||
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
@@ -1747,7 +1787,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
|
||||
@@ -1956,23 +1996,7 @@ function file_download() {
|
||||
$target = implode('/', $args);
|
||||
$uri = $scheme . '://' . $target;
|
||||
if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
|
||||
// Let other modules provide headers and controls access to the file.
|
||||
// module_invoke_all() uses array_merge_recursive() which merges header
|
||||
// values into a new array. To avoid that and allow modules to override
|
||||
// headers instead, use array_merge() to merge the returned arrays.
|
||||
$headers = array();
|
||||
foreach (module_implements('file_download') as $module) {
|
||||
$function = $module . '_file_download';
|
||||
$result = $function($uri);
|
||||
if ($result == -1) {
|
||||
// Throw away the headers received so far.
|
||||
$headers = array();
|
||||
break;
|
||||
}
|
||||
if (isset($result) && is_array($result)) {
|
||||
$headers = array_merge($headers, $result);
|
||||
}
|
||||
}
|
||||
$headers = file_download_headers($uri);
|
||||
if (count($headers)) {
|
||||
file_transfer($uri, $headers);
|
||||
}
|
||||
@@ -1984,6 +2008,69 @@ function file_download() {
|
||||
drupal_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves headers for a private file download.
|
||||
*
|
||||
* Calls all module implementations of hook_file_download() to retrieve headers
|
||||
* for files by the module that originally provided the file. The presence of
|
||||
* returned headers indicates the current user has access to the file.
|
||||
*
|
||||
* @param $uri
|
||||
* The URI for the file whose headers should be retrieved.
|
||||
*
|
||||
* @return
|
||||
* If access is allowed, headers for the file, suitable for passing to
|
||||
* file_transfer(). If access is not allowed, an empty array will be returned.
|
||||
*
|
||||
* @see file_transfer()
|
||||
* @see file_download_access()
|
||||
* @see hook_file_download()
|
||||
*/
|
||||
function file_download_headers($uri) {
|
||||
// Let other modules provide headers and control access to the file.
|
||||
// module_invoke_all() uses array_merge_recursive() which merges header
|
||||
// values into a new array. To avoid that and allow modules to override
|
||||
// headers instead, use array_merge() to merge the returned arrays.
|
||||
$headers = array();
|
||||
foreach (module_implements('file_download') as $module) {
|
||||
$function = $module . '_file_download';
|
||||
$result = $function($uri);
|
||||
if ($result == -1) {
|
||||
// Throw away the headers received so far.
|
||||
$headers = array();
|
||||
break;
|
||||
}
|
||||
if (isset($result) && is_array($result)) {
|
||||
$headers = array_merge($headers, $result);
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the current user has access to a particular file.
|
||||
*
|
||||
* The return value of this function hinges on the return value from
|
||||
* file_download_headers(), which is the function responsible for collecting
|
||||
* access information through hook_file_download().
|
||||
*
|
||||
* If immediately transferring the file to the browser and the headers will
|
||||
* need to be retrieved, the return value of file_download_headers() should be
|
||||
* used to determine access directly, so that access checks will not be run
|
||||
* twice.
|
||||
*
|
||||
* @param $uri
|
||||
* The URI for the file whose access should be retrieved.
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE if access is allowed. FALSE if access is not allowed.
|
||||
*
|
||||
* @see file_download_headers()
|
||||
* @see hook_file_download()
|
||||
*/
|
||||
function file_download_access($uri) {
|
||||
return count(file_download_headers($uri)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all files that match a given mask in a given directory.
|
||||
@@ -2177,7 +2264,7 @@ function drupal_chmod($uri, $mode = NULL) {
|
||||
* @param $uri
|
||||
* A URI or pathname.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
@@ -2199,29 +2286,21 @@ function drupal_unlink($uri, $context = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute local filesystem path of a stream URI.
|
||||
* Resolves the absolute filepath of a local URI or filepath.
|
||||
*
|
||||
* This function was originally written to ease the conversion of 6.x code to
|
||||
* use 7.x stream wrappers. However, it assumes that every URI may be resolved
|
||||
* to an absolute local filesystem path, and this assumption fails when stream
|
||||
* wrappers are used to support remote file storage. Remote stream wrappers
|
||||
* may implement the realpath method by always returning FALSE. The use of
|
||||
* drupal_realpath() is discouraged, and is slowly being removed from core
|
||||
* functions where possible.
|
||||
* The use of drupal_realpath() is discouraged, because it does not work for
|
||||
* remote URIs. Except in rare cases, URIs should not be manually resolved.
|
||||
*
|
||||
* Only use this function if you know that the stream wrapper in the URI uses
|
||||
* the local file system, and you need to pass an absolute path to a function
|
||||
* that is incompatible with stream URIs.
|
||||
*
|
||||
* @param $uri
|
||||
* A stream wrapper URI or a filesystem path, possibly including one or more
|
||||
* symbolic links.
|
||||
* @param string $uri
|
||||
* A stream wrapper URI or a filepath, possibly including one or more symbolic
|
||||
* links.
|
||||
*
|
||||
* @return
|
||||
* The absolute local filesystem path (with no symbolic links), or FALSE on
|
||||
* failure.
|
||||
*
|
||||
* @todo This function is deprecated, and should be removed wherever possible.
|
||||
* @return string|false
|
||||
* The absolute local filepath (with no symbolic links), or FALSE on failure.
|
||||
*
|
||||
* @see DrupalStreamWrapperInterface::realpath()
|
||||
* @see http://php.net/manual/function.realpath.php
|
||||
@@ -2318,7 +2397,7 @@ function drupal_basename($uri, $suffix = NULL) {
|
||||
* @param $recursive
|
||||
* Default to FALSE.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
@@ -2349,7 +2428,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
||||
* @param $uri
|
||||
* A URI or pathname.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
|
||||
@@ -43,6 +43,7 @@ function file_default_mimetype_mapping() {
|
||||
4 => 'application/cap',
|
||||
5 => 'application/cu-seeme',
|
||||
6 => 'application/dsptype',
|
||||
350 => 'application/epub+zip',
|
||||
7 => 'application/hta',
|
||||
8 => 'application/java-archive',
|
||||
9 => 'application/java-serialized-object',
|
||||
@@ -64,6 +65,7 @@ function file_default_mimetype_mapping() {
|
||||
25 => 'application/rss+xml',
|
||||
26 => 'application/rtf',
|
||||
27 => 'application/smil',
|
||||
349 => 'application/vnd.amazon.ebook',
|
||||
28 => 'application/vnd.cinderella',
|
||||
29 => 'application/vnd.google-earth.kml+xml',
|
||||
30 => 'application/vnd.google-earth.kmz',
|
||||
@@ -183,6 +185,8 @@ function file_default_mimetype_mapping() {
|
||||
144 => 'application/x-lzx',
|
||||
145 => 'application/x-maker',
|
||||
146 => 'application/x-mif',
|
||||
351 => 'application/x-mobipocket-ebook',
|
||||
352 => 'application/x-mobipocket-ebook',
|
||||
147 => 'application/x-ms-wmd',
|
||||
148 => 'application/x-ms-wmz',
|
||||
149 => 'application/x-msdos-program',
|
||||
@@ -228,8 +232,10 @@ function file_default_mimetype_mapping() {
|
||||
188 => 'audio/mpeg',
|
||||
189 => 'audio/ogg',
|
||||
190 => 'audio/prs.sid',
|
||||
356 => 'audio/webm',
|
||||
191 => 'audio/x-aiff',
|
||||
192 => 'audio/x-gsm',
|
||||
354 => 'audio/x-matroska',
|
||||
193 => 'audio/x-mpegurl',
|
||||
194 => 'audio/x-ms-wax',
|
||||
195 => 'audio/x-ms-wma',
|
||||
@@ -301,6 +307,7 @@ function file_default_mimetype_mapping() {
|
||||
261 => 'image/vnd.djvu',
|
||||
262 => 'image/vnd.microsoft.icon',
|
||||
263 => 'image/vnd.wap.wbmp',
|
||||
355 => 'image/webp',
|
||||
264 => 'image/x-cmu-raster',
|
||||
265 => 'image/x-coreldraw',
|
||||
266 => 'image/x-coreldrawpattern',
|
||||
@@ -337,6 +344,7 @@ function file_default_mimetype_mapping() {
|
||||
297 => 'text/vnd.sun.j2me.app-descriptor',
|
||||
298 => 'text/vnd.wap.wml',
|
||||
299 => 'text/vnd.wap.wmlscript',
|
||||
358 => 'text/vtt',
|
||||
300 => 'text/x-bibtex',
|
||||
301 => 'text/x-boo',
|
||||
302 => 'text/x-c++hdr',
|
||||
@@ -371,9 +379,11 @@ function file_default_mimetype_mapping() {
|
||||
331 => 'video/ogg',
|
||||
332 => 'video/quicktime',
|
||||
333 => 'video/vnd.mpegurl',
|
||||
357 => 'video/webm',
|
||||
347 => 'video/x-flv',
|
||||
334 => 'video/x-la-asf',
|
||||
348 => 'video/x-m4v',
|
||||
353 => 'video/x-matroska',
|
||||
335 => 'video/x-mng',
|
||||
336 => 'video/x-ms-asf',
|
||||
337 => 'video/x-ms-wm',
|
||||
@@ -854,6 +864,16 @@ function file_default_mimetype_mapping() {
|
||||
'f4b' => 346,
|
||||
'flv' => 347,
|
||||
'm4v' => 348,
|
||||
'azw' => 349,
|
||||
'epub' => 350,
|
||||
'mobi' => 351,
|
||||
'prc' => 352,
|
||||
'mkv' => 353,
|
||||
'mka' => 354,
|
||||
'webp' => 355,
|
||||
'weba' => 356,
|
||||
'webm' => 357,
|
||||
'vtt' => 358,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,11 +82,11 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
||||
if (!$list) {
|
||||
$list = array();
|
||||
}
|
||||
foreach ($list as $item){
|
||||
foreach ($list as $item) {
|
||||
if ($item == '.' || $item == '..') {
|
||||
continue;
|
||||
}
|
||||
if (@ftp_chdir($this->connection, $item)){
|
||||
if (@ftp_chdir($this->connection, $item)) {
|
||||
ftp_cdup($this->connection);
|
||||
$this->removeDirectory(ftp_pwd($this->connection) . '/' . $item);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
||||
|
||||
function chmodJailed($path, $mode, $recursive) {
|
||||
if (!ftp_chmod($this->connection, $mode, $path)) {
|
||||
throw new FileTransferException("Unable to set permissions on %file", NULL, array ('%file' => $path));
|
||||
throw new FileTransferException("Unable to set permissions on %file", NULL, array('%file' => $path));
|
||||
}
|
||||
if ($this->isDirectory($path) && $recursive) {
|
||||
$filelist = @ftp_nlist($this->connection, $path);
|
||||
|
||||
@@ -72,7 +72,8 @@ class FileTransferSSH extends FileTransfer implements FileTransferChmodInterface
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
||||
}
|
||||
}
|
||||
@@ -85,7 +86,8 @@ class FileTransferSSH extends FileTransfer implements FileTransferChmodInterface
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
* reference the form builder function using \@see. For examples, of this see
|
||||
* system_modules_uninstall() or user_pass(), the latter of which has the
|
||||
* following in its doxygen documentation:
|
||||
*
|
||||
* \@ingroup forms
|
||||
* \@see user_pass_validate().
|
||||
* \@see user_pass_submit().
|
||||
* - \@ingroup forms
|
||||
* - \@see user_pass_validate()
|
||||
* - \@see user_pass_submit()
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@@ -106,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
|
||||
@@ -168,6 +168,12 @@ function drupal_get_form($form_id) {
|
||||
* processed.
|
||||
* - base_form_id: Identification for a base form, as declared in a
|
||||
* hook_forms() implementation.
|
||||
* - immutable: If this flag is set to TRUE, a new form build id is
|
||||
* generated when the form is loaded from the cache. If it is subsequently
|
||||
* saved to the cache again, it will have another cache id and therefore
|
||||
* the original form and form-state will remain unaltered. This is
|
||||
* important when page caching is enabled in order to prevent form state
|
||||
* from leaking between anonymous users.
|
||||
* - rebuild_info: Internal. Similar to 'build_info', but pertaining to
|
||||
* drupal_rebuild_form().
|
||||
* - rebuild: Normally, after the entire form processing is completed and
|
||||
@@ -235,6 +241,12 @@ function drupal_get_form($form_id) {
|
||||
* likely to occur during Ajax operations.
|
||||
* - programmed: If TRUE, the form was submitted programmatically, usually
|
||||
* invoked via drupal_form_submit(). Defaults to FALSE.
|
||||
* - programmed_bypass_access_check: If TRUE, programmatic form submissions
|
||||
* are processed without taking #access into account. Set this to FALSE
|
||||
* when submitting a form programmatically with values that may have been
|
||||
* input by the user executing the current request; this will cause #access
|
||||
* to be respected as it would on a normal form submission. Defaults to
|
||||
* TRUE.
|
||||
* - process_input: Boolean flag. TRUE signifies correct form submission.
|
||||
* This is always TRUE for programmed forms coming from drupal_form_submit()
|
||||
* (see 'programmed' key), or if the form_id coming from the $_POST data is
|
||||
@@ -402,6 +414,7 @@ function form_state_defaults() {
|
||||
'submitted' => FALSE,
|
||||
'executed' => FALSE,
|
||||
'programmed' => FALSE,
|
||||
'programmed_bypass_access_check' => TRUE,
|
||||
'cache'=> FALSE,
|
||||
'method' => 'post',
|
||||
'groups' => array(),
|
||||
@@ -452,17 +465,25 @@ function drupal_rebuild_form($form_id, &$form_state, $old_form = NULL) {
|
||||
$form = drupal_retrieve_form($form_id, $form_state);
|
||||
|
||||
// If only parts of the form will be returned to the browser (e.g., Ajax or
|
||||
// RIA clients), re-use the old #build_id to not require client-side code to
|
||||
// manually update the hidden 'build_id' input element.
|
||||
// RIA clients), or if the form already had a new build ID regenerated when it
|
||||
// was retrieved from the form cache, reuse the existing #build_id.
|
||||
// Otherwise, a new #build_id is generated, to not clobber the previous
|
||||
// build's data in the form cache; also allowing the user to go back to an
|
||||
// earlier build, make changes, and re-submit.
|
||||
// @see drupal_prepare_form()
|
||||
if (isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id'])) {
|
||||
$enforce_old_build_id = isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id']);
|
||||
$old_form_is_mutable_copy = isset($old_form['#build_id_old']);
|
||||
if ($enforce_old_build_id || $old_form_is_mutable_copy) {
|
||||
$form['#build_id'] = $old_form['#build_id'];
|
||||
if ($old_form_is_mutable_copy) {
|
||||
$form['#build_id_old'] = $old_form['#build_id_old'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
|
||||
if (isset($old_form['#build_id'])) {
|
||||
$form['#build_id_old'] = $old_form['#build_id'];
|
||||
}
|
||||
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||
}
|
||||
|
||||
// #action defaults to request_uri(), but in case of Ajax and other partial
|
||||
@@ -516,6 +537,15 @@ function form_get_cache($form_build_id, &$form_state) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generate a new #build_id if the cached form was rendered on a cacheable
|
||||
// page.
|
||||
if (!empty($form_state['build_info']['immutable'])) {
|
||||
$form['#build_id_old'] = $form['#build_id'];
|
||||
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||
$form['form_build_id']['#value'] = $form['#build_id'];
|
||||
$form['form_build_id']['#id'] = $form['#build_id'];
|
||||
unset($form_state['build_info']['immutable']);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
@@ -528,15 +558,28 @@ function form_set_cache($form_build_id, $form, $form_state) {
|
||||
// 6 hours cache life time for forms should be plenty.
|
||||
$expire = 21600;
|
||||
|
||||
// Ensure that the form build_id embedded in the form structure is the same as
|
||||
// the one passed in as a parameter. This is an additional safety measure to
|
||||
// prevent legacy code operating directly with form_get_cache and
|
||||
// form_set_cache from accidentally overwriting immutable form state.
|
||||
if ($form['#build_id'] != $form_build_id) {
|
||||
watchdog('form', 'Form build-id mismatch detected while attempting to store a form in the cache.', array(), WATCHDOG_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache form structure.
|
||||
if (isset($form)) {
|
||||
if ($GLOBALS['user']->uid) {
|
||||
$form['#cache_token'] = drupal_get_token();
|
||||
}
|
||||
unset($form['#build_id_old']);
|
||||
cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
|
||||
}
|
||||
|
||||
// Cache form state.
|
||||
if (variable_get('cache', 0) && drupal_page_is_cacheable()) {
|
||||
$form_state['build_info']['immutable'] = TRUE;
|
||||
}
|
||||
if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
|
||||
cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
|
||||
}
|
||||
@@ -727,8 +770,9 @@ function drupal_retrieve_form($form_id, &$form_state) {
|
||||
// Record the filepath of the include file containing the original form, so
|
||||
// the form builder callbacks can be loaded when the form is being rebuilt
|
||||
// from cache on a different path (such as 'system/ajax'). See
|
||||
// form_get_cache().
|
||||
// $menu_get_item() is not available during installation.
|
||||
// form_get_cache(). Don't do this in maintenance mode as Drupal may not be
|
||||
// fully bootstrapped (i.e. during installation) in which case
|
||||
// menu_get_item() is not available.
|
||||
if (!isset($form_state['build_info']['files']['menu']) && !defined('MAINTENANCE_MODE')) {
|
||||
$item = menu_get_item();
|
||||
if (!empty($item['include_file'])) {
|
||||
@@ -766,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.
|
||||
@@ -787,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;
|
||||
@@ -895,7 +939,7 @@ function drupal_process_form($form_id, &$form, &$form_state) {
|
||||
// after the batch is processed.
|
||||
}
|
||||
|
||||
// Set a flag to indicate the the form has been processed and executed.
|
||||
// Set a flag to indicate that the form has been processed and executed.
|
||||
$form_state['executed'] = TRUE;
|
||||
|
||||
// Redirect the form based on values in $form_state.
|
||||
@@ -976,7 +1020,7 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
|
||||
// @see drupal_build_form()
|
||||
// @see drupal_rebuild_form()
|
||||
if (!isset($form['#build_id'])) {
|
||||
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
|
||||
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||
}
|
||||
$form['form_build_id'] = array(
|
||||
'#type' => 'hidden',
|
||||
@@ -1085,6 +1129,17 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
|
||||
drupal_alter($hooks, $form, $form_state, $form_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to call form_set_error() if there is a token error.
|
||||
*/
|
||||
function _drupal_invalid_token_set_form_error() {
|
||||
$path = current_path();
|
||||
$query = drupal_get_query_parameters();
|
||||
$url = url($path, array('query' => $query));
|
||||
|
||||
// Setting this error will cause the form to fail validation.
|
||||
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates user-submitted form data in the $form_state array.
|
||||
@@ -1119,15 +1174,16 @@ 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.
|
||||
// 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 (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) {
|
||||
$path = current_path();
|
||||
$query = drupal_get_query_parameters();
|
||||
$url = url($path, array('query' => $query));
|
||||
|
||||
// Setting this error will cause the form to fail validation.
|
||||
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
|
||||
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
|
||||
// could invoke non-safe operations which opens the door for CSRF
|
||||
// vulnerabilities.
|
||||
$validated_forms[$form_id] = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1778,6 +1834,20 @@ function form_builder($form_id, &$element, &$form_state) {
|
||||
// from the POST data is set and matches the current form_id.
|
||||
if ($form_state['programmed'] || (!empty($form_state['input']) && (isset($form_state['input']['form_id']) && ($form_state['input']['form_id'] == $form_id)))) {
|
||||
$form_state['process_input'] = TRUE;
|
||||
// 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($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.
|
||||
_drupal_invalid_token_set_form_error();
|
||||
// This value is checked in _form_builder_handle_input_element().
|
||||
$form_state['invalid_token'] = TRUE;
|
||||
// Make sure file uploads do not get processed.
|
||||
$_FILES = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form_state['process_input'] = FALSE;
|
||||
@@ -1881,6 +1951,18 @@ function form_builder($form_id, &$element, &$form_state) {
|
||||
$element['#attributes']['enctype'] = 'multipart/form-data';
|
||||
}
|
||||
|
||||
// Allow Ajax submissions to the form action to bypass verification. This is
|
||||
// especially useful for multipart forms, which cannot be verified via a
|
||||
// response header.
|
||||
$element['#attached']['js'][] = array(
|
||||
'type' => 'setting',
|
||||
'data' => array(
|
||||
'urlIsAjaxTrusted' => array(
|
||||
$element['#action'] => TRUE,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// If a form contains a single textfield, and the ENTER key is pressed
|
||||
// within it, Internet Explorer submits the form with no POST data
|
||||
// identifying any submit button. Other browsers submit POST data as though
|
||||
@@ -1929,6 +2011,19 @@ function form_builder($form_id, &$element, &$form_state) {
|
||||
* Adds the #name and #value properties of an input element before rendering.
|
||||
*/
|
||||
function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
|
||||
static $safe_core_value_callbacks = array(
|
||||
'form_type_token_value',
|
||||
'form_type_textarea_value',
|
||||
'form_type_textfield_value',
|
||||
'form_type_checkbox_value',
|
||||
'form_type_checkboxes_value',
|
||||
'form_type_radios_value',
|
||||
'form_type_password_confirm_value',
|
||||
'form_type_select_value',
|
||||
'form_type_tableselect_value',
|
||||
'list_boolean_allowed_values_callback',
|
||||
);
|
||||
|
||||
if (!isset($element['#name'])) {
|
||||
$name = array_shift($element['#parents']);
|
||||
$element['#name'] = $name;
|
||||
@@ -1978,7 +2073,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
|
||||
// #access=FALSE on an element usually allow access for some users, so forms
|
||||
// submitted with drupal_form_submit() may bypass access restriction and be
|
||||
// treated as high-privilege users instead.
|
||||
$process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
|
||||
$process_input = empty($element['#disabled']) && (($form_state['programmed'] && $form_state['programmed_bypass_access_check']) || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
|
||||
|
||||
// Set the element's #value property.
|
||||
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
|
||||
@@ -2007,7 +2102,14 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
|
||||
// property, optionally filtered through $value_callback.
|
||||
if ($input_exists) {
|
||||
if (function_exists($value_callback)) {
|
||||
$element['#value'] = $value_callback($element, $input, $form_state);
|
||||
// Skip all value callbacks except safe ones like text if the CSRF
|
||||
// token was invalid.
|
||||
if (empty($form_state['invalid_token']) || in_array($value_callback, $safe_core_value_callbacks)) {
|
||||
$element['#value'] = $value_callback($element, $input, $form_state);
|
||||
}
|
||||
else {
|
||||
$input = NULL;
|
||||
}
|
||||
}
|
||||
if (!isset($element['#value']) && isset($input)) {
|
||||
$element['#value'] = $input;
|
||||
@@ -2402,6 +2504,17 @@ function form_type_password_confirm_value($element, $input = FALSE) {
|
||||
$element += array('#default_value' => array());
|
||||
return $element['#default_value'] + array('pass1' => '', 'pass2' => '');
|
||||
}
|
||||
$value = array('pass1' => '', 'pass2' => '');
|
||||
// Throw out all invalid array keys; we only allow pass1 and pass2.
|
||||
foreach ($value as $allowed_key => $default) {
|
||||
// These should be strings, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions. Any nested array values
|
||||
// are ignored.
|
||||
if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
|
||||
$value[$allowed_key] = (string) $input[$allowed_key];
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2445,6 +2558,27 @@ function form_type_select_value($element, $input = FALSE) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the value for a textarea form element.
|
||||
*
|
||||
* @param array $element
|
||||
* The form element whose value is being populated.
|
||||
* @param mixed $input
|
||||
* The incoming input to populate the form element. If this is FALSE,
|
||||
* the element's default value should be returned.
|
||||
*
|
||||
* @return string
|
||||
* The data that will appear in the $element_state['values'] collection
|
||||
* for this element. Return nothing to use the default.
|
||||
*/
|
||||
function form_type_textarea_value($element, $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 : '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the value for a textfield form element.
|
||||
*
|
||||
@@ -2460,9 +2594,12 @@ function form_type_select_value($element, $input = FALSE) {
|
||||
*/
|
||||
function form_type_textfield_value($element, $input = FALSE) {
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// Equate $input to the form value to ensure it's marked for
|
||||
// validation.
|
||||
return str_replace(array("\r", "\n"), '', $input);
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
if (!is_scalar($input)) {
|
||||
$input = '';
|
||||
}
|
||||
return str_replace(array("\r", "\n"), '', (string) $input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2578,8 +2715,8 @@ function _form_options_flatten($array) {
|
||||
* - #required: (optional) Whether the user needs to select an option (TRUE)
|
||||
* or not (FALSE). Defaults to FALSE.
|
||||
* - #empty_option: (optional) The label to show for the first default option.
|
||||
* By default, the label is automatically set to "- Please select -" for a
|
||||
* required field and "- None -" for an optional field.
|
||||
* By default, the label is automatically set to "- Select -" for a required
|
||||
* field and "- None -" for an optional field.
|
||||
* - #empty_value: (optional) The value for the first default option, which is
|
||||
* used to determine whether the user submitted a value or not.
|
||||
* - If #required is TRUE, this defaults to '' (an empty string).
|
||||
@@ -2650,17 +2787,43 @@ function theme_select($variables) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a select form element's options array into HTML.
|
||||
* Converts an array of options into HTML, for use in select list form elements.
|
||||
*
|
||||
* @param $element
|
||||
* An associative array containing the properties of the element.
|
||||
* @param $choices
|
||||
* Mixed: Either an associative array of items to list as choices, or an
|
||||
* object with an 'option' member that is an associative array. This
|
||||
* parameter is only used internally and should not be passed.
|
||||
* This function calls itself recursively to obtain the values for each optgroup
|
||||
* within the list of options and when the function encounters an object with
|
||||
* an 'options' property inside $element['#options'].
|
||||
*
|
||||
* @return
|
||||
* An HTML string of options for the select form element.
|
||||
* @param array $element
|
||||
* An associative array containing the following key-value pairs:
|
||||
* - #multiple: Optional Boolean indicating if the user may select more than
|
||||
* one item.
|
||||
* - #options: An associative array of options to render as HTML. Each array
|
||||
* value can be a string, an array, or an object with an 'option' property:
|
||||
* - A string or integer key whose value is a translated string is
|
||||
* interpreted as a single HTML option element. Do not use placeholders
|
||||
* that sanitize data: doing so will lead to double-escaping. Note that
|
||||
* the key will be visible in the HTML and could be modified by malicious
|
||||
* users, so don't put sensitive information in it.
|
||||
* - A translated string key whose value is an array indicates a group of
|
||||
* options. The translated string is used as the label attribute for the
|
||||
* optgroup. Do not use placeholders to sanitize data: doing so will lead
|
||||
* to double-escaping. The array should contain the options you wish to
|
||||
* group and should follow the syntax of $element['#options'].
|
||||
* - If the function encounters a string or integer key whose value is an
|
||||
* object with an 'option' property, the key is ignored, the contents of
|
||||
* the option property are interpreted as $element['#options'], and the
|
||||
* resulting HTML is added to the output.
|
||||
* - #value: Optional integer, string, or array representing which option(s)
|
||||
* to pre-select when the list is first displayed. The integer or string
|
||||
* must match the key of an option in the '#options' list. If '#multiple' is
|
||||
* TRUE, this can be an array of integers or strings.
|
||||
* @param array|null $choices
|
||||
* (optional) Either an associative array of options in the same format as
|
||||
* $element['#options'] above, or NULL. This parameter is only used internally
|
||||
* and is not intended to be passed in to the initial function call.
|
||||
*
|
||||
* @return string
|
||||
* An HTML string of options and optgroups for use in a select form element.
|
||||
*/
|
||||
function form_select_options($element, $choices = NULL) {
|
||||
if (!isset($choices)) {
|
||||
@@ -2673,7 +2836,7 @@ function form_select_options($element, $choices = NULL) {
|
||||
$options = '';
|
||||
foreach ($choices as $key => $choice) {
|
||||
if (is_array($choice)) {
|
||||
$options .= '<optgroup label="' . $key . '">';
|
||||
$options .= '<optgroup label="' . check_plain($key) . '">';
|
||||
$options .= form_select_options($element, $choice);
|
||||
$options .= '</optgroup>';
|
||||
}
|
||||
@@ -2866,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.'));
|
||||
}
|
||||
@@ -3051,8 +3214,7 @@ function form_process_radios($element) {
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - element: An associative array containing the properties of the element.
|
||||
* Properties used: #title, #value, #return_value, #description, #required,
|
||||
* #attributes, #checked.
|
||||
* Properties used: #id, #name, #attributes, #checked, #return_value.
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
@@ -3224,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:
|
||||
@@ -3237,6 +3402,8 @@ function form_process_container($element, &$form_state) {
|
||||
*/
|
||||
function theme_container($variables) {
|
||||
$element = $variables['element'];
|
||||
// Ensure #attributes is set.
|
||||
$element += array('#attributes' => array());
|
||||
|
||||
// Special handling for form elements.
|
||||
if (isset($element['#array_parents'])) {
|
||||
@@ -3379,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 {
|
||||
@@ -3799,6 +3967,34 @@ function theme_hidden($variables) {
|
||||
return '<input' . drupal_attributes($element['#attributes']) . " />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Process function to prepare autocomplete data.
|
||||
*
|
||||
* @param $element
|
||||
* A textfield or other element with a #autocomplete_path.
|
||||
*
|
||||
* @return array
|
||||
* The processed form element.
|
||||
*/
|
||||
function form_process_autocomplete($element) {
|
||||
$element['#autocomplete_input'] = array();
|
||||
if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
|
||||
$element['#autocomplete_input']['#id'] = $element['#id'] .'-autocomplete';
|
||||
// Force autocomplete to use non-clean URLs since this protects against the
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for a textfield form element.
|
||||
*
|
||||
@@ -3817,14 +4013,14 @@ function theme_textfield($variables) {
|
||||
_form_set_class($element, array('form-text'));
|
||||
|
||||
$extra = '';
|
||||
if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
|
||||
if ($element['#autocomplete_path'] && !empty($element['#autocomplete_input'])) {
|
||||
drupal_add_library('system', 'drupal.autocomplete');
|
||||
$element['#attributes']['class'][] = 'form-autocomplete';
|
||||
|
||||
$attributes = array();
|
||||
$attributes['type'] = 'hidden';
|
||||
$attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
|
||||
$attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
|
||||
$attributes['id'] = $element['#autocomplete_input']['#id'];
|
||||
$attributes['value'] = $element['#autocomplete_input']['#url_value'];
|
||||
$attributes['disabled'] = 'disabled';
|
||||
$attributes['class'][] = 'autocomplete';
|
||||
$extra = '<input' . drupal_attributes($attributes) . ' />';
|
||||
@@ -4244,7 +4440,7 @@ function element_validate_number($element, &$form_state) {
|
||||
* returns any user input in the 'results' or 'message' keys of $context,
|
||||
* it must also sanitize them first.
|
||||
*
|
||||
* Sample batch operations:
|
||||
* Sample callback_batch_operation():
|
||||
* @code
|
||||
* // Simple and artificial: load a node of a given type for a given user
|
||||
* function my_function_1($uid, $type, &$context) {
|
||||
@@ -4296,9 +4492,9 @@ function element_validate_number($element, &$form_state) {
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Sample 'finished' callback:
|
||||
* 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) {
|
||||
@@ -4335,12 +4531,14 @@ function element_validate_number($element, &$form_state) {
|
||||
* @param $batch_definition
|
||||
* An associative array defining the batch, with the following elements (all
|
||||
* are optional except as noted):
|
||||
* - operations: (required) Array of function calls to be performed.
|
||||
* - operations: (required) Array of operations to be performed, where each
|
||||
* item is an array consisting of the name of an implementation of
|
||||
* callback_batch_operation() and an array of parameter.
|
||||
* Example:
|
||||
* @code
|
||||
* array(
|
||||
* array('my_function_1', array($arg1)),
|
||||
* array('my_function_2', array($arg2_1, $arg2_2)),
|
||||
* array('callback_batch_operation_1', array($arg1)),
|
||||
* array('callback_batch_operation_2', array($arg2_1, $arg2_2)),
|
||||
* )
|
||||
* @endcode
|
||||
* - title: A safe, translated string to use as the title for the progress
|
||||
@@ -4352,10 +4550,10 @@ function element_validate_number($element, &$form_state) {
|
||||
* @elapsed. Defaults to t('Completed @current of @total.').
|
||||
* - error_message: Message displayed if an error occurred while processing
|
||||
* the batch. Defaults to t('An error has occurred.').
|
||||
* - finished: Name of a function to be executed after the batch has
|
||||
* completed. This should be used to perform any result massaging that may
|
||||
* be needed, and possibly save data in $_SESSION for display after final
|
||||
* page redirection.
|
||||
* - finished: Name of an implementation of callback_batch_finished(). This is
|
||||
* executed after the batch has completed. This should be used to perform
|
||||
* any result massaging that may be needed, and possibly save data in
|
||||
* $_SESSION for display after final page redirection.
|
||||
* - file: Path to the file containing the definitions of the 'operations' and
|
||||
* 'finished' functions, for instance if they don't reside in the main
|
||||
* .module file. The path should be relative to base_path(), and thus should
|
||||
|
||||
@@ -362,7 +362,8 @@ function install_run_tasks(&$install_state) {
|
||||
* Runs an individual installation task.
|
||||
*
|
||||
* @param $task
|
||||
* An array of information about the task to be run.
|
||||
* An array of information about the task to be run as returned by
|
||||
* hook_install_tasks().
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state. This is
|
||||
* passed in by reference so that it can be modified by the task.
|
||||
@@ -478,11 +479,15 @@ function install_run_task($task, &$install_state) {
|
||||
* the page request evolves (for example, if an installation profile hasn't
|
||||
* been selected yet, we don't yet know which profile tasks need to be run).
|
||||
*
|
||||
* You can override this using hook_install_tasks() or
|
||||
* hook_install_tasks_alter().
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @return
|
||||
* A list of tasks to be performed, with associated metadata.
|
||||
* A list of tasks to be performed, with associated metadata as returned by
|
||||
* hook_install_tasks().
|
||||
*/
|
||||
function install_tasks_to_perform($install_state) {
|
||||
// Start with a list of all currently available tasks.
|
||||
@@ -692,6 +697,21 @@ function install_full_redirect_url($install_state) {
|
||||
*/
|
||||
function install_display_output($output, $install_state) {
|
||||
drupal_page_header();
|
||||
|
||||
// Prevent install.php from being indexed when installed in a sub folder.
|
||||
// robots.txt rules are not read if the site is within domain.com/subfolder
|
||||
// resulting in /subfolder/install.php being found through search engines.
|
||||
// When settings.php is writeable this can be used via an external database
|
||||
// leading a malicious user to gain php access to the server.
|
||||
$noindex_meta_tag = array(
|
||||
'#tag' => 'meta',
|
||||
'#attributes' => array(
|
||||
'name' => 'robots',
|
||||
'content' => 'noindex, nofollow',
|
||||
),
|
||||
);
|
||||
drupal_add_html_head($noindex_meta_tag, 'install_meta_robots');
|
||||
|
||||
// Only show the task list if there is an active task; otherwise, the page
|
||||
// request has ended before tasks have even been started, so there is nothing
|
||||
// meaningful to show.
|
||||
@@ -766,6 +786,15 @@ function install_system_module(&$install_state) {
|
||||
// Install system.module.
|
||||
drupal_install_system();
|
||||
|
||||
// Call file_ensure_htaccess() to ensure that all of Drupal's standard
|
||||
// directories (e.g., the public and private files directories) have
|
||||
// appropriate .htaccess files. These directories will have already been
|
||||
// created by this point in the installer, since Drupal creates them during
|
||||
// the install_verify_requirements() task. Note that we cannot call
|
||||
// file_ensure_htaccess() any earlier than this, since it relies on
|
||||
// system.module in order to work.
|
||||
file_ensure_htaccess();
|
||||
|
||||
// Enable the user module so that sessions can be recorded during the
|
||||
// upcoming bootstrap step.
|
||||
module_enable(array('user'), FALSE);
|
||||
@@ -780,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -981,7 +1017,7 @@ function install_settings_form_submit($form, &$form_state) {
|
||||
'required' => TRUE,
|
||||
);
|
||||
$settings['drupal_hash_salt'] = array(
|
||||
'value' => drupal_hash_base64(drupal_random_bytes(55)),
|
||||
'value' => drupal_random_key(),
|
||||
'required' => TRUE,
|
||||
);
|
||||
drupal_rewrite_settings($settings);
|
||||
@@ -1561,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
|
||||
@@ -1574,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) {
|
||||
|
||||
@@ -420,7 +420,7 @@ abstract class DatabaseTasks {
|
||||
}
|
||||
}
|
||||
if (!empty($message)) {
|
||||
$message = '<p>In order for Drupal to work, and to continue with the installation process, you must resolve all issues reported below. For more help with configuring your database server, see the <a href="http://drupal.org/getting-started/install">installation handbook</a>. If you are unsure what any of this means you should probably contact your hosting provider.</p>' . $message;
|
||||
$message = 'Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="http://drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider.' . $message;
|
||||
throw new DatabaseTaskException($message);
|
||||
}
|
||||
}
|
||||
@@ -653,6 +653,13 @@ function drupal_rewrite_settings($settings = array(), $prefix = '') {
|
||||
if ($fp && fwrite($fp, $buffer) === FALSE) {
|
||||
throw new Exception(st('Failed to modify %settings. Verify the file permissions.', array('%settings' => $settings_file)));
|
||||
}
|
||||
else {
|
||||
// The existing settings.php file might have been included already. In
|
||||
// case an opcode cache is enabled, the rewritten contents of the file
|
||||
// will not be reflected in this process. Ensure to invalidate the file
|
||||
// in case an opcode cache is enabled.
|
||||
drupal_clear_opcode_cache(DRUPAL_ROOT . '/' . $settings_file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception(st('Failed to open %settings. Verify the file permissions.', array('%settings' => $default_settings)));
|
||||
@@ -741,20 +748,28 @@ function drupal_install_system() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls a given list of modules.
|
||||
* Uninstalls a given list of disabled modules.
|
||||
*
|
||||
* @param $module_list
|
||||
* The modules to uninstall.
|
||||
* @param $uninstall_dependents
|
||||
* If TRUE, the function will check that all modules which depend on the
|
||||
* passed-in module list either are already uninstalled or contained in the
|
||||
* list, and it will ensure that the modules are uninstalled 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.
|
||||
* @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.
|
||||
* @param bool $uninstall_dependents
|
||||
* (optional) If TRUE, the function will check that all modules which depend
|
||||
* on the passed-in module list either are already uninstalled or contained in
|
||||
* the list, and it will ensure that the modules are uninstalled 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.
|
||||
* Defaults to TRUE.
|
||||
*
|
||||
* @return
|
||||
* FALSE if one or more dependent modules are missing from the list, TRUE
|
||||
* otherwise.
|
||||
* @return bool
|
||||
* Returns TRUE if the operation succeeds or FALSE if it aborts due to an
|
||||
* unsafe condition, namely, $uninstall_dependents is TRUE and a module in
|
||||
* $module_list has dependents which are not already uninstalled and not also
|
||||
* included in $module_list).
|
||||
*
|
||||
* @see module_disable()
|
||||
* @see module_enable()
|
||||
*/
|
||||
function drupal_uninstall_modules($module_list = array(), $uninstall_dependents = TRUE) {
|
||||
if ($uninstall_dependents) {
|
||||
@@ -766,7 +781,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
$profile = drupal_get_profile();
|
||||
while (list($module) = each($module_list)) {
|
||||
if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {
|
||||
// This module doesn't exist or is already uninstalled, skip it.
|
||||
// This module doesn't exist or is already uninstalled. Skip it.
|
||||
unset($module_list[$module]);
|
||||
continue;
|
||||
}
|
||||
@@ -799,7 +814,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
}
|
||||
|
||||
if (!empty($module_list)) {
|
||||
// Call hook_module_uninstall to let other modules act
|
||||
// Let other modules react.
|
||||
module_invoke_all('modules_uninstalled', $module_list);
|
||||
}
|
||||
|
||||
@@ -1127,7 +1142,6 @@ function st($string, array $args = array(), array $options = array()) {
|
||||
}
|
||||
}
|
||||
|
||||
require_once DRUPAL_ROOT . '/includes/theme.inc';
|
||||
// Transform arguments before inserting them
|
||||
foreach ($args as $key => $value) {
|
||||
switch ($key[0]) {
|
||||
|
||||
@@ -53,6 +53,7 @@ function _country_get_predefined_list() {
|
||||
'BM' => $t('Bermuda'),
|
||||
'BN' => $t('Brunei'),
|
||||
'BO' => $t('Bolivia'),
|
||||
'BQ' => $t('Caribbean Netherlands'),
|
||||
'BR' => $t('Brazil'),
|
||||
'BS' => $t('Bahamas'),
|
||||
'BT' => $t('Bhutan'),
|
||||
@@ -74,8 +75,8 @@ function _country_get_predefined_list() {
|
||||
'CO' => $t('Colombia'),
|
||||
'CR' => $t('Costa Rica'),
|
||||
'CU' => $t('Cuba'),
|
||||
'CW' => $t('Curaçao'),
|
||||
'CV' => $t('Cape Verde'),
|
||||
'CW' => $t('Curaçao'),
|
||||
'CX' => $t('Christmas Island'),
|
||||
'CY' => $t('Cyprus'),
|
||||
'CZ' => $t('Czech Republic'),
|
||||
@@ -230,8 +231,10 @@ function _country_get_predefined_list() {
|
||||
'SN' => $t('Senegal'),
|
||||
'SO' => $t('Somalia'),
|
||||
'SR' => $t('Suriname'),
|
||||
'SS' => $t('South Sudan'),
|
||||
'ST' => $t('Sao Tome and Principe'),
|
||||
'SV' => $t('El Salvador'),
|
||||
'SX' => $t('Sint Maarten'),
|
||||
'SY' => $t('Syria'),
|
||||
'SZ' => $t('Swaziland'),
|
||||
'TC' => $t('Turks and Caicos Islands'),
|
||||
|
||||
@@ -78,7 +78,7 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||
* function mymodule_language_negotiation_info_alter(&$negotiation_info) {
|
||||
* // Replace the core function with our own function.
|
||||
* module_load_include('language', 'inc', 'language.negotiation');
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['negotiation'] = 'mymodule_from_url';
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['language'] = 'mymodule_from_url';
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
|
||||
* }
|
||||
*
|
||||
@@ -94,7 +94,6 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||
* }
|
||||
* return $langcode;
|
||||
* }
|
||||
* ?>
|
||||
* @endcode
|
||||
*
|
||||
* For more information, see
|
||||
@@ -298,7 +297,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
// Add support for WCAG 2.0's Language of Parts to add language identifiers.
|
||||
// http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html
|
||||
foreach ($result as $langcode => $link) {
|
||||
$result[$langcode]['attributes']['lang'] = $langcode;
|
||||
$result[$langcode]['attributes']['xml:lang'] = $langcode;
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
@@ -314,7 +313,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any unused language negotation providers from the configuration.
|
||||
* Removes any unused language negotiation providers from the configuration.
|
||||
*/
|
||||
function language_negotiation_purge() {
|
||||
// Ensure that we are getting the defined language negotiation information. An
|
||||
|
||||
@@ -398,7 +398,7 @@ function locale_language_switcher_session($type, $path) {
|
||||
$links[$langcode]['query'][$param] = $langcode;
|
||||
}
|
||||
else {
|
||||
$links[$langcode]['attributes']['class'][] = ' session-active';
|
||||
$links[$langcode]['attributes']['class'][] = 'session-active';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1931,7 +1970,7 @@ function _locale_translate_seek() {
|
||||
$groups[$string['group']],
|
||||
array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>'),
|
||||
$string['context'],
|
||||
array('data' => _locale_translate_language_list($string['languages'], $limit_language), 'align' => 'center'),
|
||||
array('data' => _locale_translate_language_list($string, $limit_language), 'align' => 'center'),
|
||||
array('data' => l(t('edit'), "admin/config/regional/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
||||
array('data' => l(t('delete'), "admin/config/regional/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
||||
);
|
||||
@@ -2126,16 +2165,21 @@ function _locale_rebuild_js($langcode = NULL) {
|
||||
/**
|
||||
* List languages in search result table
|
||||
*/
|
||||
function _locale_translate_language_list($translation, $limit_language) {
|
||||
function _locale_translate_language_list($string, $limit_language) {
|
||||
// Add CSS.
|
||||
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
|
||||
|
||||
// Include both translated and not yet translated target languages in the
|
||||
// list. The source language is English for built-in strings and the default
|
||||
// language for other strings.
|
||||
$languages = language_list();
|
||||
unset($languages['en']);
|
||||
$default = language_default();
|
||||
$omit = $string['group'] == 'default' ? 'en' : $default->language;
|
||||
unset($languages[$omit]);
|
||||
$output = '';
|
||||
foreach ($languages as $langcode => $language) {
|
||||
if (!$limit_language || $limit_language == $langcode) {
|
||||
$output .= (!empty($translation[$langcode])) ? $langcode . ' ' : "<em class=\"locale-untranslated\">$langcode</em> ";
|
||||
$output .= (!empty($string['languages'][$langcode])) ? $langcode . ' ' : "<em class=\"locale-untranslated\">$langcode</em> ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2301,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
|
||||
@@ -2319,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.
|
||||
*/
|
||||
@@ -2329,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.
|
||||
*/
|
||||
|
||||
@@ -92,7 +92,7 @@ function _lock_id() {
|
||||
* Acquire (or renew) a lock, but do not block if it fails.
|
||||
*
|
||||
* @param $name
|
||||
* The name of the lock.
|
||||
* The name of the lock. Limit of name's length is 255 characters.
|
||||
* @param $timeout
|
||||
* A number of seconds (float) before the lock expires (minimum of 0.001).
|
||||
*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* $conf['mail_line_endings'] will override this setting.
|
||||
*/
|
||||
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE ? "\r\n" : "\n");
|
||||
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE) ? "\r\n" : "\n");
|
||||
|
||||
/**
|
||||
* Composes and optionally sends an e-mail message.
|
||||
@@ -339,13 +339,13 @@ interface MailSystemInterface {
|
||||
*
|
||||
* We deliberately use LF rather than CRLF, see drupal_mail().
|
||||
*
|
||||
* @param $text
|
||||
* @param string $text
|
||||
* The plain text to process.
|
||||
* @param $indent (optional)
|
||||
* @param string $indent (optional)
|
||||
* A string to indent the text with. Only '>' characters are repeated on
|
||||
* subsequent wrapped lines. Others are replaced by spaces.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The content of the email as a string with formatting applied.
|
||||
*/
|
||||
function drupal_wrap_mail($text, $indent = '') {
|
||||
@@ -356,8 +356,9 @@ function drupal_wrap_mail($text, $indent = '') {
|
||||
$soft = strpos($clean_indent, ' ') === FALSE;
|
||||
// Check if the string has line breaks.
|
||||
if (strpos($text, "\n") !== FALSE) {
|
||||
// Remove trailing spaces to make existing breaks hard.
|
||||
$text = preg_replace('/ +\n/m', "\n", $text);
|
||||
// Remove trailing spaces to make existing breaks hard, but leave signature
|
||||
// marker untouched (RFC 3676, Section 4.3).
|
||||
$text = preg_replace('/(?(?<!^--) +\n| +\n)/m', "\n", $text);
|
||||
// Wrap each line at the needed width.
|
||||
$lines = explode("\n", $text);
|
||||
array_walk($lines, '_drupal_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
|
||||
@@ -563,9 +564,9 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
|
||||
*/
|
||||
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");
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -309,7 +317,7 @@ define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91');
|
||||
* actually exists. This list of 'masks' is built in menu_rebuild().
|
||||
*
|
||||
* @param $parts
|
||||
* An array of path parts, for the above example
|
||||
* An array of path parts; for the above example,
|
||||
* array('node', '12345', 'edit').
|
||||
*
|
||||
* @return
|
||||
@@ -430,8 +438,8 @@ function menu_set_item($path, $router_item) {
|
||||
* Gets a router item.
|
||||
*
|
||||
* @param $path
|
||||
* The path, for example node/5. The function will find the corresponding
|
||||
* node/% item and return that.
|
||||
* The path; for example, 'node/5'. The function will find the corresponding
|
||||
* node/% item and return that. Defaults to the current path.
|
||||
* @param $router_item
|
||||
* Internal use only.
|
||||
*
|
||||
@@ -456,7 +464,9 @@ function menu_get_item($path = NULL, $router_item = NULL) {
|
||||
// Rebuild if we know it's needed, or if the menu masks are missing which
|
||||
// occurs rarely, likely due to a race condition of multiple rebuilds.
|
||||
if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
|
||||
menu_rebuild();
|
||||
if (_menu_check_rebuild()) {
|
||||
menu_rebuild();
|
||||
}
|
||||
}
|
||||
$original_map = arg(NULL, $path);
|
||||
|
||||
@@ -542,7 +552,7 @@ function menu_execute_active_handler($path = NULL, $deliver = TRUE) {
|
||||
* @param $item
|
||||
* A menu router or menu link item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
*
|
||||
* @return
|
||||
* Returns TRUE for success, FALSE if an object cannot be loaded.
|
||||
@@ -612,7 +622,7 @@ function _menu_load_objects(&$item, &$map) {
|
||||
* @param $item
|
||||
* A menu router or menu link item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
*
|
||||
* @return
|
||||
* $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
|
||||
@@ -738,7 +748,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
|
||||
* @param $router_item
|
||||
* A menu router item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
* @param $to_arg
|
||||
* Execute $item['to_arg_functions'] or not. Use only if you want to render a
|
||||
* path from the menu table, for example tabs.
|
||||
@@ -801,9 +811,9 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
||||
* Translates the path elements in the map using any to_arg helper function.
|
||||
*
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
* @param $to_arg_functions
|
||||
* An array of helper function (ex: array(2 => 'menu_tail_to_arg'))
|
||||
* An array of helper functions; for example, array(2 => 'menu_tail_to_arg').
|
||||
*
|
||||
* @see hook_menu()
|
||||
*/
|
||||
@@ -1000,7 +1010,7 @@ function menu_tree($menu_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rendered menu tree.
|
||||
* Returns an output structure for rendering a menu tree.
|
||||
*
|
||||
* The menu item's LI element is given one of the following classes:
|
||||
* - expanded: The menu item is showing its submenu.
|
||||
@@ -1485,7 +1495,7 @@ function menu_tree_collect_node_links(&$tree, &$node_links) {
|
||||
* menu_tree_collect_node_links().
|
||||
*/
|
||||
function menu_tree_check_access(&$tree, $node_links = array()) {
|
||||
if ($node_links) {
|
||||
if ($node_links && (user_access('access content') || user_access('bypass node access'))) {
|
||||
$nids = array_keys($node_links);
|
||||
$select = db_select('node', 'n');
|
||||
$select->addField('n', 'nid');
|
||||
@@ -1926,13 +1936,21 @@ function menu_local_tasks($level = 0) {
|
||||
}
|
||||
|
||||
// Get all tabs (also known as local tasks) and the root page.
|
||||
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
||||
->fields('menu_router')
|
||||
->condition('tab_root', $router_item['tab_root'])
|
||||
->condition('context', MENU_CONTEXT_INLINE, '<>')
|
||||
->orderBy('weight')
|
||||
->orderBy('title')
|
||||
->execute();
|
||||
$cid = 'local_tasks:' . $router_item['tab_root'];
|
||||
if ($cache = cache_get($cid, 'cache_menu')) {
|
||||
$result = $cache->data;
|
||||
}
|
||||
else {
|
||||
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
||||
->fields('menu_router')
|
||||
->condition('tab_root', $router_item['tab_root'])
|
||||
->condition('context', MENU_CONTEXT_INLINE, '<>')
|
||||
->orderBy('weight')
|
||||
->orderBy('title')
|
||||
->execute()
|
||||
->fetchAll();
|
||||
cache_set($cid, $result, 'cache_menu');
|
||||
}
|
||||
$map = $router_item['original_map'];
|
||||
$children = array();
|
||||
$tasks = array();
|
||||
@@ -2139,7 +2157,7 @@ function menu_local_tasks($level = 0) {
|
||||
* example 'node' or 'admin/structure/block/manage'.
|
||||
* @param $args
|
||||
* A list of dynamic path arguments to append to $parent_path to form the
|
||||
* fully-qualified menu router path, for example array(123) for a certain
|
||||
* fully-qualified menu router path; for example, array(123) for a certain
|
||||
* node or array('system', 'navigation') for a certain block.
|
||||
*
|
||||
* @return
|
||||
@@ -2401,7 +2419,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) {
|
||||
@@ -2430,7 +2448,7 @@ function menu_set_active_trail($new_trail = NULL) {
|
||||
* Looks up the preferred menu link for a given system path.
|
||||
*
|
||||
* @param $path
|
||||
* The path, for example 'node/5'. The function will find the corresponding
|
||||
* The path; for example, 'node/5'. The function will find the corresponding
|
||||
* menu link ('node/5' if it exists, or fallback to 'node/%').
|
||||
* @param $selected_menu
|
||||
* The name of a menu used to restrict the search for a preferred menu link.
|
||||
@@ -2487,6 +2505,7 @@ function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
|
||||
$query->addField('ml', 'weight', 'link_weight');
|
||||
$query->fields('m');
|
||||
$query->condition('ml.link_path', $path_candidates, 'IN');
|
||||
$query->addTag('preferred_menu_links');
|
||||
|
||||
// Sort candidates by link path and menu name.
|
||||
$candidates = array();
|
||||
@@ -2602,10 +2621,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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2684,6 +2723,21 @@ function menu_reset_static_cache() {
|
||||
drupal_static_reset('menu_link_get_preferred');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a menu_rebuild() is necessary.
|
||||
*/
|
||||
function _menu_check_rebuild() {
|
||||
// To absolutely ensure that the menu rebuild is required, re-load the
|
||||
// variables in case they were set by another process.
|
||||
$variables = variable_initialize();
|
||||
if (empty($variables['menu_rebuild_needed']) && !empty($variables['menu_masks'])) {
|
||||
unset($GLOBALS['conf']['menu_rebuild_needed']);
|
||||
$GLOBALS['conf']['menu_masks'] = $variables['menu_masks'];
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the database tables used by various menu functions.
|
||||
*
|
||||
@@ -2704,6 +2758,14 @@ function menu_rebuild() {
|
||||
// We choose to block here since otherwise the router item may not
|
||||
// be available in menu_execute_active_handler() resulting in a 404.
|
||||
lock_wait('menu_rebuild');
|
||||
|
||||
if (_menu_check_rebuild()) {
|
||||
// If we get here and menu_masks was not set, then it is possible a menu
|
||||
// is being reloaded, or that the process rebuilding the menu was unable
|
||||
// to complete successfully. A missing menu_masks variable could result
|
||||
// in a 404, so re-run the function.
|
||||
return menu_rebuild();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2728,6 +2790,12 @@ function menu_rebuild() {
|
||||
$transaction->rollback();
|
||||
watchdog_exception('menu', $e);
|
||||
}
|
||||
// Explicitly commit the transaction now; this ensures that the database
|
||||
// operations during the menu rebuild are committed before the lock is made
|
||||
// available again, since locks may not always reside in the same database
|
||||
// connection. The lock is acquired outside of the transaction so should also
|
||||
// be released outside of it.
|
||||
unset($transaction);
|
||||
|
||||
lock_release('menu_rebuild');
|
||||
return TRUE;
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,11 +269,11 @@ function _module_build_dependencies($files) {
|
||||
/**
|
||||
* Determines whether a given module exists.
|
||||
*
|
||||
* @param $module
|
||||
* @param string $module
|
||||
* The name of the module (without the .module extension).
|
||||
*
|
||||
* @return
|
||||
* TRUE if the module is both installed and enabled.
|
||||
* @return bool
|
||||
* TRUE if the module is both installed and enabled, FALSE otherwise.
|
||||
*/
|
||||
function module_exists($module) {
|
||||
$list = module_list();
|
||||
@@ -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) {
|
||||
@@ -610,9 +630,40 @@ function module_disable($module_list, $disable_dependents = TRUE) {
|
||||
* just models that you can modify. Only the hooks implemented within modules
|
||||
* are executed when running Drupal.
|
||||
*
|
||||
* See also @link themeable the themeable group page. @endlink
|
||||
* @see themeable
|
||||
* @see callbacks
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup callbacks Callbacks
|
||||
* @{
|
||||
* Callback function signatures.
|
||||
*
|
||||
* Drupal's API sometimes uses callback functions to allow you to define how
|
||||
* some type of processing happens. A callback is a function with a defined
|
||||
* signature, which you define in a module. Then you pass the function name as
|
||||
* a parameter to a Drupal API function or return it as part of a hook
|
||||
* implementation return value, and your function is called at an appropriate
|
||||
* time. For instance, when setting up batch processing you might need to
|
||||
* provide a callback function for each processing step and/or a callback for
|
||||
* when processing is finished; you would do that by defining these functions
|
||||
* and passing their names into the batch setup function.
|
||||
*
|
||||
* Callback function signatures, like hook definitions, are described by
|
||||
* creating and documenting dummy functions in a *.api.php file; normally, the
|
||||
* dummy callback function's name should start with "callback_", and you should
|
||||
* document the parameters and return value and provide a sample function body.
|
||||
* Then your API documentation can refer to this callback function in its
|
||||
* documentation. A user of your API can usually name their callback function
|
||||
* anything they want, although a standard name would be to replace "callback_"
|
||||
* with the module name.
|
||||
*
|
||||
* @see hooks
|
||||
* @see themeable
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determines whether a module implements a hook.
|
||||
*
|
||||
@@ -645,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).
|
||||
@@ -665,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
|
||||
@@ -680,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) {
|
||||
@@ -696,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);
|
||||
@@ -713,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.
|
||||
@@ -738,6 +823,7 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
|
||||
$implementations['#write_cache'] = TRUE;
|
||||
}
|
||||
}
|
||||
$verified[$hook] = TRUE;
|
||||
}
|
||||
|
||||
return array_keys($implementations[$hook]);
|
||||
@@ -802,11 +888,13 @@ 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');
|
||||
// Check whether we need to write the cache. We do not want to cache hooks
|
||||
// which are only invoked on HTTP POST requests since these do not need to be
|
||||
// optimized as tightly, and not doing so keeps the cache entry smaller.
|
||||
if (isset($implementations['#write_cache']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD')) {
|
||||
if (isset($implementations['#write_cache'])) {
|
||||
unset($implementations['#write_cache']);
|
||||
cache_set('module_implements', $implementations, 'cache_bootstrap');
|
||||
}
|
||||
@@ -815,6 +903,9 @@ function module_implements_write_cache() {
|
||||
/**
|
||||
* Invokes a hook in a particular module.
|
||||
*
|
||||
* All arguments are passed by value. Use drupal_alter() if you need to pass
|
||||
* arguments by reference.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module (without the .module extension).
|
||||
* @param $hook
|
||||
@@ -824,6 +915,8 @@ function module_implements_write_cache() {
|
||||
*
|
||||
* @return
|
||||
* The return value of the hook implementation.
|
||||
*
|
||||
* @see drupal_alter()
|
||||
*/
|
||||
function module_invoke($module, $hook) {
|
||||
$args = func_get_args();
|
||||
@@ -837,6 +930,9 @@ function module_invoke($module, $hook) {
|
||||
/**
|
||||
* Invokes a hook in all enabled modules that implement it.
|
||||
*
|
||||
* All arguments are passed by value. Use drupal_alter() if you need to pass
|
||||
* arguments by reference.
|
||||
*
|
||||
* @param $hook
|
||||
* The name of the hook to invoke.
|
||||
* @param ...
|
||||
@@ -844,7 +940,11 @@ 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()
|
||||
*/
|
||||
function module_invoke_all($hook) {
|
||||
$args = func_get_args();
|
||||
|
||||
@@ -140,7 +140,7 @@ function _password_enforce_log2_boundaries($count_log2) {
|
||||
* @param $algo
|
||||
* The string name of a hashing algorithm usable by hash(), like 'sha256'.
|
||||
* @param $password
|
||||
* The plain-text password to hash.
|
||||
* Plain-text password up to 512 bytes (128 to 512 UTF-8 characters) to hash.
|
||||
* @param $setting
|
||||
* An existing hash or the output of _password_generate_salt(). Must be
|
||||
* at least 12 characters (the settings and salt).
|
||||
@@ -150,6 +150,10 @@ function _password_enforce_log2_boundaries($count_log2) {
|
||||
* The return string will be truncated at DRUPAL_HASH_LENGTH characters max.
|
||||
*/
|
||||
function _password_crypt($algo, $password, $setting) {
|
||||
// Prevent DoS attacks by refusing to hash large passwords.
|
||||
if (strlen($password) > 512) {
|
||||
return FALSE;
|
||||
}
|
||||
// The first 12 characters of an existing hash are its setting string.
|
||||
$setting = substr($setting, 0, 12);
|
||||
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
@@ -560,8 +561,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
|
||||
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
|
||||
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
|
||||
if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
|
||||
$item['link_path'] = $form_item['link_path'];
|
||||
$item['link_title'] = $form_item['link_title'];
|
||||
$item['link_path'] = $item['path'];
|
||||
$item['link_title'] = $item['title'];
|
||||
$item['external'] = FALSE;
|
||||
$item['options'] = '';
|
||||
_menu_link_translate($item);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @{
|
||||
* The code registry engine.
|
||||
*
|
||||
* Drupal maintains an internal registry of all functions or classes in the
|
||||
* Drupal maintains an internal registry of all interfaces or classes in the
|
||||
* system, allowing it to lazy-load code files as needed (reducing the amount
|
||||
* of code that must be parsed on each request).
|
||||
*/
|
||||
@@ -120,7 +120,10 @@ function registry_get_parsed_files() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all files that have changed since the registry was last built, and save their function and class listings.
|
||||
* Parse all changed files and save their interface and class listings.
|
||||
*
|
||||
* Parse all files that have changed since the registry was last built, and save
|
||||
* their interface and class listings.
|
||||
*
|
||||
* @param $files
|
||||
* The list of files to check and parse.
|
||||
@@ -149,7 +152,7 @@ function _registry_parse_files($files) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a file and save its function and class listings.
|
||||
* Parse a file and save its interface and class listings.
|
||||
*
|
||||
* @param $filename
|
||||
* Name of the file we are going to parse.
|
||||
@@ -161,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(
|
||||
|
||||
@@ -79,7 +79,7 @@ function _drupal_session_read($sid) {
|
||||
// Handle the case of first time visitors and clients that don't store
|
||||
// cookies (eg. web crawlers).
|
||||
$insecure_session_name = substr(session_name(), 1);
|
||||
if (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name])) {
|
||||
if (empty($sid) || (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name]))) {
|
||||
$user = drupal_anonymous_user();
|
||||
return '';
|
||||
}
|
||||
@@ -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.
|
||||
@@ -263,10 +263,10 @@ function drupal_session_initialize() {
|
||||
// Less random sessions (which are much faster to generate) are used for
|
||||
// anonymous users than are generated in drupal_session_regenerate() when
|
||||
// a user becomes authenticated.
|
||||
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
|
||||
session_id(drupal_random_key());
|
||||
if ($is_https && variable_get('https', FALSE)) {
|
||||
$insecure_session_name = substr(session_name(), 1);
|
||||
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE));
|
||||
$session_id = drupal_random_key();
|
||||
$_COOKIE[$insecure_session_name] = $session_id;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +360,7 @@ function drupal_session_regenerate() {
|
||||
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
|
||||
}
|
||||
$params = session_get_cookie_params();
|
||||
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
|
||||
$session_id = drupal_random_key();
|
||||
// If a session cookie lifetime is set, the session will expire
|
||||
// $params['lifetime'] seconds from the current request. If it is not set,
|
||||
// it will expire when the browser is closed.
|
||||
@@ -372,7 +372,7 @@ function drupal_session_regenerate() {
|
||||
if (drupal_session_started()) {
|
||||
$old_session_id = session_id();
|
||||
}
|
||||
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55)));
|
||||
session_id(drupal_random_key());
|
||||
|
||||
if (isset($old_session_id)) {
|
||||
$params = session_get_cookie_params();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -93,7 +93,7 @@ define('STREAM_WRAPPERS_LOCAL_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_N
|
||||
/**
|
||||
* Generic PHP stream wrapper interface.
|
||||
*
|
||||
* @see http://www.php.net/manual/en/class.streamwrapper.php
|
||||
* @see http://www.php.net/manual/class.streamwrapper.php
|
||||
*/
|
||||
interface StreamWrapperInterface {
|
||||
public function stream_open($uri, $mode, $options, &$opened_url);
|
||||
@@ -401,7 +401,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* Returns TRUE if file was opened successfully.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-open.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-open.php
|
||||
*/
|
||||
public function stream_open($uri, $mode, $options, &$opened_path) {
|
||||
$this->uri = $uri;
|
||||
@@ -429,7 +429,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* Always returns TRUE at the present time.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-lock.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-lock.php
|
||||
*/
|
||||
public function stream_lock($operation) {
|
||||
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
|
||||
@@ -448,7 +448,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* The string that was read, or FALSE in case of an error.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-read.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-read.php
|
||||
*/
|
||||
public function stream_read($count) {
|
||||
return fread($this->handle, $count);
|
||||
@@ -463,7 +463,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* The number of bytes written (integer).
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-write.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-write.php
|
||||
*/
|
||||
public function stream_write($data) {
|
||||
return fwrite($this->handle, $data);
|
||||
@@ -475,7 +475,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if end-of-file has been reached.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-eof.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-eof.php
|
||||
*/
|
||||
public function stream_eof() {
|
||||
return feof($this->handle);
|
||||
@@ -492,7 +492,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE on success.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-seek.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-seek.php
|
||||
*/
|
||||
public function stream_seek($offset, $whence) {
|
||||
// fseek returns 0 on success and -1 on a failure.
|
||||
@@ -506,7 +506,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if data was successfully stored (or there was no data to store).
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-flush.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-flush.php
|
||||
*/
|
||||
public function stream_flush() {
|
||||
return fflush($this->handle);
|
||||
@@ -518,7 +518,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* The current offset in bytes from the beginning of file.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-tell.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-tell.php
|
||||
*/
|
||||
public function stream_tell() {
|
||||
return ftell($this->handle);
|
||||
@@ -531,7 +531,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* An array with file status, or FALSE in case of an error - see fstat()
|
||||
* for a description of this array.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-stat.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-stat.php
|
||||
*/
|
||||
public function stream_stat() {
|
||||
return fstat($this->handle);
|
||||
@@ -543,7 +543,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if stream was successfully closed.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-close.php
|
||||
* @see http://php.net/manual/streamwrapper.stream-close.php
|
||||
*/
|
||||
public function stream_close() {
|
||||
return fclose($this->handle);
|
||||
@@ -558,7 +558,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if resource was successfully deleted.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.unlink.php
|
||||
* @see http://php.net/manual/streamwrapper.unlink.php
|
||||
*/
|
||||
public function unlink($uri) {
|
||||
$this->uri = $uri;
|
||||
@@ -576,7 +576,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if file was successfully renamed.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.rename.php
|
||||
* @see http://php.net/manual/streamwrapper.rename.php
|
||||
*/
|
||||
public function rename($from_uri, $to_uri) {
|
||||
return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
|
||||
@@ -622,7 +622,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if directory was successfully created.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.mkdir.php
|
||||
* @see http://php.net/manual/streamwrapper.mkdir.php
|
||||
*/
|
||||
public function mkdir($uri, $mode, $options) {
|
||||
$this->uri = $uri;
|
||||
@@ -654,7 +654,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE if directory was successfully removed.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.rmdir.php
|
||||
* @see http://php.net/manual/streamwrapper.rmdir.php
|
||||
*/
|
||||
public function rmdir($uri, $options) {
|
||||
$this->uri = $uri;
|
||||
@@ -678,7 +678,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* An array with file status, or FALSE in case of an error - see fstat()
|
||||
* for a description of this array.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.url-stat.php
|
||||
* @see http://php.net/manual/streamwrapper.url-stat.php
|
||||
*/
|
||||
public function url_stat($uri, $flags) {
|
||||
$this->uri = $uri;
|
||||
@@ -704,7 +704,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE on success.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.dir-opendir.php
|
||||
* @see http://php.net/manual/streamwrapper.dir-opendir.php
|
||||
*/
|
||||
public function dir_opendir($uri, $options) {
|
||||
$this->uri = $uri;
|
||||
@@ -719,7 +719,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* The next filename, or FALSE if there are no more files in the directory.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.dir-readdir.php
|
||||
* @see http://php.net/manual/streamwrapper.dir-readdir.php
|
||||
*/
|
||||
public function dir_readdir() {
|
||||
return readdir($this->handle);
|
||||
@@ -731,7 +731,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE on success.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php
|
||||
* @see http://php.net/manual/streamwrapper.dir-rewinddir.php
|
||||
*/
|
||||
public function dir_rewinddir() {
|
||||
rewinddir($this->handle);
|
||||
@@ -747,7 +747,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* TRUE on success.
|
||||
*
|
||||
* @see http://php.net/manual/en/streamwrapper.dir-closedir.php
|
||||
* @see http://php.net/manual/streamwrapper.dir-closedir.php
|
||||
*/
|
||||
public function dir_closedir() {
|
||||
closedir($this->handle);
|
||||
@@ -788,8 +788,6 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
*
|
||||
* Provides support for storing privately accessible files with the Drupal file
|
||||
* interface.
|
||||
*
|
||||
* Extends DrupalPublicStreamWrapper.
|
||||
*/
|
||||
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
/**
|
||||
|
||||
@@ -46,10 +46,9 @@ class TableSort extends SelectQueryExtender {
|
||||
// Based on code from db_escape_table(), but this can also contain a dot.
|
||||
$field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']);
|
||||
|
||||
// Sort order can only be ASC or DESC.
|
||||
$sort = drupal_strtoupper($ts['sort']);
|
||||
$sort = in_array($sort, array('ASC', 'DESC')) ? $sort : '';
|
||||
$this->orderBy($field, $sort);
|
||||
// orderBy() will ensure that only ASC/DESC values are accepted, so we
|
||||
// don't need to sanitize that here.
|
||||
$this->orderBy($field, $ts['sort']);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ class ThemeRegistry Extends DrupalCacheArray {
|
||||
* themes/bartik.
|
||||
*
|
||||
* @see theme()
|
||||
* @see _theme_process_registry()
|
||||
* @see _theme_build_registry()
|
||||
* @see hook_theme()
|
||||
* @see list_themes()
|
||||
*/
|
||||
@@ -869,11 +869,18 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
/**
|
||||
* Generates themed output.
|
||||
*
|
||||
* All requests for themed output must go through this function. It examines
|
||||
* the request and routes it to the appropriate
|
||||
* All requests for themed output must go through this function (however,
|
||||
* calling the theme() function directly is strongly discouraged - see next
|
||||
* paragraph). It examines the request and routes it to the appropriate
|
||||
* @link themeable theme function or template @endlink, by checking the theme
|
||||
* registry.
|
||||
*
|
||||
* Avoid calling this function directly. It is preferable to replace direct
|
||||
* calls to the theme() function with calls to drupal_render() by passing a
|
||||
* render array with a #theme key to drupal_render(), which in turn calls
|
||||
* theme().
|
||||
*
|
||||
* @section sec_theme_hooks Theme Hooks
|
||||
* Most commonly, the first argument to this function is the name of the theme
|
||||
* hook. For instance, to theme a taxonomy term, the theme hook name is
|
||||
* 'taxonomy_term'. Modules register theme hooks within a hook_theme()
|
||||
@@ -885,6 +892,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* underscores changed to hyphens, so for the 'taxonomy_term' theme hook, the
|
||||
* default template is 'taxonomy-term.tpl.php'.
|
||||
*
|
||||
* @subsection sub_overriding_theme_hooks Overriding Theme Hooks
|
||||
* Themes may also register new theme hooks within a hook_theme()
|
||||
* implementation, but it is more common for themes to override default
|
||||
* implementations provided by modules than to register entirely new theme
|
||||
@@ -897,6 +905,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* rendering engine, it overrides the default implementation of the 'page' theme
|
||||
* hook by containing a 'page.tpl.php' file within its folder structure).
|
||||
*
|
||||
* @subsection sub_preprocess_templates Preprocessing for Template Files
|
||||
* If the implementation is a template file, several functions are called
|
||||
* before the template file is invoked, to modify the $variables array. These
|
||||
* fall into the "preprocessing" phase and the "processing" phase, and are
|
||||
@@ -945,12 +954,14 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* - THEME_process_HOOK(&$variables): Allows the theme to process the
|
||||
* variables specific to the theme hook.
|
||||
*
|
||||
* @subsection sub_preprocess_theme_funcs Preprocessing for Theme Functions
|
||||
* If the implementation is a function, only the theme-hook-specific preprocess
|
||||
* and process functions (the ones ending in _HOOK) are called from the
|
||||
* list above. This is because theme hooks with function implementations
|
||||
* need to be fast, and calling the non-theme-hook-specific preprocess and
|
||||
* process functions for them would incur a noticeable performance penalty.
|
||||
*
|
||||
* @subsection sub_alternate_suggestions Suggesting Alternate Hooks
|
||||
* There are two special variables that these preprocess and process functions
|
||||
* can set: 'theme_hook_suggestion' and 'theme_hook_suggestions'. These will be
|
||||
* merged together to form a list of 'suggested' alternate theme hooks to use,
|
||||
@@ -992,6 +1003,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* @return
|
||||
* An HTML string representing the themed output.
|
||||
*
|
||||
* @see drupal_render()
|
||||
* @see themeable
|
||||
* @see hook_theme()
|
||||
* @see template_preprocess()
|
||||
@@ -1017,6 +1029,7 @@ function theme($hook, $variables = array()) {
|
||||
}
|
||||
$hook = $candidate;
|
||||
}
|
||||
$theme_hook_original = $hook;
|
||||
|
||||
// If there's no implementation, check for more generic fallbacks. If there's
|
||||
// still no implementation, log an error and return an empty string.
|
||||
@@ -1078,6 +1091,8 @@ function theme($hook, $variables = array()) {
|
||||
$variables += array($info['render element'] => array());
|
||||
}
|
||||
|
||||
$variables['theme_hook_original'] = $theme_hook_original;
|
||||
|
||||
// Invoke the variable processors, if any. The processors may specify
|
||||
// alternate suggestions for which hook's template/function to use. If the
|
||||
// hook is a suggestion of a base hook, invoke the variable processors of
|
||||
@@ -1186,7 +1201,12 @@ function theme($hook, $variables = array()) {
|
||||
if (isset($info['path'])) {
|
||||
$template_file = $info['path'] . '/' . $template_file;
|
||||
}
|
||||
$output = $render_function($template_file, $variables);
|
||||
if (variable_get('theme_debug', FALSE)) {
|
||||
$output = _theme_render_template_debug($render_function, $template_file, $variables, $extension);
|
||||
}
|
||||
else {
|
||||
$output = $render_function($template_file, $variables);
|
||||
}
|
||||
}
|
||||
|
||||
// restore path_to_theme()
|
||||
@@ -1228,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) {
|
||||
@@ -1244,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);
|
||||
@@ -1508,6 +1529,72 @@ function theme_render_template($template_file, $variables) {
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a template for any engine.
|
||||
*
|
||||
* Includes the possibility to get debug output by setting the
|
||||
* theme_debug variable to TRUE.
|
||||
*
|
||||
* @param string $template_function
|
||||
* The function to call for rendering the template.
|
||||
* @param string $template_file
|
||||
* The filename of the template to render.
|
||||
* @param array $variables
|
||||
* A keyed array of variables that will appear in the output.
|
||||
* @param string $extension
|
||||
* The extension used by the theme engine for template files.
|
||||
*
|
||||
* @return string
|
||||
* The output generated by the template including debug information.
|
||||
*/
|
||||
function _theme_render_template_debug($template_function, $template_file, $variables, $extension) {
|
||||
$output = array(
|
||||
'debug_prefix' => '',
|
||||
'debug_info' => '',
|
||||
'rendered_markup' => call_user_func($template_function, $template_file, $variables),
|
||||
'debug_suffix' => '',
|
||||
);
|
||||
$output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
|
||||
$output['debug_prefix'] .= "\n<!-- CALL: theme('" . check_plain($variables['theme_hook_original']) . "') -->";
|
||||
// If there are theme suggestions, reverse the array so more specific
|
||||
// suggestions are shown first.
|
||||
if (!empty($variables['theme_hook_suggestions'])) {
|
||||
$variables['theme_hook_suggestions'] = array_reverse($variables['theme_hook_suggestions']);
|
||||
}
|
||||
// Add debug output for directly called suggestions like
|
||||
// '#theme' => 'comment__node__article'.
|
||||
if (strpos($variables['theme_hook_original'], '__') !== FALSE) {
|
||||
$derived_suggestions[] = $hook = $variables['theme_hook_original'];
|
||||
while ($pos = strrpos($hook, '__')) {
|
||||
$hook = substr($hook, 0, $pos);
|
||||
$derived_suggestions[] = $hook;
|
||||
}
|
||||
// Get the value of the base hook (last derived suggestion) and append it
|
||||
// to the end of all theme suggestions.
|
||||
$base_hook = array_pop($derived_suggestions);
|
||||
$variables['theme_hook_suggestions'] = array_merge($derived_suggestions, $variables['theme_hook_suggestions']);
|
||||
$variables['theme_hook_suggestions'][] = $base_hook;
|
||||
}
|
||||
if (!empty($variables['theme_hook_suggestions'])) {
|
||||
$current_template = basename($template_file);
|
||||
$suggestions = $variables['theme_hook_suggestions'];
|
||||
// Only add the original theme hook if it wasn't a directly called
|
||||
// suggestion.
|
||||
if (strpos($variables['theme_hook_original'], '__') === FALSE) {
|
||||
$suggestions[] = $variables['theme_hook_original'];
|
||||
}
|
||||
foreach ($suggestions as &$suggestion) {
|
||||
$template = strtr($suggestion, '_', '-') . $extension;
|
||||
$prefix = ($template == $current_template) ? 'x' : '*';
|
||||
$suggestion = $prefix . ' ' . $template;
|
||||
}
|
||||
$output['debug_info'] .= "\n<!-- FILE NAME SUGGESTIONS:\n " . check_plain(implode("\n ", $suggestions)) . "\n-->";
|
||||
}
|
||||
$output['debug_info'] .= "\n<!-- BEGIN OUTPUT from '" . check_plain($template_file) . "' -->\n";
|
||||
$output['debug_suffix'] .= "\n<!-- END OUTPUT from '" . check_plain($template_file) . "' -->\n\n";
|
||||
return implode('', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a given list of themes.
|
||||
*
|
||||
@@ -1605,7 +1692,7 @@ function theme_status_messages($variables) {
|
||||
$output .= " </ul>\n";
|
||||
}
|
||||
else {
|
||||
$output .= $messages[0];
|
||||
$output .= reset($messages);
|
||||
}
|
||||
$output .= "</div>\n";
|
||||
}
|
||||
@@ -1624,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>';
|
||||
@@ -1678,8 +1783,6 @@ function theme_links($variables) {
|
||||
$output = '';
|
||||
|
||||
if (count($links) > 0) {
|
||||
$output = '';
|
||||
|
||||
// Treat the heading first if it is present to prepend it to the
|
||||
// list of links.
|
||||
if (!empty($heading)) {
|
||||
@@ -1707,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';
|
||||
}
|
||||
@@ -1725,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']);
|
||||
}
|
||||
@@ -1814,7 +1919,9 @@ function theme_breadcrumb($variables) {
|
||||
* - "data": The localized title of the table column.
|
||||
* - "field": The database field represented in the table column (required
|
||||
* if user is to be able to sort on this column).
|
||||
* - "sort": A default sort order for this column ("asc" or "desc").
|
||||
* - "sort": A default sort order for this column ("asc" or "desc"). Only
|
||||
* one column should be given a default sort order because table sorting
|
||||
* only applies to one column at a time.
|
||||
* - Any HTML attributes, such as "colspan", to apply to the column header
|
||||
* cell.
|
||||
* - rows: An array of table rows. Every row is an array of cells, or an
|
||||
@@ -1973,25 +2080,24 @@ function theme_table($variables) {
|
||||
$flip = array('even' => 'odd', 'odd' => 'even');
|
||||
$class = 'even';
|
||||
foreach ($rows as $number => $row) {
|
||||
$attributes = array();
|
||||
|
||||
// Check if we're dealing with a simple or complex row
|
||||
if (isset($row['data'])) {
|
||||
foreach ($row as $key => $value) {
|
||||
if ($key == 'data') {
|
||||
$cells = $value;
|
||||
}
|
||||
else {
|
||||
$attributes[$key] = $value;
|
||||
}
|
||||
}
|
||||
$cells = $row['data'];
|
||||
$no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
|
||||
|
||||
// Set the attributes array and exclude 'data' and 'no_striping'.
|
||||
$attributes = $row;
|
||||
unset($attributes['data']);
|
||||
unset($attributes['no_striping']);
|
||||
}
|
||||
else {
|
||||
$cells = $row;
|
||||
$attributes = array();
|
||||
$no_striping = FALSE;
|
||||
}
|
||||
if (count($cells)) {
|
||||
// Add odd/even class
|
||||
if (empty($row['no_striping'])) {
|
||||
if (!$no_striping) {
|
||||
$class = $flip[$class];
|
||||
$attributes['class'][] = $class;
|
||||
}
|
||||
@@ -2533,10 +2639,13 @@ 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();
|
||||
}
|
||||
if ($region_content = drupal_get_region_content($region_key)) {
|
||||
$variables['page'][$region_key][]['#markup'] = $region_content;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up layout variable.
|
||||
|
||||
@@ -116,11 +116,15 @@ function _unicode_check() {
|
||||
if (ini_get('mbstring.encoding_translation') != 0) {
|
||||
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||
}
|
||||
if (ini_get('mbstring.http_input') != 'pass') {
|
||||
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||
}
|
||||
if (ini_get('mbstring.http_output') != 'pass') {
|
||||
return array(UNICODE_ERROR, $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||
// mbstring.http_input and mbstring.http_output are deprecated and empty by
|
||||
// default in PHP 5.6.
|
||||
if (version_compare(PHP_VERSION, '5.6.0') == -1) {
|
||||
if (ini_get('mbstring.http_input') != 'pass') {
|
||||
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||
}
|
||||
if (ini_get('mbstring.http_output') != 'pass') {
|
||||
return array(UNICODE_ERROR, $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||
}
|
||||
}
|
||||
|
||||
// Set appropriate configuration
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -178,7 +178,41 @@ function xmlrpc_message_parse($xmlrpc_message) {
|
||||
xml_set_element_handler($xmlrpc_message->_parser, 'xmlrpc_message_tag_open', 'xmlrpc_message_tag_close');
|
||||
xml_set_character_data_handler($xmlrpc_message->_parser, 'xmlrpc_message_cdata');
|
||||
xmlrpc_message_set($xmlrpc_message);
|
||||
if (!xml_parse($xmlrpc_message->_parser, $xmlrpc_message->message)) {
|
||||
|
||||
// Strip XML declaration.
|
||||
$header = preg_replace('/<\?xml.*?\?'.'>/s', '', substr($xmlrpc_message->message, 0, 100), 1);
|
||||
$xml = trim(substr_replace($xmlrpc_message->message, $header, 0, 100));
|
||||
if ($xml == '') {
|
||||
return FALSE;
|
||||
}
|
||||
// Strip DTD.
|
||||
$header = preg_replace('/^<!DOCTYPE[^>]*+>/i', '', substr($xml, 0, 200), 1);
|
||||
$xml = trim(substr_replace($xml, $header, 0, 200));
|
||||
if ($xml == '') {
|
||||
return FALSE;
|
||||
}
|
||||
// Confirm the XML now starts with a valid root tag. A root tag can end in [> \t\r\n]
|
||||
$root_tag = substr($xml, 0, strcspn(substr($xml, 0, 20), "> \t\r\n"));
|
||||
// Reject a second DTD.
|
||||
if (strtoupper($root_tag) == '<!DOCTYPE') {
|
||||
return FALSE;
|
||||
}
|
||||
if (!in_array($root_tag, array('<methodCall', '<methodResponse', '<fault'))) {
|
||||
return FALSE;
|
||||
}
|
||||
// Skip parsing if there is an unreasonably large number of tags.
|
||||
try {
|
||||
$dom = new DOMDocument();
|
||||
@$dom->loadXML($xml);
|
||||
if ($dom->getElementsByTagName('*')->length > variable_get('xmlrpc_message_maximum_tag_count', 30000)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!xml_parse($xmlrpc_message->_parser, $xml)) {
|
||||
return FALSE;
|
||||
}
|
||||
xml_parser_free($xmlrpc_message->_parser);
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
* Invokes XML-RPC methods on this server.
|
||||
*
|
||||
* @param array $callbacks
|
||||
* Array of external XML-RPC method names with the callbacks they map to.
|
||||
* Either an associative array of external XML-RPC method names as keys with
|
||||
* the callbacks they map to as values, or a more complex structure
|
||||
* describing XML-RPC callbacks as returned from hook_xmlrpc().
|
||||
*/
|
||||
function xmlrpc_server($callbacks) {
|
||||
$xmlrpc_server = new stdClass();
|
||||
@@ -262,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) {
|
||||
@@ -271,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);
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?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();
|
||||
@@ -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);
|
||||
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
||||
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||
<!-- Consider adding an manifest.appcache: h5bp.com/d/Offline -->
|
||||
<!--[if gt IE 8]><!-->
|
||||
<html class="js no-flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" dir="ltr" lang="en"><!--<![endif]-->
|
||||
<head>
|
||||
|
||||
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
|
||||
Remove this if you use the .htaccess -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
|
||||
<link type="image/png" rel="shortcut icon" href="http://www.materio.com/sites/all/themes/gui/materiobasetheme/materio-icon-O.png">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="alternate" type="application/rss+xml" title="Materio's news" href="http://www.materio.com/en/rss/feed">
|
||||
|
||||
<title>Site under maintenance | materiO’</title>
|
||||
<style type="text/css" media="all">
|
||||
@import url("http://www.materio.com/modules/system/system.base.css?mu8p7n");
|
||||
@import url("http://www.materio.com/modules/system/system.menus.css?mu8p7n");
|
||||
@import url("http://www.materio.com/modules/system/system.theme.css?mu8p7n");
|
||||
</style>
|
||||
<style type="text/css" media="all">
|
||||
@import url("http://www.materio.com/sites/all/modules/contrib/mail/simplenews/simplenews.css?mu8p7n");
|
||||
@import url("http://www.materio.com/modules/field/theme/field.css?mu8p7n");
|
||||
@import url("http://www.materio.com/modules/node/node.css?mu8p7n");
|
||||
</style>
|
||||
<style type="text/css" media="all">
|
||||
@import url("http://www.materio.com/sites/all/modules/contrib/theming/extlink/extlink.css?mu8p7n");
|
||||
</style>
|
||||
<style type="text/css" media="all">
|
||||
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/normalize.css?mu8p7n");
|
||||
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/fonts/ubuntu/ubuntu.css?mu8p7n");
|
||||
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/styles.css?mu8p7n");
|
||||
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/nonsemantic.css?mu8p7n");
|
||||
</style>
|
||||
|
||||
|
||||
<!-- All JavaScript at the bottom, except for Modernizr / Respond.
|
||||
|
||||
|
||||
<!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
||||
</head>
|
||||
|
||||
<body class="maintenance-page in-maintenance no-sidebars">
|
||||
<div id="root">
|
||||
|
||||
<div id="container">
|
||||
|
||||
<header id="header">
|
||||
<h1 class="site-name">materiO’</h1>
|
||||
<h2 class="site-slogan">l'inspiration par la matière </h2>
|
||||
</header>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<section id="center">
|
||||
|
||||
<section id="content">
|
||||
<div class="inner-content">
|
||||
<h3 class="page-title">Site under maintenance</h3> <p>materiO' is currently working hard to make a better service for you !<br>We should be back shortly.<br>Thank you for your patience.</p>
|
||||
<img src="index_files/maintenance.jpg">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</section> <!-- /center -->
|
||||
|
||||
</div><!-- /main -->
|
||||
|
||||
<div id="footer"></div>
|
||||
|
||||
</div>
|
||||
<!-- /container -->
|
||||
|
||||
</div>
|
||||
<!-- /root -->
|
||||
|
||||
|
||||
<div style="display: none;" id="cboxOverlay"></div><div style="display: none;" tabindex="-1" role="dialog" class="" id="colorbox"><div id="cboxWrapper"><div><div style="float: left;" id="cboxTopLeft"></div><div style="float: left;" id="cboxTopCenter"></div><div style="float: left;" id="cboxTopRight"></div></div><div style="clear: left;"><div style="float: left;" id="cboxMiddleLeft"></div><div style="float: left;" id="cboxContent"><div style="float: left;" id="cboxTitle"></div><div style="float: left;" id="cboxCurrent"></div><button id="cboxPrevious" type="button"></button><button id="cboxNext" type="button"></button><button id="cboxSlideshow"></button><div style="float: left;" id="cboxLoadingOverlay"></div><div style="float: left;" id="cboxLoadingGraphic"></div><button id="cboxClose" type="button"></button></div><div style="float: left;" id="cboxMiddleRight"></div></div><div style="clear: left;"><div style="float: left;" id="cboxBottomLeft"></div><div style="float: left;" id="cboxBottomCenter"></div><div style="float: left;" id="cboxBottomRight"></div></div></div><div style="position: absolute; width: 9999px; visibility: hidden; display: none;"></div></div></body></html>
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -14,6 +14,8 @@
|
||||
|
||||
Drupal.ajax = Drupal.ajax || {};
|
||||
|
||||
Drupal.settings.urlIsAjaxTrusted = Drupal.settings.urlIsAjaxTrusted || {};
|
||||
|
||||
/**
|
||||
* Attaches the Ajax behavior to each Ajax form element.
|
||||
*/
|
||||
@@ -130,6 +132,11 @@ Drupal.ajax = function (base, element, element_settings) {
|
||||
// 5. /nojs# - Followed by a fragment.
|
||||
// E.g.: path/nojs#myfragment
|
||||
this.url = element_settings.url.replace(/\/nojs(\/|$|\?|&|#)/g, '/ajax$1');
|
||||
// If the 'nojs' version of the URL is trusted, also trust the 'ajax' version.
|
||||
if (Drupal.settings.urlIsAjaxTrusted[element_settings.url]) {
|
||||
Drupal.settings.urlIsAjaxTrusted[this.url] = true;
|
||||
}
|
||||
|
||||
this.wrapper = '#' + element_settings.wrapper;
|
||||
|
||||
// If there isn't a form, jQuery.ajax() will be used instead, allowing us to
|
||||
@@ -155,18 +162,36 @@ Drupal.ajax = function (base, element, element_settings) {
|
||||
ajax.ajaxing = true;
|
||||
return ajax.beforeSend(xmlhttprequest, options);
|
||||
},
|
||||
success: function (response, status) {
|
||||
success: function (response, status, xmlhttprequest) {
|
||||
// Sanity check for browser support (object expected).
|
||||
// When using iFrame uploads, responses must be returned as a string.
|
||||
if (typeof response == 'string') {
|
||||
response = $.parseJSON(response);
|
||||
}
|
||||
|
||||
// Prior to invoking the response's commands, verify that they can be
|
||||
// trusted by checking for a response header. See
|
||||
// ajax_set_verification_header() for details.
|
||||
// - Empty responses are harmless so can bypass verification. This avoids
|
||||
// an alert message for server-generated no-op responses that skip Ajax
|
||||
// rendering.
|
||||
// - Ajax objects with trusted URLs (e.g., ones defined server-side via
|
||||
// #ajax) can bypass header verification. This is especially useful for
|
||||
// Ajax with multipart forms. Because IFRAME transport is used, the
|
||||
// response headers cannot be accessed for verification.
|
||||
if (response !== null && !Drupal.settings.urlIsAjaxTrusted[ajax.url]) {
|
||||
if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') {
|
||||
var customMessage = Drupal.t("The response failed verification so will not be processed.");
|
||||
return ajax.error(xmlhttprequest, ajax.url, customMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return ajax.success(response, status);
|
||||
},
|
||||
complete: function (response, status) {
|
||||
complete: function (xmlhttprequest, status) {
|
||||
ajax.ajaxing = false;
|
||||
if (status == 'error' || status == 'parsererror') {
|
||||
return ajax.error(response, ajax.url);
|
||||
return ajax.error(xmlhttprequest, ajax.url);
|
||||
}
|
||||
},
|
||||
dataType: 'json',
|
||||
@@ -175,6 +200,9 @@ Drupal.ajax = function (base, element, element_settings) {
|
||||
|
||||
// Bind the ajaxSubmit function to the element event.
|
||||
$(ajax.element).bind(element_settings.event, function (event) {
|
||||
if (!Drupal.settings.urlIsAjaxTrusted[ajax.url] && !Drupal.urlIsLocal(ajax.url)) {
|
||||
throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', {'!url': ajax.url}));
|
||||
}
|
||||
return ajax.eventResponse(this, event);
|
||||
});
|
||||
|
||||
@@ -348,7 +376,7 @@ Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) {
|
||||
// this is only needed for IFRAME submissions.
|
||||
var v = $.fieldValue(this.element);
|
||||
if (v !== null) {
|
||||
options.extraData[this.element.name] = v;
|
||||
options.extraData[this.element.name] = Drupal.checkPlain(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,8 +475,8 @@ Drupal.ajax.prototype.getEffect = function (response) {
|
||||
/**
|
||||
* Handler for the form redirection error.
|
||||
*/
|
||||
Drupal.ajax.prototype.error = function (response, uri) {
|
||||
alert(Drupal.ajaxError(response, uri));
|
||||
Drupal.ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
|
||||
Drupal.displayAjaxError(Drupal.ajaxError(xmlhttprequest, uri, customMessage));
|
||||
// Remove the progress element.
|
||||
if (this.progress.element) {
|
||||
$(this.progress.element).remove();
|
||||
@@ -462,7 +490,7 @@ Drupal.ajax.prototype.error = function (response, uri) {
|
||||
$(this.element).removeClass('progress-disabled').removeAttr('disabled');
|
||||
// Reattach behaviors, if they were detached in beforeSerialize().
|
||||
if (this.form) {
|
||||
var settings = response.settings || this.settings || Drupal.settings;
|
||||
var settings = this.settings || Drupal.settings;
|
||||
Drupal.attachBehaviors(this.form, settings);
|
||||
}
|
||||
};
|
||||
@@ -616,6 +644,33 @@ Drupal.ajax.prototype.commands = {
|
||||
.removeClass('odd even')
|
||||
.filter(':even').addClass('odd').end()
|
||||
.filter(':odd').addClass('even');
|
||||
},
|
||||
|
||||
/**
|
||||
* Command to add css.
|
||||
*
|
||||
* Uses the proprietary addImport method if available as browsers which
|
||||
* support that method ignore @import statements in dynamically added
|
||||
* stylesheets.
|
||||
*/
|
||||
add_css: function (ajax, response, status) {
|
||||
// Add the styles in the normal way.
|
||||
$('head').prepend(response.data);
|
||||
// Add imports in the styles using the addImport method if available.
|
||||
var match, importMatch = /^@import url\("(.*)"\);$/igm;
|
||||
if (document.styleSheets[0].addImport && importMatch.test(response.data)) {
|
||||
importMatch.lastIndex = 0;
|
||||
while (match = importMatch.exec(response.data)) {
|
||||
document.styleSheets[0].addImport(match[1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Command to update a form's build ID.
|
||||
*/
|
||||
updateBuildId: function(ajax, response, status) {
|
||||
$('input[name="form_build_id"][value="' + response['old'] + '"]').val(response['new']);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |