Compare commits
985
Commits
7.15
...
advanced-search
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a11650f2b4 | ||
|
|
f09e9563b2 | ||
|
|
c914e7e348 | ||
|
|
b5f3769416 | ||
|
|
3133fd480b | ||
|
|
b20732f9a8 | ||
|
|
8b486ffc60 | ||
|
|
7d5bedcb0c | ||
|
|
268c8b619b | ||
|
|
bbeb5f01ac | ||
|
|
bd1a1de792 | ||
|
|
af9630060a | ||
|
|
383ca8b173 | ||
|
|
afc654c704 | ||
|
|
106129c27c | ||
|
|
81810c5af4 | ||
|
|
12c076c349 | ||
|
|
9d45086951 | ||
|
|
8777adbe2e | ||
|
|
82a22114d3 | ||
|
|
098f083b8d | ||
|
|
e8586eb4da | ||
|
|
1e1a762b9b | ||
|
|
e9146c29ce | ||
|
|
042e111bc4 | ||
|
|
2f56697bb7 | ||
|
|
55700094a2 | ||
|
|
9bfbd861ca | ||
|
|
5f26b3e160 | ||
|
|
1b9f8e3ab4 | ||
|
|
c90cfa63e4 | ||
|
|
7bc3c13ad6 | ||
|
|
1ee4e95491 | ||
|
|
bf5f1a63ff | ||
|
|
38648c1670 | ||
|
|
1d4fcf0d89 | ||
|
|
73417de740 | ||
|
|
0edc6fd23a | ||
|
|
abb106d7c2 | ||
|
|
be2da7afe0 | ||
|
|
243f5b689c | ||
|
|
301d403887 | ||
|
|
08e5ed7202 | ||
|
|
4ca87255ab | ||
|
|
4b2ab455c9 | ||
|
|
b9c809d2c7 | ||
|
|
ed483507e5 | ||
|
|
8feebe3d1e | ||
|
|
5c7f02554f | ||
|
|
58161d2b57 | ||
|
|
ce192b080e | ||
|
|
aafe1c5460 | ||
|
|
8539255353 | ||
|
|
5706aea93b | ||
|
|
9369b73118 | ||
|
|
ab9f1d3cc4 | ||
|
|
8d0f110c50 | ||
|
|
cedbce376b | ||
|
|
6e2a36fe0c | ||
|
|
d9f3677b98 | ||
|
|
5b82dfb691 | ||
|
|
728f8e6d31 | ||
|
|
9acef9d37e | ||
|
|
542ac42fca | ||
|
|
dbd7b88639 | ||
|
|
28c7a0965a | ||
|
|
b5d76ec5e6 | ||
|
|
83cbcefff9 | ||
|
|
0d940c99db | ||
|
|
2334eb741b | ||
|
|
ddc28956c4 | ||
|
|
abbcb19838 | ||
|
|
024afdfd3d | ||
|
|
b9f2b16d24 | ||
|
|
3f9ba49255 | ||
|
|
f01fdbdd9c | ||
|
|
7563311a19 | ||
|
|
669341f1d6 | ||
|
|
13aafca7e4 | ||
|
|
e24eec56e7 | ||
|
|
eba58a57bf | ||
|
|
e190f5f47d | ||
|
|
ec6f23e149 | ||
|
|
fdd842fe19 | ||
|
|
73ec6d3c1e | ||
|
|
dee5085c89 | ||
|
|
c4ab89f177 | ||
|
|
d1b069ad8b | ||
|
|
c56a523286 | ||
|
|
8b5d721bfd | ||
|
|
7ed9dc54bf | ||
|
|
adee2f54e3 | ||
|
|
41e3e6dfb2 | ||
|
|
5f6a9ac5d1 | ||
|
|
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 | ||
|
|
5658794f17 | ||
|
|
df0ec71ac7 | ||
|
|
93c278c5e8 | ||
|
|
13d6d3b95b | ||
|
|
e0ae80791b | ||
|
|
dfe36ba913 | ||
|
|
caf3bf662c | ||
|
|
66e87e0bf4 | ||
|
|
b2873ad5b1 | ||
|
|
f43260082d | ||
|
|
bef27e8258 | ||
|
|
443e4fc138 | ||
|
|
09ac2a24ac | ||
|
|
789d8708bf | ||
|
|
578adab53b | ||
|
|
d5097a4bc6 | ||
|
|
661765bde9 | ||
|
|
fde4f26165 | ||
|
|
8763bf01dd | ||
|
|
10c9d53c31 | ||
|
|
29f7711833 | ||
|
|
9cc5ba4cfa | ||
|
|
644b7db597 | ||
|
|
779d42d9bb | ||
|
|
78b816920d | ||
|
|
f5e39e1209 | ||
|
|
c9912105d5 | ||
|
|
6a402551d7 | ||
|
|
5b845da277 | ||
|
|
763ce99b95 | ||
|
|
f207e56b2d | ||
|
|
06a4d254c2 | ||
|
|
49fb38b169 | ||
|
|
de022d62e2 | ||
|
|
d9d092295b | ||
|
|
8c47736b71 | ||
|
|
de59738907 | ||
|
|
a575bce275 | ||
|
|
2fdd8fb95c | ||
|
|
e573564b93 | ||
|
|
454adf9478 | ||
|
|
b181133e60 | ||
|
|
e7d0e34651 | ||
|
|
f0f9635e8b | ||
|
|
7a3ee63d15 | ||
|
|
8f492c8b4e | ||
|
|
108f77c73d | ||
|
|
0db5022c47 | ||
|
|
d01d0a2a7e | ||
|
|
2b137c6a19 | ||
|
|
cb6963919c | ||
|
|
39db0ed16d | ||
|
|
1aa3c4e9eb | ||
|
|
1f662a2b40 | ||
|
|
83cf488d4a | ||
|
|
1a145b8470 | ||
|
|
8c09d74e68 | ||
|
|
8e432ea544 | ||
|
|
2d4301ad40 | ||
|
|
662012976d | ||
|
|
cc526dd563 | ||
|
|
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 | ||
|
|
6d0af35191 | ||
|
|
6a94814eaa | ||
|
|
1b6b74ea40 | ||
|
|
00df84c69c | ||
|
|
89e7b9de6e | ||
|
|
4caa0c442b | ||
|
|
6c0f932603 | ||
|
|
18eea497c3 | ||
|
|
c3f366a045 | ||
|
|
fc0253d9c2 | ||
|
|
a6f0f199b5 | ||
|
|
b20b38f514 | ||
|
|
12045fe181 | ||
|
|
feae2e1f34 | ||
|
|
b0f5c3eae0 | ||
|
|
bcf209570a | ||
|
|
b7ab35d6aa | ||
|
|
3b2eb43c8f | ||
|
|
4ef59776b0 | ||
|
|
f276e09115 | ||
|
|
60ca2f9e72 | ||
|
|
aa45d84855 | ||
|
|
5396b3e2b5 | ||
|
|
3eaa5817e0 | ||
|
|
975d758599 | ||
|
|
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 | ||
|
|
4240ab47e8 | ||
|
|
c259bc4543 | ||
|
|
04d628c609 | ||
|
|
3faebabce1 | ||
|
|
a7b1a91c6f | ||
|
|
900155d078 | ||
|
|
aa8698232d | ||
|
|
2543d32599 | ||
|
|
e5028b4522 | ||
|
|
3b4f1e024f | ||
|
|
476ccd94fe | ||
|
|
86d0eb03f5 | ||
|
|
789a40d106 | ||
|
|
2697ba8675 | ||
|
|
c811ffcb26 | ||
|
|
3a3a620cac | ||
|
|
4f6a8d389b | ||
|
|
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 |
Regular → Executable
+24
-4
@@ -1,9 +1,29 @@
|
||||
# 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
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.sublime-project*
|
||||
|
||||
node_modules
|
||||
|
||||
.sass-cache
|
||||
typescript
|
||||
.directory
|
||||
|
||||
*.old_patched
|
||||
|
||||
sync_uploads
|
||||
|
||||
_base_d7.tmproj
|
||||
@@ -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
|
||||
@@ -78,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.
|
||||
@@ -95,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().
|
||||
@@ -129,3 +158,139 @@ DirectoryIndex index.php index.html index.htm
|
||||
</FilesMatch>
|
||||
</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
|
||||
|
||||
# ######################################################################
|
||||
# # MEDIA TYPES AND CHARACTER ENCODINGS #
|
||||
# ######################################################################
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# | Media types |
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 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
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
|
||||
# Data interchange
|
||||
|
||||
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>
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# | Character encodings |
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 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
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
# 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
|
||||
|
||||
<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
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
diff --git a/modules/user/user.module b/modules/user/user.module
|
||||
index bdfd36f..d33a528 100644
|
||||
--- a/modules/user/user.module
|
||||
+++ b/modules/user/user.module
|
||||
@@ -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
|
||||
+ * urls. If langcode is NULL the users preferred language is used.
|
||||
*
|
||||
* @return
|
||||
* A unique URL that provides a one-time log in for the user, from which
|
||||
* they can change their password.
|
||||
*/
|
||||
-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, $account->uid), array('absolute' => TRUE));
|
||||
+ $url_options = array('absolute' => TRUE);
|
||||
+ if (isset($options['langcode'])) {
|
||||
+ $languages = language_list();
|
||||
+ $url_options['language'] = $languages[$options['langcode']];
|
||||
+ }
|
||||
+ else {
|
||||
+ $url_options['language'] = user_preferred_language($account);
|
||||
+ }
|
||||
+ return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), $url_options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2347,6 +2359,10 @@ function user_pass_reset_url($account) {
|
||||
* - uid: The user ID number.
|
||||
* - pass: The hashed user password string.
|
||||
* - 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.
|
||||
*
|
||||
* @return
|
||||
* A unique URL that may be used to confirm the cancellation of the user
|
||||
@@ -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, $account->uid), array('absolute' => TRUE));
|
||||
+ $url_options = array('absolute' => TRUE);
|
||||
+ if (isset($options['langcode'])) {
|
||||
+ $languages = language_list();
|
||||
+ $url_options['language'] = $languages[$options['langcode']];
|
||||
+ }
|
||||
+ else {
|
||||
+ $url_options['language'] = user_preferred_language($account);
|
||||
+ }
|
||||
+ return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid), $url_options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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('language' => $language, 'langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
}
|
||||
|
||||
return $text;
|
||||
@@ -2870,8 +2894,8 @@ Your account on [site:name] has been canceled.
|
||||
*/
|
||||
function user_mail_tokens(&$replacements, $data, $options) {
|
||||
if (isset($data['user'])) {
|
||||
- $replacements['[user:one-time-login-url]'] = user_pass_reset_url($data['user']);
|
||||
- $replacements['[user:cancel-url]'] = user_cancel_url($data['user']);
|
||||
+ $replacements['[user:one-time-login-url]'] = user_pass_reset_url($data['user'], $options);
|
||||
+ $replacements['[user:cancel-url]'] = user_cancel_url($data['user'], $options);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/modules/user/user.test b/modules/user/user.test
|
||||
index 07be4c2..4536e0c 100644
|
||||
--- a/modules/user/user.test
|
||||
+++ b/modules/user/user.test
|
||||
@@ -2145,6 +2145,26 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
+ public function setUp() {
|
||||
+ parent::setUp('locale');
|
||||
+
|
||||
+ $account = $this->drupalCreateUser(array('access administration pages', 'administer languages'));
|
||||
+ $this->drupalLogin($account);
|
||||
+
|
||||
+ // Add language.
|
||||
+ $edit = array('langcode' => 'de');
|
||||
+ $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
+
|
||||
+ // Enable URL language detection and selection.
|
||||
+ $edit = array('language[enabled][locale-url]' => 1);
|
||||
+ $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
|
||||
+
|
||||
+ // Reset static caching.
|
||||
+ drupal_static_reset('language_list');
|
||||
+ drupal_static_reset('locale_url_outbound_alter');
|
||||
+ drupal_static_reset('locale_language_url_rewrite_url');
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Creates a user, then tests the tokens generated from it.
|
||||
*/
|
||||
@@ -2195,6 +2215,39 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase {
|
||||
$output = token_replace($input, array('user' => $account), array('language' => $language, 'sanitize' => FALSE));
|
||||
$this->assertEqual($output, $expected, format_string('Unsanitized user token %token replaced.', array('%token' => $input)));
|
||||
}
|
||||
+
|
||||
+ $languages = language_list();
|
||||
+
|
||||
+ // Generate login and cancel link.
|
||||
+ $tests = array();
|
||||
+ $tests['[user:one-time-login-url]'] = user_pass_reset_url($account);
|
||||
+ $tests['[user:cancel-url]'] = user_cancel_url($account);
|
||||
+
|
||||
+ // Generate tokens with interface language.
|
||||
+ $link = url('user', array('absolute' => TRUE));
|
||||
+ foreach ($tests as $input => $expected) {
|
||||
+ $output = token_replace($input, array('user' => $account), array('langcode' => $language->language, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
+ $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.');
|
||||
+ }
|
||||
+
|
||||
+ // Generate tokens with the user's preferred language.
|
||||
+ $edit['language'] = 'de';
|
||||
+ $account = user_save($account, $edit);
|
||||
+ $link = url('user', array('language' => $languages[$account->language], 'absolute' => TRUE));
|
||||
+ foreach ($tests as $input => $expected) {
|
||||
+ $output = token_replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
+ $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language.");
|
||||
+ }
|
||||
+
|
||||
+ // Generate tokens with one specific language.
|
||||
+ $link = url('user', array('language' => $languages['de'], 'absolute' => TRUE));
|
||||
+ foreach ($tests as $input => $expected) {
|
||||
+ foreach (array($user1, $user2) as $account) {
|
||||
+ $output = token_replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
|
||||
+ $this->assertTrue(strpos($output, $link) === 0, "Generated URL in in the requested language.");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
+770
-29
@@ -1,4 +1,745 @@
|
||||
|
||||
Drupal 7.56, 2017-06-21
|
||||
-----------------------
|
||||
- Fixed security issues (access bypass). See SA-CORE-2017-003.
|
||||
|
||||
Drupal 7.55, 2017-06-07
|
||||
-----------------------
|
||||
- Fixed incompatibility with PHP versions 7.0.19 and 7.1.5 due to duplicate
|
||||
DATE_RFC7231 definition.
|
||||
- Made Drupal core pass all automated tests on PHP 7.1.
|
||||
- Allowed services such as Let's Encrypt to work with Drupal on Apache, by
|
||||
making Drupal's .htaccess file allow access to the .well-known directory
|
||||
defined by RFC 5785.
|
||||
- Made new Drupal sites work correctly on Apache 2.4 when the mod_access_compat
|
||||
Apache module is disabled.
|
||||
- Fixed Drupal's URL-generating functions to always encode '[' and ']' so that
|
||||
the URLs will pass HTML5 validation.
|
||||
- Various additional bug fixes.
|
||||
- Various API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.54, 2017-02-01
|
||||
-----------------------
|
||||
- Modules are now able to define theme engines (API addition:
|
||||
https://www.drupal.org/node/2826480).
|
||||
- Logging of searches can now be disabled (new option in the administrative
|
||||
interface).
|
||||
- Added menu tree render structure to (pre-)process hooks for theme_menu_tree()
|
||||
(API addition: https://www.drupal.org/node/2827134).
|
||||
- Added new function for determining whether an HTTPS request is being served
|
||||
(API addition: https://www.drupal.org/node/2824590).
|
||||
- Fixed incorrect default value for short and medium date formats on the date
|
||||
type configuration page.
|
||||
- File validation error message is now removed after subsequent upload of valid
|
||||
file.
|
||||
- Numerous bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional performance improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.53, 2016-12-07
|
||||
-----------------------
|
||||
- Fixed drag and drop support on newer Chrome/IE 11+ versions after 7.51 update
|
||||
when jQuery is updated to 1.7-1.11.0.
|
||||
|
||||
Drupal 7.52, 2016-11-16
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-005.
|
||||
|
||||
Drupal 7.51, 2016-10-05
|
||||
-----------------------
|
||||
- The Update module now also checks for updates to a disabled theme that is
|
||||
used as an admin theme.
|
||||
- Exceptions thrown in dblog_watchdog() are now caught and ignored.
|
||||
- Clarified the warning that appears when modules are missing or have moved.
|
||||
- Log messages are now XSS filtered on display.
|
||||
- Draggable tables now work on touch screen devices.
|
||||
- Added a setting for allowing double underscores in CSS identifiers
|
||||
(https://www.drupal.org/node/2810369).
|
||||
- If a user navigates away from a page while an Ajax request is running they
|
||||
will no longer get an error message saying "An Ajax HTTP request terminated
|
||||
abnormally".
|
||||
- The system_region_list() API function now takes an optional third parameter
|
||||
which allows region name translations to be skipped when they are not needed
|
||||
(API addition: https://www.drupal.org/node/2810365).
|
||||
- Numerous performance improvements.
|
||||
- Numerous bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.50, 2016-07-07
|
||||
-----------------------
|
||||
- Added a new "administer fields" permission for trusted users, which is
|
||||
required in addition to other permissions to use the field UI
|
||||
(https://www.drupal.org/node/2483307).
|
||||
- Added clickjacking protection to Drupal core by setting the X-Frame-Options
|
||||
header to SAMEORIGIN by default (https://www.drupal.org/node/2735873).
|
||||
- Added support for full UTF-8 (emojis, Asian symbols, mathematical symbols) on
|
||||
MySQL and other database drivers when the site and database are configured to
|
||||
allow it (https://www.drupal.org/node/2761183).
|
||||
- Improved performance by avoiding a re-scan of directories when a file is
|
||||
missing; instead, trigger a PHP warning (minor API change:
|
||||
https://www.drupal.org/node/2581445).
|
||||
- Made it possible to use any PHP callable in Ajax form callbacks, form API
|
||||
form-building functions, and form API wrapper callbacks (API addition:
|
||||
https://www.drupal.org/node/2761169).
|
||||
- Fixed that following a password reset link while logged in leaves users unable
|
||||
to change their password (minor user interface change:
|
||||
https://www.drupal.org/node/2759023).
|
||||
- Implemented various fixes for automated test failures on PHP 5.4+ and PHP 7.
|
||||
Drupal core automated tests now pass in these environments.
|
||||
- Improved support for PHP 7 by fixing various problems.
|
||||
- Fixed various bugs with PHP 5.5+ imagerotate(), including when incorrect
|
||||
color indices are passed in.
|
||||
- Fixed a regression introduced in Drupal 7.43 that allowed files uploaded by
|
||||
anonymous users to be lost after form validation errors, and that also caused
|
||||
regressions with certain contributed modules.
|
||||
- Fixed a regression introduced in Drupal 7.36 which caused the default value
|
||||
of hidden textarea fields to be ignored.
|
||||
- Fixed robots.txt to allow search engines to access CSS, JavaScript and image
|
||||
files.
|
||||
- Changed wording on the Update Manager settings page to clarify that the
|
||||
option to check for disabled module updates also applies to uninstalled
|
||||
modules (administrative-facing translatable string change).
|
||||
- Changed the help text when editing menu links and configuring URL redirect
|
||||
actions so that it does not reference "Drupal" or the drupal.org website
|
||||
(administrative-facing translatable string change).
|
||||
- Fixed the locale safety check that is used to ensure that translations are
|
||||
safe to allow for tokens in the href/src attributes of translated strings.
|
||||
- Fixed that URL generation only works on port 80 when using domain based
|
||||
language negotation.
|
||||
- Made method="get" forms work inside the administrative overlay. The fix adds
|
||||
a new hidden field to these forms when they appear inside the overlay (minor
|
||||
data structure change).
|
||||
- Increased maxlength of menu link title input fields in the node form and
|
||||
menu link form from 128 to 255 characters.
|
||||
- Removed meaningless post-check=0 and pre-check=0 cache control headers from
|
||||
Drupal HTTP responses.
|
||||
- Added a .editorconfig file to auto-configure editors that support it.
|
||||
- Added --directory option to run-tests.sh for easier test discovery of all
|
||||
tests within a project.
|
||||
- Made run-tests.sh exit with a failure code when there are test fails or
|
||||
problems running the script.
|
||||
- Fixed that cookies from previous tests are still present when a new test
|
||||
starts in DrupalWebTestCase.
|
||||
- Improved performance of queries on the {authmap} database table.
|
||||
- Fixed handling of missing files and functions inside the registry.
|
||||
- Fixed Ajax handling for tableselect form elements that use checkboxes.
|
||||
- Fixed a bug which caused ip_address() to return nothing when the client IP
|
||||
address and proxy IP address are the same.
|
||||
- Added a new option to format_xml_elements() to allow for already encoded
|
||||
values.
|
||||
- Changed the {history} table's node ID field to be an unsigned integer, to
|
||||
match the same field in the {node} table and to prevent errors with very
|
||||
large node IDs.
|
||||
- Added an explicit page callback to the "admin/people/create" menu item in the
|
||||
User module (minor data structure change). Previously this automatically
|
||||
inherited the page callback from the parent "admin/people" menu item, which
|
||||
broke contributed modules that override the "admin/people" page.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.44, 2016-06-15
|
||||
-----------------------
|
||||
- Fixed security issues (privilege escalation). See SA-CORE-2016-002.
|
||||
|
||||
Drupal 7.43, 2016-02-24
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-001.
|
||||
|
||||
Drupal 7.42, 2016-02-03
|
||||
-----------------------
|
||||
- Stopped invoking hook_flush_caches() on every cron run, since some modules
|
||||
use that hook for expensive operations that are only needed on cache clears.
|
||||
- Changed the default .htaccess and web.config to block Composer-related files.
|
||||
- Added static caching to module_load_include() to improve performance.
|
||||
- Fixed double-encoding bugs in select field widgets provided by the Options
|
||||
module. The fix deprecates the 'strip_tags' property on option widgets and
|
||||
replaces it with a new 'strip_tags_and_unescape' property (minor data
|
||||
structure change).
|
||||
- Improved MySQL 5.7 support by changing the MySQL database driver to stop
|
||||
using the ANSI SQL mode alias, which has different meanings for different
|
||||
MySQL versions.
|
||||
- Fixed a regression introduced in Drupal 7.39 which prevented autocomplete
|
||||
functionality from working on servers that are not configured to
|
||||
automatically recognize index.php.
|
||||
- Updated the Archive_Tar PEAR package to the latest 1.4.0 release, to fix bugs
|
||||
with tar file handling on various operating systems.
|
||||
- Fixed fatal errors on node preview when a field is displayed in the node
|
||||
teaser but hidden in the full node view. The fix removes a
|
||||
field_attach_prepare_view() call from the node_preview() function since it is
|
||||
redundant with one in the node preview theme layer.
|
||||
- Improved the description of the "Trimmed" format option on text fields
|
||||
(translatable string change, and minor UI and data structure change).
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.41, 2015-10-21
|
||||
-----------------------
|
||||
- Fixed security issues (open redirect). See SA-CORE-2015-004.
|
||||
|
||||
Drupal 7.40, 2015-10-14
|
||||
-----------------------
|
||||
- Made Drupal's code for parsing .info files run much faster and use much less
|
||||
memory.
|
||||
- Prevented drupal_http_request() from returning an error when it receives a
|
||||
201 through 206 HTTP status code.
|
||||
- Added support for autoloading traits via the registry on sites running PHP
|
||||
5.4 or higher.
|
||||
- Allowed the user-picture.tpl.php theme template to have HTML classes besides
|
||||
the default "user-picture" class printed in it (markup change).
|
||||
- Fixed the URL text filter to convert e-mail addresses with plus signs into
|
||||
mailto: links.
|
||||
- Added alternate text to file icons displayed by the File module, to improve
|
||||
accessibility (string change, and minor API addition to theme_file_icon()).
|
||||
- Changed one-time login link failure messages to be displayed as errors or
|
||||
warnings as appropriate, rather than as regular status messages (minor UI
|
||||
change and data structure change).
|
||||
- Changed the default settings.php configuration to exclude private files from
|
||||
the "404_fast_paths" behavior.
|
||||
- Changed the page that displays filter tips for a particular text format, for
|
||||
example filter/tips/full_html, to return "page not found" or "access denied"
|
||||
if the format does not exist or the user does not have access to it. This
|
||||
change adds a new menu item to the Filter module's hook_menu() entry (minor
|
||||
data structure change).
|
||||
- Added a new hook, hook_block_cid_parts_alter(), to allow modules to alter the
|
||||
cache keys used for caching a particular block.
|
||||
- Made drupal_set_message() display and return messages when "0" is passed in
|
||||
as the message to set.
|
||||
- Fixed non-functional "Files displayed by default" setting on file fields.
|
||||
- The "worker callback" provided in hook_cron_queue_info() and the "finished"
|
||||
callback specified during batch processing can now be any PHP callable
|
||||
instead of just functions.
|
||||
- Prevented drupal_set_time_limit() from decreasing the time limit in the case
|
||||
where the PHP maximum execution time is already unlimited.
|
||||
- Changed the default thousand marker for numeric fields from a space ("1 000")
|
||||
to nothing ("1000") (minor UI change: https://www.drupal.org/node/1388376).
|
||||
- Prevented malformed theme .info files (without a "name" key) from causing
|
||||
exceptions during menu rebuilds. If an .info file without a "name" key is
|
||||
found in a module or theme directory, Drupal will now use the module or
|
||||
theme's machine name as the display name instead.
|
||||
- Made the format column in the {date_format_locale} database table
|
||||
case-sensitive, to match the equivalent column in the {date_formats} table.
|
||||
- Fixed a bug in the Statistics module that caused JavaScript files attached to
|
||||
a node while it is being viewed to be omitted from the page.
|
||||
- Added an optional 'project:' prefix that can be added to dependencies in a
|
||||
module's .info file to indicate which project the dependency resides in (API
|
||||
addition: https://www.drupal.org/node/2299747).
|
||||
- Fixed various bugs that occurred after hooks were invoked early in the Drupal
|
||||
bootstrap and that caused module_implements() and drupal_alter() to cache an
|
||||
incomplete set of hook implementations for later use.
|
||||
- Set the X-Content-Type-Options header to "nosniff" when possible, to prevent
|
||||
certain web browsers from picking an unsafe MIME type.
|
||||
- Prevented the database API from executing multiple queries at once on MySQL,
|
||||
if the site's PHP version is new enough to do so. This is a secondary defense
|
||||
against SQL injection (API change: https://www.drupal.org/node/2463973).
|
||||
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused the upgrade
|
||||
to fail when there were multiple file records pointing to the same file.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.39, 2015-08-19
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2015-003.
|
||||
|
||||
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
|
||||
additional HTTP request capabilities can be added by contributed modules.
|
||||
- Changed the Simpletest module to allow PSR-0 test classes to be used in
|
||||
Drupal 7.
|
||||
- Removed an unnecessary "Content-Disposition" header from private file
|
||||
downloads; it prevented many private files from being viewed inline in a web
|
||||
browser.
|
||||
- Changed various field API functions to allow them to optionally act on a
|
||||
single field within an entity (API addition: http://drupal.org/node/1825844).
|
||||
- Fixed a bug which prevented Drupal's file transfer functionality from working
|
||||
on some PHP 5.4 systems.
|
||||
- Fixed incorrect log message when theme() is called for a theme hook that does
|
||||
not exist (minor string change).
|
||||
- Fixed Drupal's token-replacement system to allow spaces in the token value.
|
||||
- Changed the default behavior after a user creates a node they do not have
|
||||
access to view. The user will now be redirected to the front page rather than
|
||||
an access denied page.
|
||||
- Fixed a bug which prevented empty HTTP headers (such as "0") from being set.
|
||||
(Minor behavior change: Callers of drupal_add_http_header() must now set
|
||||
FALSE explicitly to prevent a header from being sent at all; this was already
|
||||
indicated in the function's documentation.)
|
||||
- Fixed OpenID errors when more than one module implements hook_openid(). The
|
||||
behavior is now changed so that if more than one module tries to set the same
|
||||
parameter, the last module's change takes effect.
|
||||
- Fixed a serious documentation bug: The $name variable in the
|
||||
taxonomy-term.tpl.php theme template was incorrectly documented as being
|
||||
sanitized when in fact it is not.
|
||||
- Fixed a bug which prevented Drupal 6 to Drupal 7 upgrades on sites which had
|
||||
duplicate permission names in the User module's database tables.
|
||||
- Added an empty "datatype" attribute to taxonomy term and username links to
|
||||
make the RDFa markup upward compatible with RDFa 1.1 (minor markup addition).
|
||||
- Fixed a bug which caused the denial-of-service protection added in Drupal
|
||||
7.20 to break certain valid image URLs that had an extra slash in them.
|
||||
- Fixed a bug with update queries in the SQLite database driver that prevented
|
||||
Drupal from being installed with SQLite on PHP 5.4.
|
||||
- Fixed enforced dependencies errors updating to recent versions of Drupal 7 on
|
||||
certain non-MySQL databases.
|
||||
- Refactored the Field module's caching behavior to obtain large improvements
|
||||
in memory usage for sites with many fields and instances (API addition:
|
||||
http://drupal.org/node/1915646).
|
||||
- Fixed entity argument not being passed to implementations of
|
||||
hook_file_download_access_alter(). The fix adds an additional context
|
||||
parameter that can be passed when calling drupal_alter() for any hook (API
|
||||
change: http://drupal.org/node/1882722).
|
||||
- Fixed broken support for translatable comment fields (API change:
|
||||
http://drupal.org/node/1874724).
|
||||
- Added an assertThemeOutput() method to Simpletest to allow tests to check
|
||||
that themed output matches an expected HTML string (API addition).
|
||||
- Added a link to "Install another module" after a module has been successfully
|
||||
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: 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
|
||||
settings page (UI change).
|
||||
- Fixed a bug which prevented image styles from being reverted on PHP 5.4.
|
||||
- Made the default .htaccess rules protocol sensitive to improve security for
|
||||
sites which use HTTPS and redirect between "www" and non-"www" versions of
|
||||
the page.
|
||||
- Numerous small bug fixes.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.21, 2013-03-06
|
||||
-----------------------
|
||||
- Allowed sites using the 'image_allow_insecure_derivatives' variable to still
|
||||
have partial protection from the security issues fixed in Drupal 7.20.
|
||||
|
||||
Drupal 7.20, 2013-02-20
|
||||
-----------------------
|
||||
- Fixed security issues (denial of service). See SA-CORE-2013-002.
|
||||
|
||||
Drupal 7.19, 2013-01-16
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2013-001.
|
||||
|
||||
Drupal 7.18, 2012-12-19
|
||||
-----------------------
|
||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2012-004.
|
||||
|
||||
Drupal 7.17, 2012-11-07
|
||||
-----------------------
|
||||
- Changed the default value of the '404_fast_html' variable to have a DOCTYPE
|
||||
declaration.
|
||||
- Made it possible to use associative arrays for the 'items' variable in
|
||||
theme_item_list().
|
||||
- Fixed a bug which prevented required form elements without a title from being
|
||||
given an "error" class when the form fails validation.
|
||||
- Prevented duplicate HTML IDs from appearing when two forms are displayed on
|
||||
the same page and one of them is submitted with invalid data (minor markup
|
||||
change).
|
||||
- Fixed a bug which prevented Drupal 6 to Drupal 7 upgrades on sites which had
|
||||
stale data in the Upload module's database tables.
|
||||
- Fixed a bug in the States API which prevented certain types of form elements
|
||||
from being disabled when requested.
|
||||
- Allowed aggregator feed items with author names longer than 255 characters to
|
||||
have a truncated version saved to the database (rather than causing a fatal
|
||||
error).
|
||||
- Allowed aggregator feed items to have URLs longer than 255 characters
|
||||
(schema change which results in several columns in the Aggregator module's
|
||||
database tables changing from VARCHAR to TEXT fields).
|
||||
- Added hook_taxonomy_term_view() and standardized the process for rendering
|
||||
taxonomy terms to invoke hook_entity_view() and otherwise make it consistent
|
||||
with other entities (API change: http://drupal.org/node/1808870).
|
||||
- Added hook_entity_view_mode_alter() to allow modules to change entity view
|
||||
modes on display (API addition: http://drupal.org/node/1833086).
|
||||
- Fixed a bug which made database queries running a "LIKE" query on blob fields
|
||||
fail on PostgreSQL databases. This caused errors during the Drupal 6 to
|
||||
Drupal 7 upgrade.
|
||||
- Changed the hook_menu() entry for Drupal's rss.xml page to prevent extra path
|
||||
components from being accidentally passed to the page callback function (data
|
||||
structure change).
|
||||
- Removed a non-standard "name" attribute from Drupal's default Content-Type
|
||||
header for file downloads.
|
||||
- Fixed the theme settings form to properly clean up submitted values in
|
||||
$form_state['values'] when the form is submitted (data structure change).
|
||||
- Fixed an inconsistency by removing the colon from the end of the label on
|
||||
multi-valued form fields (minor string change).
|
||||
- Added support for 'weight' in hook_field_widget_info() to allow modules to
|
||||
control the order in which widgets are displayed in the Field UI.
|
||||
- Updated various tables in the OpenID and Book modules to use the default
|
||||
"empty table" text pattern (string change).
|
||||
- Added proxy server support to drupal_http_request().
|
||||
- Added "lang" attributes to language links, to better support screen readers.
|
||||
- Fixed double occurrence of a "ul" HTML tag on secondary local tasks in the
|
||||
Seven theme (markup change).
|
||||
- Fixed bugs which caused taxonomy vocabulary and shortcut set titles to be
|
||||
double-escaped. The fix replaces the taxonomy vocabulary overview page and
|
||||
"Edit shortcuts" menu items' title callback entries in hook_menu() with new
|
||||
functions that do not escape HTML characters (data structure change).
|
||||
- Modified the Update manager module to allow drupal.org to collect usage
|
||||
statistics for individual modules and themes, rather than only for entire
|
||||
projects.
|
||||
- Modified the node listing database query on Drupal's default front page to
|
||||
add table aliases for better query altering (this is a data structure change
|
||||
affecting code which implements hook_query_alter() on this query).
|
||||
- Improved the translatability of the "Field type(s) in use" message on the
|
||||
modules page (admin-facing string change).
|
||||
- Fixed a regression which caused a "call to undefined function
|
||||
drupal_find_base_themes()" fatal error under rare circumstances.
|
||||
- Numerous API documentation improvements.
|
||||
- Additional automated test coverage.
|
||||
|
||||
Drupal 7.16, 2012-10-17
|
||||
-----------------------
|
||||
- Fixed security issues (Arbitrary PHP code execution and information
|
||||
disclosure). See SA-CORE-2012-003.
|
||||
|
||||
Drupal 7.15, 2012-08-01
|
||||
-----------------------
|
||||
- Introduced a 'user_password_reset_timeout' variable to allow the 24-hour
|
||||
@@ -50,8 +791,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.
|
||||
@@ -99,12 +840,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.
|
||||
@@ -138,11 +879,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
|
||||
@@ -310,8 +1051,8 @@ Drupal 7.0, 2011-01-05
|
||||
order can now be customized using the Views module.
|
||||
* Removed the 'related terms' feature from taxonomy module since this can
|
||||
now be achieved with Field API.
|
||||
* Added additional features to the default install profile, and implemented
|
||||
a "slimmed down" install profile designed for developers.
|
||||
* Added additional features to the default installation profile, and
|
||||
implemented a "slimmed down" profile designed for developers.
|
||||
* Added a built-in, automated cron run feature, which is triggered by site
|
||||
visitors.
|
||||
* Added an administrator role which is assigned all permissions for
|
||||
@@ -495,7 +1236,7 @@ Drupal 7.0, 2011-01-05
|
||||
requests.
|
||||
|
||||
Drupal 6.23-dev, xxxx-xx-xx (development release)
|
||||
-----------------------
|
||||
---------------------------
|
||||
|
||||
Drupal 6.22, 2011-05-25
|
||||
-----------------------
|
||||
@@ -505,25 +1246,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
|
||||
@@ -532,24 +1273,24 @@ 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.
|
||||
- Better support for updated jQuery versions.
|
||||
- Reduced resource usage of update.module.
|
||||
- Fixed several issues relating to support of install profiles and
|
||||
- Fixed several issues relating to support of installation profiles and
|
||||
distributions.
|
||||
- Added a locking framework to avoid data corruption on long operations.
|
||||
- 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
|
||||
@@ -558,18 +1299,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
|
||||
@@ -577,7 +1318,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.
|
||||
@@ -656,7 +1397,7 @@ Drupal 6.0, 2008-02-13
|
||||
* Expands the severity levels from 3 (Error, Warning, Notice) to the 8
|
||||
levels defined in RFC 3164.
|
||||
* The watchdog module is now called dblog, and is optional, but enabled by
|
||||
default in the default install profile.
|
||||
default in the default installation profile.
|
||||
* Extended the database log module so log messages can be filtered.
|
||||
* Added syslog module: useful for monitoring large Drupal installations.
|
||||
- Added optional e-mail notifications when users are approved, blocked, or
|
||||
@@ -711,7 +1452,7 @@ Drupal 6.0, 2008-02-13
|
||||
* Themed the installer with the Garland theme.
|
||||
* Added form to provide initial site information during installation.
|
||||
* Added ability to provide extra installation steps programmatically.
|
||||
* Made it possible to import interface translations at install time.
|
||||
* Made it possible to import interface translations during installation.
|
||||
- Added the HTML corrector filter:
|
||||
* Fixes faulty and chopped off HTML in postings.
|
||||
* Tags are now automatically closed at the end of the teaser.
|
||||
@@ -890,7 +1631,7 @@ Drupal 5.0, 2007-01-15
|
||||
- Added web-based installer which can:
|
||||
* Check installation and run-time requirements
|
||||
* Automatically generate the database configuration file
|
||||
* Install pre-made 'install profiles' or distributions
|
||||
* Install pre-made installation profiles or distributions
|
||||
* Import the database structure with automatic table prefixing
|
||||
* Be localized
|
||||
- Added new default Garland theme
|
||||
@@ -950,7 +1691,7 @@ Drupal 5.0, 2007-01-15
|
||||
- Removed the archive module.
|
||||
- Upgrade system:
|
||||
* Created space for update branches.
|
||||
- Forms API:
|
||||
- Form API:
|
||||
* Made it possible to programmatically submit forms.
|
||||
* Improved api for multistep forms.
|
||||
- Theme system:
|
||||
@@ -973,7 +1714,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
|
||||
@@ -1086,7 +1827,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
|
||||
|
||||
Regular → Executable
+1
-1
@@ -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
|
||||
|
||||
+9
-6
@@ -20,18 +20,21 @@ initial database files. Next you must log in and set the access database rights:
|
||||
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.*
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
|
||||
CREATE TEMPORARY TABLES ON databasename.*
|
||||
TO 'username'@'localhost' IDENTIFIED BY 'password';
|
||||
|
||||
where
|
||||
where:
|
||||
|
||||
'databasename' is the name of your database
|
||||
'username@localhost' is the username of your MySQL account
|
||||
'username' is the username of your MySQL account
|
||||
'localhost' is the web server host where Drupal is installed
|
||||
'password' is the password required for that username
|
||||
|
||||
Note: Unless your database user has all of the privileges listed above, you will
|
||||
not be able to run Drupal.
|
||||
Note: Unless the database user/host combination for your Drupal installation
|
||||
has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
|
||||
which is currently only used by Drupal core automated tests and some
|
||||
contributed modules), you will not be able to install or run Drupal.
|
||||
|
||||
If successful, MySQL will reply with:
|
||||
|
||||
|
||||
+5
-3
@@ -20,8 +20,10 @@ Drupal requires:
|
||||
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
|
||||
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
|
||||
compatible drop-in replacement for MySQL.
|
||||
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
|
||||
Server is a backwards-compatible replacement for MySQL.
|
||||
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
|
||||
- SQLite 3.4.2 (or greater) (http://www.sqlite.org/).
|
||||
- SQLite 3.3.7 (or greater) (http://www.sqlite.org/).
|
||||
|
||||
For more detailed information about Drupal requirements, including a list of
|
||||
PHP extensions and configurations that are required, see "System requirements"
|
||||
@@ -89,8 +91,8 @@ INSTALLATION
|
||||
- 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 install profile,
|
||||
- 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/
|
||||
|
||||
Regular → Executable
+116
-112
@@ -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,148 +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>
|
||||
- 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
|
||||
- Heine Deelstra 'Heine' <http://drupal.org/user/17943>
|
||||
- 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
|
||||
------------------
|
||||
@@ -159,145 +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>
|
||||
- Heine Deelstra 'Heine' <http://drupal.org/user/17943>
|
||||
- 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>
|
||||
- Kristof De Jaeger 'swentel' <http://drupal.org/user/107403>
|
||||
- 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
|
||||
Regular → Executable
+35
@@ -4,6 +4,7 @@ CONTENTS OF THIS FILE
|
||||
|
||||
* About Drupal
|
||||
* Configuration and features
|
||||
* Installation profiles
|
||||
* Appearance
|
||||
* Developing for Drupal
|
||||
|
||||
@@ -43,6 +44,40 @@ More about configuration:
|
||||
http://drupal.org/project/modules
|
||||
* See also: "Developing for Drupal" for writing your own modules, below.
|
||||
|
||||
INSTALLATION PROFILES
|
||||
---------------------
|
||||
|
||||
Installation profiles define additional steps (such as enabling modules,
|
||||
defining content types, etc.) that run after the base installation provided
|
||||
by core when Drupal is first installed. There are two basic installation
|
||||
profiles provided with Drupal core.
|
||||
|
||||
Installation profiles from the Drupal community modify the installation process
|
||||
to provide a website for a specific use case, such as a CMS for media
|
||||
publishers, a web-based project tracking tool, or a full-fledged CRM for
|
||||
non-profit organizations raising money and accepting donations. They can be
|
||||
distributed as bare installation profiles or as "distributions". Distributions
|
||||
include Drupal core, the installation profile, and all other required
|
||||
extensions, such as contributed and custom modules, themes, and third-party
|
||||
libraries. Bare installation profiles require you to download Drupal Core and
|
||||
the required extensions separately; place the downloaded profile in the
|
||||
/profiles directory before you start the installation process. Note that the
|
||||
contents of this directory may be overwritten during updates of Drupal core;
|
||||
it is advised to keep code backups or use a version control system.
|
||||
|
||||
Additionally, modules and themes may be placed inside subdirectories in a
|
||||
specific installation profile such as profiles/your_site_profile/modules and
|
||||
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
|
||||
|
||||
APPEARANCE
|
||||
----------
|
||||
|
||||
|
||||
Regular → Executable
+10
@@ -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.
|
||||
|
||||
Regular → Executable
+18
-17
@@ -4,16 +4,16 @@
|
||||
* @file
|
||||
* Administrative script for running authorized file operations.
|
||||
*
|
||||
* Using this script, the site owner (the user actually owning the files on
|
||||
* the webserver) can authorize certain file-related operations to proceed
|
||||
* with elevated privileges, for example to deploy and upgrade modules or
|
||||
* themes. Users should not visit this page directly, but instead use an
|
||||
* administrative user interface which knows how to redirect the user to this
|
||||
* script as part of a multistep process. This script actually performs the
|
||||
* selected operations without loading all of Drupal, to be able to more
|
||||
* gracefully recover from errors. Access to the script is controlled by a
|
||||
* global killswitch in settings.php ('allow_authorize_operations') and via
|
||||
* the 'administer software updates' permission.
|
||||
* Using this script, the site owner (the user actually owning the files on the
|
||||
* webserver) can authorize certain file-related operations to proceed with
|
||||
* elevated privileges, for example to deploy and upgrade modules or themes.
|
||||
* Users should not visit this page directly, but instead use an administrative
|
||||
* user interface which knows how to redirect the user to this script as part of
|
||||
* a multistep process. This script actually performs the selected operations
|
||||
* without loading all of Drupal, to be able to more gracefully recover from
|
||||
* errors. Access to the script is controlled by a global killswitch in
|
||||
* settings.php ('allow_authorize_operations') and via the 'administer software
|
||||
* updates' permission.
|
||||
*
|
||||
* There are helper functions for setting up an operation to run via this
|
||||
* system in modules/system/system.module. For more information, see:
|
||||
@@ -21,16 +21,17 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Root directory of Drupal installation.
|
||||
* Defines the root directory of the Drupal installation.
|
||||
*/
|
||||
define('DRUPAL_ROOT', getcwd());
|
||||
|
||||
/**
|
||||
* Global flag to identify update.php and authorize.php runs, and so
|
||||
* avoid various unwanted operations, such as hook_init() and
|
||||
* hook_exit() invokes, css/js preprocessing and translation, and
|
||||
* solve some theming issues. This flag is checked on several places
|
||||
* in Drupal code (not just authorize.php).
|
||||
* Global flag to identify update.php and authorize.php runs.
|
||||
*
|
||||
* Identifies update.php and authorize.php runs, avoiding unwanted operations
|
||||
* such as hook_init() and hook_exit() invokes, css/js preprocessing and
|
||||
* translation, and solves some theming issues. The flag is checked in other
|
||||
* places in Drupal code (not just authorize.php).
|
||||
*/
|
||||
define('MAINTENANCE_MODE', 'update');
|
||||
|
||||
@@ -51,7 +52,7 @@ function authorize_access_denied_page() {
|
||||
* have access to the 'administer software updates' permission.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the current user can run authorize.php, otherwise FALSE.
|
||||
* TRUE if the current user can run authorize.php, and FALSE if not.
|
||||
*/
|
||||
function authorize_access_allowed() {
|
||||
return variable_get('allow_authorize_operations', TRUE) && user_access('administer software updates');
|
||||
|
||||
Executable
+23
@@ -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/
|
||||
Regular → Executable
Regular → Executable
+121
-15
@@ -168,7 +168,7 @@
|
||||
* displayed while awaiting a response from the callback, and add an optional
|
||||
* message. Possible keys: 'type', 'message', 'url', 'interval'.
|
||||
* More information is available in the
|
||||
* @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7 Form API Reference @endlink
|
||||
* @link forms_api_reference.html Form API Reference @endlink
|
||||
*
|
||||
* In addition to using Form API for doing in-form modification, Ajax may be
|
||||
* enabled by adding classes to buttons and links. By adding the 'use-ajax'
|
||||
@@ -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
|
||||
@@ -251,8 +255,8 @@ function ajax_render($commands = array()) {
|
||||
// reliably diffed with array_diff_key(), since the number can change
|
||||
// due to factors unrelated to the inline content, so for now, we strip
|
||||
// the inline items from Ajax responses, and can add support for them
|
||||
// when drupal_add_css() and drupal_add_js() are changed to using md5()
|
||||
// or some other hash of the inline content.
|
||||
// when drupal_add_css() and drupal_add_js() are changed to use a hash
|
||||
// of the inline content as the array key.
|
||||
foreach ($items[$type] as $key => $item) {
|
||||
if (is_numeric($key)) {
|
||||
unset($items[$type][$key]);
|
||||
@@ -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.
|
||||
@@ -836,7 +895,8 @@ function ajax_command_insert($selector, $html, $settings = NULL) {
|
||||
* @return
|
||||
* An array suitable for use with the ajax_render() function.
|
||||
*
|
||||
* See @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink
|
||||
* See
|
||||
* @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink
|
||||
*/
|
||||
function ajax_command_replace($selector, $html, $settings = NULL) {
|
||||
return array(
|
||||
@@ -1209,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,
|
||||
);
|
||||
}
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -18,7 +18,7 @@ function authorize_filetransfer_form($form, &$form_state) {
|
||||
global $base_url, $is_https;
|
||||
$form = array();
|
||||
|
||||
// If possible, we want to post this form securely via https.
|
||||
// If possible, we want to post this form securely via HTTPS.
|
||||
$form['#https'] = TRUE;
|
||||
|
||||
// CSS we depend on lives in modules/system/maintenance.css, which is loaded
|
||||
|
||||
Regular → Executable
+2
-2
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
Regular → Executable
+707
-237
File diff suppressed because it is too large
Load Diff
Regular → Executable
Regular → Executable
+98
-66
@@ -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.
|
||||
*
|
||||
@@ -80,43 +81,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
||||
* same name. Other implementations might want to store several bins in data
|
||||
* structures that get flushed together. While it is not a problem for most
|
||||
* cache bins if the entries in them are flushed before their expire time, some
|
||||
* might break functionality or are extremely expensive to recalculate. These
|
||||
* will be marked with a (*). The other bins expired automatically by core.
|
||||
* Contributed modules can add additional bins and get them expired
|
||||
* automatically by implementing hook_flush_caches().
|
||||
*
|
||||
* - cache: Generic cache storage bin (used for variables, theme registry,
|
||||
* locale date, list of simpletest tests etc).
|
||||
*
|
||||
* - cache_block: Stores the content of various blocks.
|
||||
*
|
||||
* - cache field: Stores the field data belonging to a given object.
|
||||
*
|
||||
* - cache_filter: Stores filtered pieces of content.
|
||||
*
|
||||
* - cache_form(*): Stores multistep forms. Flushing this bin means that some
|
||||
* forms displayed to users lose their state and the data already submitted
|
||||
* to them.
|
||||
*
|
||||
* - cache_menu: Stores the structure of visible navigation menus per page.
|
||||
*
|
||||
* - cache_page: Stores generated pages for anonymous users. It is flushed
|
||||
* very often, whenever a page changes, at least for every ode and comment
|
||||
* submission. This is the only bin affected by the page cache setting on
|
||||
* the administrator panel.
|
||||
*
|
||||
* - cache path: Stores the system paths that have an alias.
|
||||
*
|
||||
* - cache update(*): Stores available releases. The update server (for
|
||||
* example, drupal.org) needs to produce the relevant XML for every project
|
||||
* installed on the current site. As this is different for (almost) every
|
||||
* site, it's very expensive to recalculate for the update server.
|
||||
* might break functionality or are extremely expensive to recalculate. The
|
||||
* other bins are expired automatically by core. Contributed modules can add
|
||||
* additional bins and get them expired automatically by implementing
|
||||
* hook_flush_caches().
|
||||
*
|
||||
* The reasons for having several bins are as follows:
|
||||
*
|
||||
* - smaller bins mean smaller database tables and allow for faster selects and
|
||||
* inserts
|
||||
* - we try to put fast changing cache items and rather static ones into
|
||||
* - Smaller bins mean smaller database tables and allow for faster selects and
|
||||
* inserts.
|
||||
* - We try to put fast changing cache items and rather static ones into
|
||||
* different bins. The effect is that only the fast changing bins will need a
|
||||
* lot of writes to disk. The more static bins will also be better cacheable
|
||||
* with MySQL's query cache.
|
||||
@@ -125,15 +98,36 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
||||
* 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 are
|
||||
* 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 'cache_block',
|
||||
* 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form',
|
||||
* 'cache_menu', 'cache_page', 'cache_update' or 'cache' for the default
|
||||
* cache.
|
||||
* (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.
|
||||
* - cache_bootstrap: Stores the class registry, the system list of modules,
|
||||
* the list of which modules implement which hooks, and the Drupal variable
|
||||
* list.
|
||||
* - cache_field: Stores the field data belonging to a given object.
|
||||
* - cache_filter: Stores filtered pieces of content.
|
||||
* - cache_form: Stores multistep forms. Flushing this bin means that some
|
||||
* forms displayed to users lose their state and the data already submitted
|
||||
* to them. This bin should not be flushed before its expired time.
|
||||
* - cache_menu: Stores the structure of visible navigation menus per page.
|
||||
* - cache_page: Stores generated pages for anonymous users. It is flushed
|
||||
* very often, whenever a page changes, at least for every node and comment
|
||||
* submission. This is the only bin affected by the page cache setting on
|
||||
* the administrator panel.
|
||||
* - cache_path: Stores the system paths that have an alias.
|
||||
* @param $expire
|
||||
* One of the following values:
|
||||
* (optional) Controls the maximum lifetime of this cache entry. Note that
|
||||
* caches might be subject to clearing at any time, so this setting does not
|
||||
* guarantee a minimum lifetime. With this in mind, the cache should not be
|
||||
* used for data that must be kept during a cache clear, like sessions.
|
||||
*
|
||||
* Use one of the following values:
|
||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||
* explicitly told to using cache_clear_all() with a cache ID.
|
||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||
@@ -141,6 +135,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
||||
* - A Unix timestamp: Indicates that the item should be kept at least until
|
||||
* the given time, after which it behaves like CACHE_TEMPORARY.
|
||||
*
|
||||
* @see _update_cache_set()
|
||||
* @see cache_get()
|
||||
*/
|
||||
function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
||||
@@ -150,18 +145,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)) {
|
||||
@@ -230,13 +227,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.
|
||||
@@ -272,10 +262,17 @@ 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) Controls the maximum lifetime of this cache entry. Note that
|
||||
* caches might be subject to clearing at any time, so this setting does not
|
||||
* guarantee a minimum lifetime. With this in mind, the cache should not be
|
||||
* used for data that must be kept during a cache clear, like sessions.
|
||||
*
|
||||
* Use one of the following values:
|
||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||
* explicitly told to using cache_clear_all() with a cache ID.
|
||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||
@@ -293,12 +290,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);
|
||||
|
||||
@@ -324,7 +323,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;
|
||||
@@ -518,7 +520,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)
|
||||
@@ -555,4 +566,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']));
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
+608
-188
File diff suppressed because it is too large
Load Diff
Regular → Executable
+118
-30
@@ -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.
|
||||
* }
|
||||
@@ -167,7 +170,7 @@
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @link http://drupal.org/developing/api/database
|
||||
* @see http://drupal.org/developing/api/database
|
||||
*/
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -194,7 +197,7 @@ abstract class DatabaseConnection extends PDO {
|
||||
|
||||
/**
|
||||
* The key representing this connection.
|
||||
*
|
||||
*
|
||||
* The key is a unique string which identifies a database connection. A
|
||||
* connection can be a single server or a cluster of master and slaves (use
|
||||
* target to pick between master and slave).
|
||||
@@ -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'] : '');
|
||||
@@ -303,12 +320,28 @@ abstract class DatabaseConnection extends PDO {
|
||||
// Call PDO::__construct and PDO::setAttribute.
|
||||
parent::__construct($dsn, $username, $password, $driver_options);
|
||||
|
||||
// Set a specific PDOStatement class if the driver requires that.
|
||||
// Set a Statement class, unless the driver opted out.
|
||||
if (!empty($this->statementClass)) {
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this Connection object.
|
||||
*
|
||||
* PHP does not destruct an object if it is still referenced in other
|
||||
* variables. In case of PDO database connection objects, PHP only closes the
|
||||
* connection when the PDO object is destructed, so any references to this
|
||||
* object may cause the number of maximum allowed connections to be exceeded.
|
||||
*/
|
||||
public function destroy() {
|
||||
// Destroy all references to this connection by setting them to NULL.
|
||||
// The Statement class attribute only accepts a new value that presents a
|
||||
// proper callable, so we reset it to PDOStatement.
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array()));
|
||||
$this->schema = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default query options for any given query.
|
||||
*
|
||||
@@ -607,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('*' => ' * '));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -637,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
|
||||
@@ -717,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
|
||||
@@ -900,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -914,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -929,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1294,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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1627,8 +1702,8 @@ abstract class Database {
|
||||
*/
|
||||
final public static function removeConnection($key) {
|
||||
if (isset(self::$databaseInfo[$key])) {
|
||||
self::closeConnection(NULL, $key);
|
||||
unset(self::$databaseInfo[$key]);
|
||||
unset(self::$connections[$key]);
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
@@ -1694,11 +1769,24 @@ abstract class Database {
|
||||
if (!isset($key)) {
|
||||
$key = self::$activeKey;
|
||||
}
|
||||
// To close the connection, we need to unset the static variable.
|
||||
// To close a connection, it needs to be set to NULL and removed from the
|
||||
// static variable. In all cases, closeConnection() might be called for a
|
||||
// connection that was not opened yet, in which case the key is not defined
|
||||
// yet and we just ensure that the connection key is undefined.
|
||||
if (isset($target)) {
|
||||
if (isset(self::$connections[$key][$target])) {
|
||||
self::$connections[$key][$target]->destroy();
|
||||
self::$connections[$key][$target] = NULL;
|
||||
}
|
||||
unset(self::$connections[$key][$target]);
|
||||
}
|
||||
else {
|
||||
if (isset(self::$connections[$key])) {
|
||||
foreach (self::$connections[$key] as $target => $connection) {
|
||||
self::$connections[$key][$target]->destroy();
|
||||
self::$connections[$key][$target] = NULL;
|
||||
}
|
||||
}
|
||||
unset(self::$connections[$key]);
|
||||
}
|
||||
}
|
||||
@@ -1852,8 +1940,8 @@ class DatabaseTransaction {
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
public function __construct(DatabaseConnection &$connection, $name = NULL) {
|
||||
$this->connection = &$connection;
|
||||
public function __construct(DatabaseConnection $connection, $name = NULL) {
|
||||
$this->connection = $connection;
|
||||
// If there is no transaction depth, then no transaction has started. Name
|
||||
// the transaction 'drupal_transaction'.
|
||||
if (!$depth = $connection->transactionDepth()) {
|
||||
@@ -1957,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
|
||||
@@ -1976,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
|
||||
@@ -2351,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
|
||||
@@ -2769,7 +2857,7 @@ function _db_create_keys_sql($spec) {
|
||||
* Renames a table.
|
||||
*
|
||||
* @param $table
|
||||
* The table to be renamed.
|
||||
* The current name of the table to be renamed.
|
||||
* @param $new_name
|
||||
* The new name for the table.
|
||||
*/
|
||||
@@ -2800,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
|
||||
@@ -2980,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.
|
||||
*/
|
||||
|
||||
Regular → Executable
+6
-4
@@ -128,9 +128,10 @@ class DatabaseLog {
|
||||
* Determine the routine that called this query.
|
||||
*
|
||||
* We define "the routine that called this query" as the first entry in
|
||||
* the call stack that is not inside includes/database. That makes the
|
||||
* climbing logic very simple, and handles the variable stack depth caused
|
||||
* by the query builders.
|
||||
* the call stack that is not inside includes/database and does have a file
|
||||
* (which excludes call_user_func_array(), anonymous functions and similar).
|
||||
* That makes the climbing logic very simple, and handles the variable stack
|
||||
* depth caused by the query builders.
|
||||
*
|
||||
* @link http://www.php.net/debug_backtrace
|
||||
* @return
|
||||
@@ -144,7 +145,8 @@ class DatabaseLog {
|
||||
$stack = debug_backtrace();
|
||||
$stack_count = count($stack);
|
||||
for ($i = 0; $i < $stack_count; ++$i) {
|
||||
if (strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'database') === FALSE) {
|
||||
if (!empty($stack[$i]['file']) && strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'database') === FALSE) {
|
||||
$stack[$i] += array('args' => array());
|
||||
return array(
|
||||
'file' => $stack[$i]['file'],
|
||||
'line' => $stack[$i]['line'],
|
||||
|
||||
Regular → Executable
+68
-14
@@ -13,11 +13,11 @@
|
||||
class DatabaseConnection_mysql extends DatabaseConnection {
|
||||
|
||||
/**
|
||||
* Flag to indicate if we have registered the nextID cleanup function.
|
||||
* Flag to indicate if the cleanup function in __destruct() should run.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $shutdownRegistered = FALSE;
|
||||
protected $needsCleanup = FALSE;
|
||||
|
||||
public function __construct(array $connection_options = array()) {
|
||||
// This driver defaults to transaction support, except if explicitly passed FALSE.
|
||||
@@ -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,18 @@ 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() {
|
||||
if ($this->needsCleanup) {
|
||||
$this->nextIdDelete();
|
||||
}
|
||||
}
|
||||
|
||||
public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
|
||||
@@ -84,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;
|
||||
}
|
||||
|
||||
@@ -115,12 +138,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
||||
$this->query('INSERT INTO {sequences} (value) VALUES (:value) ON DUPLICATE KEY UPDATE value = value', array(':value' => $existing_id));
|
||||
$new_id = $this->query('INSERT INTO {sequences} () VALUES ()', array(), array('return' => Database::RETURN_INSERT_ID));
|
||||
}
|
||||
if (!$this->shutdownRegistered) {
|
||||
// Use register_shutdown_function() here to keep the database system
|
||||
// independent of Drupal.
|
||||
register_shutdown_function(array($this, 'nextIdDelete'));
|
||||
$shutdownRegistered = TRUE;
|
||||
}
|
||||
$this->needsCleanup = TRUE;
|
||||
return $new_id;
|
||||
}
|
||||
|
||||
@@ -194,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Regular → Executable
Regular → Executable
+3
-16
@@ -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".
|
||||
|
||||
Regular → Executable
+25
-17
@@ -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));
|
||||
|
||||
Regular → Executable
+26
-7
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The name by which to obtain a lock for retrive the next insert id.
|
||||
* The name by which to obtain a lock for retrieving the next insert id.
|
||||
*/
|
||||
define('POSTGRESQL_NEXTID_LOCK', 1000);
|
||||
|
||||
@@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
$connection_options['pdo'] += array(
|
||||
// Prepared statements are most effective for performance when queries
|
||||
// are recycled (used several times). However, if they are not re-used,
|
||||
// prepared statements become ineffecient. Since most of Drupal's
|
||||
// prepared statements become inefficient. Since most of Drupal's
|
||||
// prepared queries are not re-used, it should be faster to emulate
|
||||
// the preparation than to actually ready statements for re-use. If in
|
||||
// doubt, reset to FALSE and measure performance.
|
||||
@@ -74,6 +74,17 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public function prepareQuery($query) {
|
||||
// mapConditionOperator converts LIKE operations to ILIKE for consistency
|
||||
// with MySQL. However, Postgres does not support ILIKE on bytea (blobs)
|
||||
// fields.
|
||||
// To make the ILIKE operator work, we type-cast bytea fields into text.
|
||||
// @todo This workaround only affects bytea fields, but the involved field
|
||||
// types involved in the query are unknown, so there is no way to
|
||||
// conditionally execute this for affected queries only.
|
||||
return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE) /i', ' ${1}::text ${2} ', $query));
|
||||
}
|
||||
|
||||
public function query($query, array $args = array(), $options = array()) {
|
||||
|
||||
$options += $this->defaultOptions();
|
||||
@@ -135,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;
|
||||
}
|
||||
|
||||
@@ -164,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive a the next id in a sequence.
|
||||
* Retrieve the next id in a sequence.
|
||||
*
|
||||
* PostgreSQL has built in sequences. We'll use these instead of inserting
|
||||
* and updating a sequences table.
|
||||
*/
|
||||
public function nextId($existing = 0) {
|
||||
|
||||
// Retrive the name of the sequence. This information cannot be cached
|
||||
// Retrieve the name of the sequence. This information cannot be cached
|
||||
// because the prefix may change, for example, like it does in simpletests.
|
||||
$sequence_name = $this->makeSequenceName('sequences', 'value');
|
||||
|
||||
@@ -183,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
}
|
||||
|
||||
// PostgreSQL advisory locks are simply locks to be used by an
|
||||
// application such as Drupal. This will prevent other Drupal proccesses
|
||||
// application such as Drupal. This will prevent other Drupal processes
|
||||
// from altering the sequence while we are.
|
||||
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||
|
||||
@@ -198,13 +209,21 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
// Reset the sequence to a higher value than the existing id.
|
||||
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
|
||||
|
||||
// Retrive the next id. We know this will be as high as we want it.
|
||||
// Retrieve the next id. We know this will be as high as we want it.
|
||||
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
|
||||
|
||||
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function utf8mb4IsActive() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function utf8mb4IsSupported() {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Regular → Executable
+1
-1
@@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
|
||||
LANGUAGE \'sql\''
|
||||
);
|
||||
|
||||
// Using || to concatenate in Drupal is not recommeneded because there are
|
||||
// Using || to concatenate in Drupal is not recommended because there are
|
||||
// database drivers for Drupal that do not support the syntax, however
|
||||
// they do support CONCAT(item1, item2) which we can replicate in
|
||||
// PostgreSQL. PostgreSQL requires the function to be defined for each
|
||||
|
||||
Regular → Executable
+2
-1
@@ -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 ';
|
||||
|
||||
Regular → Executable
+14
-14
@@ -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);
|
||||
|
||||
Regular → Executable
+2
-2
@@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
||||
}
|
||||
|
||||
// If a table loads all fields, it can not be added again. It would
|
||||
// result in an ambigious alias error because that field would be loaded
|
||||
// result in an ambiguous alias error because that field would be loaded
|
||||
// twice: Once through table_alias.* and once directly. If the field
|
||||
// actually belongs to a different table, it must be added manually.
|
||||
foreach ($this->tables as $table) {
|
||||
@@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
||||
}
|
||||
|
||||
// If $field contains an characters which are not allowed in a field name
|
||||
// it is considered an expression, these can't be handeld automatically
|
||||
// it is considered an expression, these can't be handled automatically
|
||||
// either.
|
||||
if ($this->connection->escapeField($field) != $field) {
|
||||
return $return;
|
||||
|
||||
Regular → Executable
Regular → Executable
+71
-67
@@ -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().
|
||||
*/
|
||||
@@ -844,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface {
|
||||
/**
|
||||
* Executes the DELETE query.
|
||||
*
|
||||
* @return
|
||||
* The return value is dependent on the database connection.
|
||||
* @return int
|
||||
* The number of rows affected by the delete query.
|
||||
*/
|
||||
public function execute() {
|
||||
$values = array();
|
||||
@@ -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().
|
||||
*/
|
||||
@@ -1231,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
|
||||
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
|
||||
* instead. MergeQuery::fields() can also be called which calls both of these
|
||||
* methods as the common case is to use the same column-value pairs for both
|
||||
* INSERT and UPDATE. However, this is not mandatory. Another convinient
|
||||
* INSERT and UPDATE. However, this is not mandatory. Another convenient
|
||||
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
|
||||
* condition and the INSERT query part.
|
||||
*
|
||||
@@ -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().
|
||||
*/
|
||||
@@ -1898,8 +1897,13 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
||||
function __clone() {
|
||||
$this->changed = TRUE;
|
||||
foreach ($this->conditions as $key => $condition) {
|
||||
if ($key !== '#conjunction' && $condition['field'] instanceOf QueryConditionInterface) {
|
||||
$this->conditions[$key]['field'] = clone($condition['field']);
|
||||
if ($key !== '#conjunction') {
|
||||
if ($condition['field'] instanceOf QueryConditionInterface) {
|
||||
$this->conditions[$key]['field'] = clone($condition['field']);
|
||||
}
|
||||
if ($condition['value'] instanceOf SelectQueryInterface) {
|
||||
$this->conditions[$key]['value'] = clone($condition['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
+11
-5
@@ -92,7 +92,8 @@ require_once dirname(__FILE__) . '/query.inc';
|
||||
* specification). Each specification is an array containing the name of
|
||||
* the referenced table ('table'), and an array of column mappings
|
||||
* ('columns'). Column mappings are defined by key pairs ('source_column' =>
|
||||
* 'referenced_column').
|
||||
* 'referenced_column'). This key is for documentation purposes only; foreign
|
||||
* keys are not created in the database, nor are they enforced by Drupal.
|
||||
* - 'indexes': An associative array of indexes ('indexname' =>
|
||||
* specification). Each specification is an array of one or more
|
||||
* key column specifiers (see below) that form an index on the
|
||||
@@ -144,6 +145,8 @@ require_once dirname(__FILE__) . '/query.inc';
|
||||
* 'unique keys' => array(
|
||||
* 'vid' => array('vid'),
|
||||
* ),
|
||||
* // For documentation purposes only; foreign keys are not created in the
|
||||
* // database.
|
||||
* 'foreign keys' => array(
|
||||
* 'node_revision' => array(
|
||||
* 'table' => 'node_revision',
|
||||
@@ -161,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc';
|
||||
* @see drupal_install_schema()
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for database schema definitions.
|
||||
*/
|
||||
abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||
|
||||
protected $connection;
|
||||
@@ -288,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
|
||||
$info = $this->connection->getConnectionOptions();
|
||||
|
||||
// Retrive the table name and schema
|
||||
// Retrieve the table name and schema
|
||||
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
|
||||
|
||||
$condition = new DatabaseCondition('AND');
|
||||
@@ -416,7 +422,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 +636,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 +660,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) {
|
||||
|
||||
Regular → Executable
+20
-2
@@ -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) {
|
||||
@@ -1230,6 +1231,21 @@ class SelectQuery extends Query implements SelectQueryInterface {
|
||||
|
||||
// Modules may alter all queries or only those having a particular tag.
|
||||
if (isset($this->alterTags)) {
|
||||
// Many contrib modules assume that query tags used for access-checking
|
||||
// purposes follow the pattern $entity_type . '_access'. But this is
|
||||
// not the case for taxonomy terms, since core used to add term_access
|
||||
// instead of taxonomy_term_access to its queries. Provide backwards
|
||||
// compatibility by adding both tags here instead of attempting to fix
|
||||
// all contrib modules in a coordinated effort.
|
||||
// TODO:
|
||||
// - Extract this mechanism into a hook as part of a public (non-security)
|
||||
// issue.
|
||||
// - Emit E_USER_DEPRECATED if term_access is used.
|
||||
// https://www.drupal.org/node/2575081
|
||||
$term_access_tags = array('term_access' => 1, 'taxonomy_term_access' => 1);
|
||||
if (array_intersect_key($this->alterTags, $term_access_tags)) {
|
||||
$this->alterTags += $term_access_tags;
|
||||
}
|
||||
$hooks = array('query');
|
||||
foreach ($this->alterTags as $tag => $value) {
|
||||
$hooks[] = 'query_' . $tag;
|
||||
@@ -1384,6 +1400,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;
|
||||
}
|
||||
|
||||
Regular → Executable
+9
-1
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Regular → Executable
-2
@@ -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';
|
||||
|
||||
Regular → Executable
+11
-32
@@ -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) . ')';
|
||||
@@ -57,39 +58,18 @@ class InsertQuery_sqlite extends InsertQuery {
|
||||
* we don't select those rows.
|
||||
*
|
||||
* A query like this one:
|
||||
* UPDATE test SET name = 'newname' WHERE tid = 1
|
||||
* UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1
|
||||
* will become:
|
||||
* UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname'
|
||||
* UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 AND (col1 <> 'newcol1' OR col2 <> 'newcol2')
|
||||
*/
|
||||
class UpdateQuery_sqlite extends UpdateQuery {
|
||||
/**
|
||||
* Helper function that removes the fields that are already in a condition.
|
||||
*
|
||||
* @param $fields
|
||||
* The fields.
|
||||
* @param QueryConditionInterface $condition
|
||||
* A database condition.
|
||||
*/
|
||||
protected function removeFieldsInCondition(&$fields, QueryConditionInterface $condition) {
|
||||
foreach ($condition->conditions() as $child_condition) {
|
||||
if ($child_condition['field'] instanceof QueryConditionInterface) {
|
||||
$this->removeFieldsInCondition($fields, $child_condition['field']);
|
||||
}
|
||||
else {
|
||||
unset($fields[$child_condition['field']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
if (!empty($this->queryOptions['sqlite_return_matched_rows'])) {
|
||||
return parent::execute();
|
||||
}
|
||||
|
||||
// Get the fields used in the update query, and remove those that are already
|
||||
// in the condition.
|
||||
// Get the fields used in the update query.
|
||||
$fields = $this->expressionFields + $this->fields;
|
||||
$this->removeFieldsInCondition($fields, $this->condition);
|
||||
|
||||
// Add the inverse of the fields to the condition.
|
||||
$condition = new DatabaseCondition('OR');
|
||||
@@ -119,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery {
|
||||
|
||||
/**
|
||||
* SQLite specific implementation of DeleteQuery.
|
||||
*
|
||||
* When the WHERE is omitted from a DELETE statement and the table being deleted
|
||||
* has no triggers, SQLite uses an optimization to erase the entire table content
|
||||
* without having to visit each row of the table individually.
|
||||
*
|
||||
* Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted
|
||||
* by that optimized "truncate" optimization.
|
||||
*/
|
||||
class DeleteQuery_sqlite extends DeleteQuery {
|
||||
public function execute() {
|
||||
// When the WHERE is omitted from a DELETE statement and the table being
|
||||
// deleted has no triggers, SQLite uses an optimization to erase the entire
|
||||
// table content without having to visit each row of the table individually.
|
||||
// Prior to SQLite 3.6.5, SQLite does not return the actual number of rows
|
||||
// deleted by that optimized "truncate" optimization. But we want to return
|
||||
// the number of rows affected, so we calculate it directly.
|
||||
if (!count($this->condition)) {
|
||||
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
|
||||
parent::execute();
|
||||
|
||||
Regular → Executable
+15
-15
@@ -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);
|
||||
@@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
||||
// database. So the syntax '...RENAME TO database.table' would fail.
|
||||
// So we must determine the full table name here rather than surrounding
|
||||
// the table with curly braces incase the db_prefix contains a reference
|
||||
// to a database outside of our existsing database.
|
||||
// to a database outside of our existing database.
|
||||
$info = $this->getPrefixInfo($new_name);
|
||||
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Regular → Executable
Regular → Executable
+10
-10
@@ -12,11 +12,6 @@ function system_default_date_formats() {
|
||||
$formats = array();
|
||||
|
||||
// Short date formats.
|
||||
$formats[] = array(
|
||||
'type' => 'short',
|
||||
'format' => 'Y-m-d H:i',
|
||||
'locales' => array(),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'short',
|
||||
'format' => 'm/d/Y - H:i',
|
||||
@@ -37,6 +32,11 @@ function system_default_date_formats() {
|
||||
'format' => 'd.m.Y - H:i',
|
||||
'locales' => array('de-ch', 'de-de', 'de-lu', 'fi-fi', 'fr-ch', 'is-is', 'pl-pl', 'ro-ro', 'ru-ru'),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'short',
|
||||
'format' => 'Y-m-d H:i',
|
||||
'locales' => array(),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'short',
|
||||
'format' => 'm/d/Y - g:ia',
|
||||
@@ -84,11 +84,6 @@ function system_default_date_formats() {
|
||||
);
|
||||
|
||||
// Medium date formats.
|
||||
$formats[] = array(
|
||||
'type' => 'medium',
|
||||
'format' => 'D, Y-m-d H:i',
|
||||
'locales' => array(),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'medium',
|
||||
'format' => 'D, m/d/Y - H:i',
|
||||
@@ -104,6 +99,11 @@ function system_default_date_formats() {
|
||||
'format' => 'D, Y/m/d - H:i',
|
||||
'locales' => array('en-ca', 'fr-ca', 'no-no', 'sv-se'),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'medium',
|
||||
'format' => 'D, Y-m-d H:i',
|
||||
'locales' => array(),
|
||||
);
|
||||
$formats[] = array(
|
||||
'type' => 'medium',
|
||||
'format' => 'F j, Y - H:i',
|
||||
|
||||
+106
-34
@@ -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).
|
||||
@@ -296,6 +329,7 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Attaches data to entities upon loading.
|
||||
*
|
||||
* This will attach fields, if the entity is fieldable. It calls
|
||||
* hook_entity_load() for modules which need to add data to all entities.
|
||||
* It also calls hook_TYPE_load() on the loaded entities. For example
|
||||
@@ -364,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,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.
|
||||
@@ -415,13 +463,14 @@ class EntityFieldQueryException extends Exception {}
|
||||
* an EntityFieldQueryException will be raised if an unsupported condition is
|
||||
* specified or if the query has field conditions or sorts that are stored in
|
||||
* different field storage engines. However, this logic can be overridden in
|
||||
* hook_entity_query().
|
||||
* hook_entity_query_alter().
|
||||
*
|
||||
* Also note that this query does not automatically respect entity access
|
||||
* restrictions. Node access control is performed by the SQL storage engine but
|
||||
* other storage engines might not do this.
|
||||
*/
|
||||
class EntityFieldQuery {
|
||||
|
||||
/**
|
||||
* Indicates that both deleted and non-deleted fields should be returned.
|
||||
*
|
||||
@@ -594,9 +643,7 @@ class EntityFieldQuery {
|
||||
*
|
||||
* 'bundle', 'revision_id' and 'entity_id' have no such restrictions.
|
||||
*
|
||||
* Note: The "comment" and "taxonomy_term" entity types don't support bundle
|
||||
* conditions. For "taxonomy_term", propertyCondition('vid') can be used
|
||||
* instead.
|
||||
* Note: The "comment" entity type does not support bundle conditions.
|
||||
*
|
||||
* @param $name
|
||||
* 'entity_type', 'bundle', 'revision_id' or 'entity_id'.
|
||||
@@ -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.
|
||||
@@ -958,7 +1029,7 @@ class EntityFieldQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a pager for the query.
|
||||
* Enables a pager for the query.
|
||||
*
|
||||
* @param $limit
|
||||
* An integer specifying the number of elements per page. If passed a false
|
||||
@@ -986,10 +1057,11 @@ class EntityFieldQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable sortable tables for this query.
|
||||
* Enables sortable tables for this query.
|
||||
*
|
||||
* @param $headers
|
||||
* An EFQ Header array based on which the order clause is added to the query.
|
||||
* An EFQ Header array based on which the order clause is added to the
|
||||
* query.
|
||||
*
|
||||
* @return EntityFieldQuery
|
||||
* The called object.
|
||||
@@ -1272,7 +1344,7 @@ class EntityFieldQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of results and initialize a pager for the query.
|
||||
* Gets the total number of results and initializes a pager for the query.
|
||||
*
|
||||
* The pager can be disabled by either setting the pager limit to 0, or by
|
||||
* setting this query to be a count query.
|
||||
@@ -1359,6 +1431,6 @@ class EntityFieldQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when a malformed entity is passed.
|
||||
* Defines an exception thrown when a malformed entity is passed.
|
||||
*/
|
||||
class EntityMalformedException extends Exception { }
|
||||
|
||||
Regular → Executable
+15
-21
@@ -5,26 +5,11 @@
|
||||
* Functions for error handling.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error reporting level: display no errors.
|
||||
*/
|
||||
define('ERROR_REPORTING_HIDE', 0);
|
||||
|
||||
/**
|
||||
* Error reporting level: display errors and warnings.
|
||||
*/
|
||||
define('ERROR_REPORTING_DISPLAY_SOME', 1);
|
||||
|
||||
/**
|
||||
* Error reporting level: display all messages.
|
||||
*/
|
||||
define('ERROR_REPORTING_DISPLAY_ALL', 2);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -81,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
|
||||
_drupal_log_error(array(
|
||||
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
|
||||
// The standard PHP error handler considers that the error messages
|
||||
// are HTML. We mimick this behavior here.
|
||||
// are HTML. We mimic this behavior here.
|
||||
'!message' => filter_xss_admin($message),
|
||||
'%function' => $caller['function'],
|
||||
'%file' => $caller['file'],
|
||||
@@ -129,7 +114,7 @@ function _drupal_decode_exception($exception) {
|
||||
return array(
|
||||
'%type' => get_class($exception),
|
||||
// The standard PHP exception handler considers that the exception message
|
||||
// is plain-text. We mimick this behavior here.
|
||||
// is plain-text. We mimic this behavior here.
|
||||
'!message' => check_plain($message),
|
||||
'%function' => $caller['function'],
|
||||
'%file' => $caller['file'],
|
||||
@@ -184,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']);
|
||||
@@ -214,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)');
|
||||
@@ -239,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
||||
}
|
||||
else {
|
||||
// Display the message if the current error reporting level allows this type
|
||||
// of message to be displayed, and unconditionnaly in update.php.
|
||||
// of message to be displayed, and unconditionally in update.php.
|
||||
if (error_displayable($error)) {
|
||||
$class = 'error';
|
||||
|
||||
|
||||
Regular → Executable
+208
-118
@@ -89,7 +89,7 @@ define('FILE_STATUS_PERMANENT', 1);
|
||||
* wrappers that are appropriate for particular usage. For example, this returns
|
||||
* only stream wrappers that use local file storage:
|
||||
* @code
|
||||
* $local_stream_wrappers = file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL);
|
||||
* $local_stream_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
|
||||
* @endcode
|
||||
*
|
||||
* The $filter parameter can only filter to types containing a particular flag.
|
||||
@@ -99,7 +99,7 @@ define('FILE_STATUS_PERMANENT', 1);
|
||||
* array_diff_key() function can be used to help with this. For example, this
|
||||
* returns only stream wrappers that do not use local file storage:
|
||||
* @code
|
||||
* $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL));
|
||||
* $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL));
|
||||
* @endcode
|
||||
*
|
||||
* @param $filter
|
||||
@@ -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);
|
||||
@@ -282,10 +284,6 @@ function file_stream_wrapper_uri_normalize($uri) {
|
||||
$uri = $scheme . '://' . $target;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The default scheme is file://
|
||||
$url = 'file://' . $uri;
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
@@ -398,8 +396,8 @@ function file_create_url($uri) {
|
||||
}
|
||||
}
|
||||
elseif ($scheme == 'http' || $scheme == 'https') {
|
||||
// Check for http so that we don't have to implement getExternalUrl() for
|
||||
// the http wrapper.
|
||||
// Check for HTTP so that we don't have to implement getExternalUrl() for
|
||||
// the HTTP wrapper.
|
||||
return $uri;
|
||||
}
|
||||
else {
|
||||
@@ -474,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);
|
||||
}
|
||||
@@ -484,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)) {
|
||||
@@ -508,6 +502,56 @@ 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 = <<<EOF
|
||||
# Deny all requests from Apache 2.4+.
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
|
||||
# Deny all requests from Apache 2.0-2.2.
|
||||
<IfModule !mod_authz_core.c>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
EOF
|
||||
. "\n\n" . $lines;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads file objects from the database.
|
||||
*
|
||||
@@ -590,7 +634,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;
|
||||
}
|
||||
|
||||
@@ -723,10 +771,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.
|
||||
@@ -821,10 +870,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
|
||||
@@ -834,9 +884,8 @@ function file_valid_uri($uri) {
|
||||
* A string specifying the filepath or URI of the source file.
|
||||
* @param $destination
|
||||
* A URI containing the destination that $source should be copied to. The
|
||||
* URI may be a bare filepath (without a scheme) and in that case the default
|
||||
* scheme (file://) will be used. If this value is omitted, Drupal's default
|
||||
* files scheme will be used, usually "public://".
|
||||
* URI may be a bare filepath (without a scheme). If this value is omitted,
|
||||
* Drupal's default files scheme will be used, usually "public://".
|
||||
* @param $replace
|
||||
* Replace behavior when the destination file already exists:
|
||||
* - FILE_EXISTS_REPLACE - Replace the existing file.
|
||||
@@ -851,7 +900,6 @@ function file_valid_uri($uri) {
|
||||
*/
|
||||
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
|
||||
$original_source = $source;
|
||||
$original_destination = $destination;
|
||||
|
||||
// Assert that the source file actually exists.
|
||||
if (!file_exists($source)) {
|
||||
@@ -892,7 +940,7 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
|
||||
$destination = file_destination($destination, $replace);
|
||||
if ($destination === FALSE) {
|
||||
drupal_set_message(t('The file %file could not be copied because a file by that name already exists in the destination directory.', array('%file' => $original_source)), 'error');
|
||||
watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%destination' => $destination));
|
||||
watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%directory' => $destination));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1113,7 +1161,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)) {
|
||||
$whitelist = array_unique(explode(' ', trim($extensions)));
|
||||
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
|
||||
$filename = str_replace(chr(0), '', $filename);
|
||||
|
||||
$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.
|
||||
@@ -1126,7 +1177,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 .= '_';
|
||||
}
|
||||
}
|
||||
@@ -1258,6 +1309,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;
|
||||
@@ -1367,8 +1419,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.
|
||||
@@ -1379,9 +1432,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.
|
||||
@@ -1399,45 +1452,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;
|
||||
}
|
||||
|
||||
@@ -1445,10 +1498,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'])) {
|
||||
@@ -1505,7 +1558,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 .= '/';
|
||||
@@ -1514,11 +1567,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.
|
||||
@@ -1533,7 +1586,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;
|
||||
}
|
||||
|
||||
@@ -1541,8 +1594,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;
|
||||
}
|
||||
@@ -1561,8 +1614,22 @@ 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)) {
|
||||
// Track non-public files in the session if they were uploaded by an
|
||||
// anonymous user. This allows modules such as the File module to only
|
||||
// grant view access to the specific anonymous user who uploaded the file.
|
||||
// See file_file_download().
|
||||
// The 'file_public_schema' variable is used to allow other publicly
|
||||
// accessible file schemes to be treated the same as the public:// scheme
|
||||
// provided by Drupal core and to avoid adding unnecessary data to the
|
||||
// session (and the resulting bypass of the page cache) in those cases. For
|
||||
// security reasons, only schemes that are completely publicly accessible,
|
||||
// with no download restrictions, should be added to this variable. See
|
||||
// file_managed_file_value().
|
||||
if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) {
|
||||
$_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid;
|
||||
}
|
||||
// Add file to the cache.
|
||||
$upload_cache[$source] = $file;
|
||||
$upload_cache[$form_field_name] = $file;
|
||||
return $file;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1688,8 +1755,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
|
||||
@@ -1707,20 +1772,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;
|
||||
}
|
||||
|
||||
@@ -1749,7 +1811,7 @@ function file_validate_is_image(stdClass $file) {
|
||||
/**
|
||||
* Verifies that image dimensions are within the specified maximum and minimum.
|
||||
*
|
||||
* Non-image files will be ignored. If a image toolkit is available the image
|
||||
* Non-image files will be ignored. If an image toolkit is available the image
|
||||
* will be scaled to fit within the desired maximum dimensions.
|
||||
*
|
||||
* @param $file
|
||||
@@ -1958,23 +2020,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);
|
||||
}
|
||||
@@ -1986,6 +2032,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.
|
||||
@@ -2179,7 +2288,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.
|
||||
@@ -2201,29 +2310,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
|
||||
@@ -2236,7 +2337,7 @@ function drupal_realpath($uri) {
|
||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {
|
||||
return $wrapper->realpath();
|
||||
}
|
||||
// Check that the uri has a value. There is a bug in PHP 5.2 on *BSD systems
|
||||
// Check that the URI has a value. There is a bug in PHP 5.2 on *BSD systems
|
||||
// that makes realpath not return FALSE as expected when passing an empty
|
||||
// variable.
|
||||
// @todo Remove when Drupal drops support for PHP 5.2.
|
||||
@@ -2320,7 +2421,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.
|
||||
@@ -2351,7 +2452,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.
|
||||
@@ -2476,22 +2577,11 @@ function file_directory_temp() {
|
||||
* An associative array of headers, as expected by file_transfer().
|
||||
*/
|
||||
function file_get_content_headers($file) {
|
||||
$name = mime_header_encode($file->filename);
|
||||
$type = mime_header_encode($file->filemime);
|
||||
// Serve images, text, and flash content for display rather than download.
|
||||
$inline_types = variable_get('file_inline_types', array('^text/', '^image/', 'flash$'));
|
||||
$disposition = 'attachment';
|
||||
foreach ($inline_types as $inline_type) {
|
||||
// Exclamation marks are used as delimiters to avoid escaping slashes.
|
||||
if (preg_match('!' . $inline_type . '!', $file->filemime)) {
|
||||
$disposition = 'inline';
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'Content-Type' => $type . '; name="' . $name . '"',
|
||||
'Content-Type' => $type,
|
||||
'Content-Length' => $file->filesize,
|
||||
'Content-Disposition' => $disposition . '; filename="' . $name . '"',
|
||||
'Cache-Control' => 'private',
|
||||
);
|
||||
}
|
||||
|
||||
Regular → Executable
+20
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Regular → Executable
+11
-1
@@ -381,7 +381,7 @@ interface FileTransferChmodInterface {
|
||||
* @param string $path
|
||||
* Path to change permissions of.
|
||||
* @param long $mode
|
||||
* @see http://php.net/chmod
|
||||
* The new file permission mode to be passed to chmod().
|
||||
* @param boolean $recursive
|
||||
* Pass TRUE to recursively chmod the entire directory specified in $path.
|
||||
*/
|
||||
@@ -406,10 +406,20 @@ class SkipDotsRecursiveDirectoryIterator extends RecursiveDirectoryIterator {
|
||||
*/
|
||||
function __construct($path) {
|
||||
parent::__construct($path);
|
||||
$this->skipdots();
|
||||
}
|
||||
|
||||
function rewind() {
|
||||
parent::rewind();
|
||||
$this->skipdots();
|
||||
}
|
||||
|
||||
function next() {
|
||||
parent::next();
|
||||
$this->skipdots();
|
||||
}
|
||||
|
||||
protected function skipdots() {
|
||||
while ($this->isDot()) {
|
||||
parent::next();
|
||||
}
|
||||
|
||||
Regular → Executable
+3
-3
@@ -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);
|
||||
|
||||
Regular → Executable
Regular → Executable
+4
-2
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
+333
-121
@@ -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()
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@@ -78,7 +77,7 @@
|
||||
* the elements and properties of the form. For information on the array
|
||||
* components and format, and more detailed explanations of the Form API
|
||||
* workflow, see the
|
||||
* @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html Form API reference @endlink
|
||||
* @link forms_api_reference.html Form API reference @endlink
|
||||
* and the
|
||||
* @link http://drupal.org/node/37775 Form API documentation section. @endlink
|
||||
* In addition, there is a set of Form API tutorials in
|
||||
@@ -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
|
||||
@@ -215,17 +221,15 @@ function drupal_get_form($form_id) {
|
||||
* set.
|
||||
* - values: An associative array of values submitted to the form. The
|
||||
* validation functions and submit functions use this array for nearly all
|
||||
* their decision making. (Note that
|
||||
* @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7#tree #tree @endlink
|
||||
* determines whether the values are a flat array or an array whose
|
||||
* structure parallels the $form array.)
|
||||
* - input: The array of values as they were submitted by the user. These are
|
||||
* raw and unvalidated, so should not be used without a thorough
|
||||
* understanding of security implications. In almost all cases, code should
|
||||
* use the data in the 'values' array exclusively. The most common use of
|
||||
* this key is for multi-step forms that need to clear some of the user
|
||||
* input when setting 'rebuild'. The values correspond to $_POST or $_GET,
|
||||
* depending on the 'method' chosen.
|
||||
* their decision making. (Note that #tree determines whether the values are
|
||||
* a flat array or an array whose structure parallels the $form array. See
|
||||
* @link forms_api_reference.html Form API reference @endlink for more
|
||||
* information.) These are raw and unvalidated, so should not be used
|
||||
* without a thorough understanding of security implications. In almost all
|
||||
* cases, code should use the data in the 'values' array exclusively. The
|
||||
* most common use of this key is for multi-step forms that need to clear
|
||||
* some of the user input when setting 'rebuild'. The values correspond to
|
||||
* $_POST or $_GET, depending on the 'method' chosen.
|
||||
* - always_process: If TRUE and the method is GET, a form_id is not
|
||||
* necessary. This should only be used on RESTful GET forms that do NOT
|
||||
* write data, as this could lead to security issues. It is useful so that
|
||||
@@ -237,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
|
||||
@@ -404,6 +414,7 @@ function form_state_defaults() {
|
||||
'submitted' => FALSE,
|
||||
'executed' => FALSE,
|
||||
'programmed' => FALSE,
|
||||
'programmed_bypass_access_check' => TRUE,
|
||||
'cache'=> FALSE,
|
||||
'method' => 'post',
|
||||
'groups' => array(),
|
||||
@@ -454,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
|
||||
@@ -518,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;
|
||||
}
|
||||
}
|
||||
@@ -530,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);
|
||||
}
|
||||
@@ -729,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 at installation time.
|
||||
// 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'])) {
|
||||
@@ -768,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.
|
||||
@@ -789,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;
|
||||
@@ -852,7 +894,10 @@ function drupal_process_form($form_id, &$form, &$form_state) {
|
||||
// cache when a form is processed, so scenarios that result in
|
||||
// the form being built behind the scenes and again for the
|
||||
// browser don't increment all the element IDs needlessly.
|
||||
drupal_static_reset('drupal_html_id');
|
||||
if (!form_get_errors()) {
|
||||
// In case of errors, do not break HTML IDs of other forms.
|
||||
drupal_static_reset('drupal_html_id');
|
||||
}
|
||||
|
||||
if ($form_state['submitted'] && !form_get_errors() && !$form_state['rebuild']) {
|
||||
// Execute form submit handlers.
|
||||
@@ -894,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.
|
||||
@@ -975,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',
|
||||
@@ -1084,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.
|
||||
@@ -1118,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.
|
||||
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)));
|
||||
// matches the current user's session. This is duplicate to code in
|
||||
// form_builder() but left to protect any custom form handling code.
|
||||
if (!empty($form['#token'])) {
|
||||
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token']) || !empty($form_state['invalid_token'])) {
|
||||
_drupal_invalid_token_set_form_error();
|
||||
// Stop here and don't run any further validation handlers, because they
|
||||
// could invoke non-safe operations which opens the door for CSRF
|
||||
// vulnerabilities.
|
||||
$validated_forms[$form_id] = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,18 +1234,23 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
|
||||
/**
|
||||
* Redirects the user to a URL after a form has been processed.
|
||||
*
|
||||
* After a form was executed, the data in $form_state controls whether the form
|
||||
* is redirected. By default, we redirect to a new destination page. The path
|
||||
* of the destination page can be set in $form_state['redirect'], as either a
|
||||
* string containing the destination or an array of arguments compatible with
|
||||
* drupal_goto(). If that is not set, the user is redirected to the current
|
||||
* page to display a fresh, unpopulated copy of the form.
|
||||
* After a form is submitted and processed, normally the user should be
|
||||
* redirected to a new destination page. This function figures out what that
|
||||
* destination should be, based on the $form_state array and the 'destination'
|
||||
* query string in the request URL, and redirects the user there.
|
||||
*
|
||||
* For example, to redirect to 'node':
|
||||
* Usually (for exceptions, see below) $form_state['redirect'] determines where
|
||||
* to redirect the user. This can be set either to a string (the path to
|
||||
* redirect to), or an array of arguments for drupal_goto(). If
|
||||
* $form_state['redirect'] is missing, the user is usually (again, see below for
|
||||
* exceptions) redirected back to the page they came from, where they should see
|
||||
* a fresh, unpopulated copy of the form.
|
||||
*
|
||||
* Here is an example of how to set up a form to redirect to the path 'node':
|
||||
* @code
|
||||
* $form_state['redirect'] = 'node';
|
||||
* @endcode
|
||||
* Or to redirect to 'node/123?foo=bar#baz':
|
||||
* And here is an example of how to redirect to 'node/123?foo=bar#baz':
|
||||
* @code
|
||||
* $form_state['redirect'] = array(
|
||||
* 'node/123',
|
||||
@@ -1201,29 +1263,27 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* There are several triggers that may prevent a redirection though:
|
||||
* - If $form_state['redirect'] is FALSE, a form builder function or form
|
||||
* validation/submit handler does not want a user to be redirected, which
|
||||
* means that drupal_goto() is not invoked. For most forms, the redirection
|
||||
* logic will be the same regardless of whether $form_state['redirect'] is
|
||||
* undefined or FALSE. However, in case it was not defined and the current
|
||||
* request contains a 'destination' query string, drupal_goto() will redirect
|
||||
* to that given destination instead. Only setting $form_state['redirect'] to
|
||||
* FALSE will prevent any redirection.
|
||||
* - If $form_state['no_redirect'] is TRUE, then the callback that originally
|
||||
* built the form explicitly disallows any redirection, regardless of the
|
||||
* redirection value in $form_state['redirect']. For example, ajax_get_form()
|
||||
* defines $form_state['no_redirect'] when building a form in an Ajax
|
||||
* callback to prevent any redirection. $form_state['no_redirect'] should NOT
|
||||
* be altered by form builder functions or form validation/submit handlers.
|
||||
* There are several exceptions to the "usual" behavior described above:
|
||||
* - If $form_state['programmed'] is TRUE, the form submission was usually
|
||||
* invoked via drupal_form_submit(), so any redirection would break the script
|
||||
* that invoked drupal_form_submit().
|
||||
* - If $form_state['rebuild'] is TRUE, the form needs to be rebuilt without
|
||||
* redirection.
|
||||
* that invoked drupal_form_submit() and no redirection is done.
|
||||
* - If $form_state['rebuild'] is TRUE, the form is being rebuilt, and no
|
||||
* redirection is done.
|
||||
* - If $form_state['no_redirect'] is TRUE, redirection is disabled. This is
|
||||
* set, for instance, by ajax_get_form() to prevent redirection in Ajax
|
||||
* callbacks. $form_state['no_redirect'] should never be set or altered by
|
||||
* form builder functions or form validation/submit handlers.
|
||||
* - If $form_state['redirect'] is set to FALSE, redirection is disabled.
|
||||
* - If none of the above conditions has prevented redirection, then the
|
||||
* redirect is accomplished by calling drupal_goto(), passing in the value of
|
||||
* $form_state['redirect'] if it is set, or the current path if it is
|
||||
* not. drupal_goto() preferentially uses the value of $_GET['destination']
|
||||
* (the 'destination' URL query string) if it is present, so this will
|
||||
* override any values set by $form_state['redirect']. Note that during
|
||||
* installation, install_goto() is called in place of drupal_goto().
|
||||
*
|
||||
* @param $form_state
|
||||
* A keyed array containing the current state of the form.
|
||||
* An associative array containing the current state of the form.
|
||||
*
|
||||
* @see drupal_process_form()
|
||||
* @see drupal_build_form()
|
||||
@@ -1255,7 +1315,7 @@ function drupal_redirect_form($form_state) {
|
||||
$function($form_state['redirect']);
|
||||
}
|
||||
}
|
||||
drupal_goto($_GET['q']);
|
||||
drupal_goto(current_path(), array('query' => drupal_get_query_parameters()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1774,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 (!empty($element['#token'])) {
|
||||
if (empty($form_state['input']['form_token']) || !drupal_valid_token($form_state['input']['form_token'], $element['#token'])) {
|
||||
// Set an early form error to block certain input processing since that
|
||||
// opens the door for CSRF vulnerabilities.
|
||||
_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;
|
||||
@@ -1877,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
|
||||
@@ -1925,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;
|
||||
@@ -1974,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)) {
|
||||
@@ -2003,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;
|
||||
@@ -2398,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2441,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.
|
||||
*
|
||||
@@ -2456,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,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).
|
||||
@@ -2646,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)) {
|
||||
@@ -2669,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>';
|
||||
}
|
||||
@@ -2862,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.'));
|
||||
}
|
||||
@@ -3047,14 +3214,12 @@ 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
|
||||
*/
|
||||
function theme_checkbox($variables) {
|
||||
$element = $variables['element'];
|
||||
$t = get_t();
|
||||
$element['#attributes']['type'] = 'checkbox';
|
||||
element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
|
||||
|
||||
@@ -3221,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:
|
||||
@@ -3234,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'])) {
|
||||
@@ -3251,21 +3421,6 @@ function theme_container($variables) {
|
||||
/**
|
||||
* Returns HTML for a table with radio buttons or checkboxes.
|
||||
*
|
||||
* An example of per-row options:
|
||||
* @code
|
||||
* $options = array();
|
||||
* $options[0]['title'] = "A red row"
|
||||
* $options[0]['#attributes'] = array ('class' => array('red-row'));
|
||||
* $options[1]['title'] = "A blue row"
|
||||
* $options[1]['#attributes'] = array ('class' => array('blue-row'));
|
||||
*
|
||||
* $form['myselector'] = array (
|
||||
* '#type' => 'tableselect',
|
||||
* '#title' => 'My Selector'
|
||||
* '#options' => $options,
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - element: An associative array containing the properties and children of
|
||||
@@ -3273,7 +3428,35 @@ function theme_container($variables) {
|
||||
* and #js_select. The #options property is an array of selection options;
|
||||
* each array element of #options is an array of properties. These
|
||||
* properties can include #attributes, which is added to the
|
||||
* table row's HTML attributes; see theme_table().
|
||||
* table row's HTML attributes; see theme_table(). An example of per-row
|
||||
* options:
|
||||
* @code
|
||||
* $options = array(
|
||||
* array(
|
||||
* 'title' => 'How to Learn Drupal',
|
||||
* 'content_type' => 'Article',
|
||||
* 'status' => 'published',
|
||||
* '#attributes' => array('class' => array('article-row')),
|
||||
* ),
|
||||
* array(
|
||||
* 'title' => 'Privacy Policy',
|
||||
* 'content_type' => 'Page',
|
||||
* 'status' => 'published',
|
||||
* '#attributes' => array('class' => array('page-row')),
|
||||
* ),
|
||||
* );
|
||||
* $header = array(
|
||||
* 'title' => t('Title'),
|
||||
* 'content_type' => t('Content type'),
|
||||
* 'status' => t('Status'),
|
||||
* );
|
||||
* $form['table'] = array(
|
||||
* '#type' => 'tableselect',
|
||||
* '#header' => $header,
|
||||
* '#options' => $options,
|
||||
* '#empty' => t('No content available.'),
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
@@ -3363,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 {
|
||||
@@ -3783,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.
|
||||
*
|
||||
@@ -3801,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) . ' />';
|
||||
@@ -3993,8 +4205,6 @@ function theme_file($variables) {
|
||||
*/
|
||||
function theme_form_element($variables) {
|
||||
$element = &$variables['element'];
|
||||
// This is also used in the installer, pre-database setup.
|
||||
$t = get_t();
|
||||
|
||||
// This function is invoked as theme wrapper, but the rendered form element
|
||||
// may not necessarily have been processed by form_builder().
|
||||
@@ -4153,7 +4363,7 @@ function _form_set_class(&$element, $class = array()) {
|
||||
if (!empty($element['#required'])) {
|
||||
$element['#attributes']['class'][] = 'required';
|
||||
}
|
||||
if (isset($element['#parents']) && form_get_error($element)) {
|
||||
if (isset($element['#parents']) && form_get_error($element) !== NULL && !empty($element['#validated'])) {
|
||||
$element['#attributes']['class'][] = 'error';
|
||||
}
|
||||
}
|
||||
@@ -4230,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) {
|
||||
@@ -4282,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) {
|
||||
@@ -4321,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
|
||||
@@ -4338,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
|
||||
@@ -4363,7 +4575,7 @@ function batch_set($batch_definition) {
|
||||
}
|
||||
|
||||
// Base and default properties for the batch set.
|
||||
// Use get_t() to allow batches at install time.
|
||||
// Use get_t() to allow batches during installation.
|
||||
$t = get_t();
|
||||
$init = array(
|
||||
'sandbox' => array(),
|
||||
|
||||
Regular → Executable
Regular → Executable
+13
-14
@@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return a list of available toolkits.
|
||||
* Gets a list of available toolkits.
|
||||
*
|
||||
* @return
|
||||
* An array with the toolkit names as keys and the descriptions as values.
|
||||
@@ -55,7 +55,7 @@ function image_get_available_toolkits() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of the currently used toolkit.
|
||||
* Gets the name of the currently used toolkit.
|
||||
*
|
||||
* @return
|
||||
* String containing the name of the selected toolkit, or FALSE on error.
|
||||
@@ -101,7 +101,7 @@ function image_toolkit_invoke($method, stdClass $image, array $params = array())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details about an image.
|
||||
* Gets details about an image.
|
||||
*
|
||||
* Drupal supports GIF, JPG and PNG file formats when used with the GD
|
||||
* toolkit, and may support others, depending on which toolkits are
|
||||
@@ -233,11 +233,11 @@ function image_dimensions_scale(array &$dimensions, $width = NULL, $height = NUL
|
||||
* @param $image
|
||||
* An image object returned by image_load().
|
||||
* @param $width
|
||||
* The target width, in pixels. This value is omitted then the scaling will
|
||||
* based only on the height value.
|
||||
* The target width, in pixels. If this value is NULL then the scaling will
|
||||
* be based only on the height value.
|
||||
* @param $height
|
||||
* The target height, in pixels. This value is omitted then the scaling will
|
||||
* based only on the width value.
|
||||
* The target height, in pixels. If this value is NULL then the scaling will
|
||||
* be based only on the width value.
|
||||
* @param $upscale
|
||||
* Boolean indicating that files smaller than the dimensions will be scaled
|
||||
* up. This generally results in a low quality image.
|
||||
@@ -261,7 +261,7 @@ function image_scale(stdClass $image, $width = NULL, $height = NULL, $upscale =
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an image to the given dimensions (ignoring aspect ratio).
|
||||
* Resizes an image to the given dimensions (ignoring aspect ratio).
|
||||
*
|
||||
* @param $image
|
||||
* An image object returned by image_load().
|
||||
@@ -284,7 +284,7 @@ function image_resize(stdClass $image, $width, $height) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate an image by the given number of degrees.
|
||||
* Rotates an image by the given number of degrees.
|
||||
*
|
||||
* @param $image
|
||||
* An image object returned by image_load().
|
||||
@@ -308,7 +308,7 @@ function image_rotate(stdClass $image, $degrees, $background = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Crop an image to the rectangle specified by the given rectangle.
|
||||
* Crops an image to a rectangle specified by the given dimensions.
|
||||
*
|
||||
* @param $image
|
||||
* An image object returned by image_load().
|
||||
@@ -340,7 +340,7 @@ function image_crop(stdClass $image, $x, $y, $width, $height) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an image to grayscale.
|
||||
* Converts an image to grayscale.
|
||||
*
|
||||
* @param $image
|
||||
* An image object returned by image_load().
|
||||
@@ -355,9 +355,8 @@ function image_desaturate(stdClass $image) {
|
||||
return image_toolkit_invoke('desaturate', $image);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load an image file and return an image object.
|
||||
* Loads an image file and returns an image object.
|
||||
*
|
||||
* Any changes to the file are not saved until image_save() is called.
|
||||
*
|
||||
@@ -400,7 +399,7 @@ function image_load($file, $toolkit = FALSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the image and save the changes to a file.
|
||||
* Closes the image and saves the changes to a file.
|
||||
*
|
||||
* @param $image
|
||||
* An image object returned by image_load(). The object's 'info' property
|
||||
|
||||
Regular → Executable
+133
-48
@@ -6,8 +6,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Global flag to indicate that a task should not be run during the current
|
||||
* installation request.
|
||||
* Do not run the task during the current installation request.
|
||||
*
|
||||
* This can be used to skip running an installation task when certain
|
||||
* conditions are met, even though the task may still show on the list of
|
||||
@@ -20,8 +19,7 @@
|
||||
define('INSTALL_TASK_SKIP', 1);
|
||||
|
||||
/**
|
||||
* Global flag to indicate that a task should be run on each installation
|
||||
* request that reaches it.
|
||||
* Run the task on each installation request until the database is set up.
|
||||
*
|
||||
* This is primarily used by the Drupal installer for bootstrap-related tasks.
|
||||
*/
|
||||
@@ -200,7 +198,7 @@ function install_state_defaults() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin an installation request, modifying the installation state as needed.
|
||||
* Begins an installation request, modifying the installation state as needed.
|
||||
*
|
||||
* This function performs commands that must run at the beginning of every page
|
||||
* request. It throws an exception if the installation should not proceed.
|
||||
@@ -295,12 +293,11 @@ function install_begin_request(&$install_state) {
|
||||
else {
|
||||
$task = NULL;
|
||||
|
||||
// Since previous versions of Drupal stored database connection information
|
||||
// in the 'db_url' variable, we should never let an installation proceed if
|
||||
// this variable is defined and the settings file was not verified above
|
||||
// (otherwise we risk installing over an existing site whose settings file
|
||||
// has not yet been updated).
|
||||
if (!empty($GLOBALS['db_url'])) {
|
||||
// Do not install over a configured settings.php. Check the 'db_url'
|
||||
// variable in addition to 'databases', since previous versions of Drupal
|
||||
// used that (and we do not want to allow installations on an existing site
|
||||
// whose settings file has not yet been updated).
|
||||
if (!empty($GLOBALS['databases']) || !empty($GLOBALS['db_url'])) {
|
||||
throw new Exception(install_already_done_error());
|
||||
}
|
||||
}
|
||||
@@ -365,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.
|
||||
@@ -481,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.
|
||||
@@ -525,7 +527,7 @@ function install_tasks($install_state) {
|
||||
$needs_translations = count($install_state['locales']) > 1 && !empty($install_state['parameters']['locale']) && $install_state['parameters']['locale'] != 'en';
|
||||
|
||||
// Start with the core installation tasks that run before handing control
|
||||
// to the install profile.
|
||||
// to the installation profile.
|
||||
$tasks = array(
|
||||
'install_select_profile' => array(
|
||||
'display_name' => st('Choose profile'),
|
||||
@@ -695,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.
|
||||
@@ -709,7 +726,7 @@ function install_display_output($output, $install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; verify the requirements for installing Drupal.
|
||||
* Verifies the requirements for installing Drupal.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
@@ -769,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);
|
||||
@@ -777,16 +803,23 @@ function install_system_module(&$install_state) {
|
||||
// variable_set() can be used now that system.module is installed.
|
||||
$modules = $install_state['profile_info']['dependencies'];
|
||||
|
||||
// The install profile is also a module, which needs to be installed
|
||||
// The installation profile is also a module, which needs to be installed
|
||||
// after all the dependencies have been installed.
|
||||
$modules[] = drupal_get_profile();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify and return the last installation task that was completed.
|
||||
* Verifies and returns the last installation task that was completed.
|
||||
*
|
||||
* @return
|
||||
* The last completed task, if there is one. An exception is thrown if Drupal
|
||||
@@ -830,7 +863,7 @@ function install_verify_settings() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify PDO library.
|
||||
* Verifies the PDO library.
|
||||
*/
|
||||
function install_verify_pdo() {
|
||||
// PDO was moved to PHP core in 5.2.0, but the old extension (targeting 5.0
|
||||
@@ -842,15 +875,14 @@ function install_verify_pdo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; define a form to configure and rewrite settings.php.
|
||||
* Form constructor for a form to configure and rewrite settings.php.
|
||||
*
|
||||
* @param $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @return
|
||||
* The form API definition for the database configuration form.
|
||||
* @see install_settings_form_validate()
|
||||
* @see install_settings_form_submit()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function install_settings_form($form, &$form_state, &$install_state) {
|
||||
global $databases;
|
||||
@@ -913,7 +945,9 @@ function install_settings_form($form, &$form_state, &$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API validate for install_settings form.
|
||||
* Form validation handler for install_settings_form().
|
||||
*
|
||||
* @see install_settings_form_submit()
|
||||
*/
|
||||
function install_settings_form_validate($form, &$form_state) {
|
||||
$driver = $form_state['values']['driver'];
|
||||
@@ -970,7 +1004,9 @@ function install_database_errors($database, $settings_file) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API submit for install_settings form.
|
||||
* Form submission handler for install_settings_form().
|
||||
*
|
||||
* @see install_settings_form_validate()
|
||||
*/
|
||||
function install_settings_form_submit($form, &$form_state) {
|
||||
global $install_state;
|
||||
@@ -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);
|
||||
@@ -1001,7 +1037,7 @@ function install_find_profiles() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; select which profile to install.
|
||||
* Selects which profile to install.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state. The chosen
|
||||
@@ -1041,8 +1077,21 @@ function install_select_profile(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for automatically selecting an installation profile from a
|
||||
* list or from a selection passed in via $_POST.
|
||||
* Selects an installation profile.
|
||||
*
|
||||
* A profile will be selected if:
|
||||
* - Only one profile is available,
|
||||
* - A profile was submitted through $_POST,
|
||||
* - Exactly one of the profiles is marked as "exclusive".
|
||||
* If multiple profiles are marked as "exclusive" then no profile will be
|
||||
* selected.
|
||||
*
|
||||
* @param array $profiles
|
||||
* An associative array of profiles with the machine-readable names as keys.
|
||||
*
|
||||
* @return
|
||||
* The machine-readable name of the selected profile or NULL if no profile was
|
||||
* selected.
|
||||
*/
|
||||
function _install_select_profile($profiles) {
|
||||
if (sizeof($profiles) == 0) {
|
||||
@@ -1062,15 +1111,34 @@ function _install_select_profile($profiles) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for a profile marked as "exclusive" and ensure that only one
|
||||
// profile is marked as such.
|
||||
$exclusive_profile = NULL;
|
||||
foreach ($profiles as $profile) {
|
||||
$profile_info = install_profile_info($profile->name);
|
||||
if (!empty($profile_info['exclusive'])) {
|
||||
if (empty($exclusive_profile)) {
|
||||
$exclusive_profile = $profile->name;
|
||||
}
|
||||
else {
|
||||
// We found a second "exclusive" profile. There's no way to choose
|
||||
// between them, so we ignore the property.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $exclusive_profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API array definition for the profile selection form.
|
||||
* Form constructor for the profile selection form.
|
||||
*
|
||||
* @param $form_state
|
||||
* Array of metadata about state of form processing.
|
||||
* @param $profile_files
|
||||
* Array of .profile files, as returned from file_scan_directory().
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function install_select_profile_form($form, &$form_state, $profile_files) {
|
||||
$profiles = array();
|
||||
@@ -1247,7 +1315,9 @@ function install_select_locale(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API array definition for language selection.
|
||||
* Form constructor for the language selection form.
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function install_select_locale_form($form, &$form_state, $locales, $profilename) {
|
||||
include_once DRUPAL_ROOT . '/includes/iso.inc';
|
||||
@@ -1297,7 +1367,7 @@ function install_already_done_error() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; load information about the chosen profile.
|
||||
* Loads information about the chosen profile during installation.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state. The loaded
|
||||
@@ -1316,7 +1386,7 @@ function install_load_profile(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; perform a full bootstrap of Drupal.
|
||||
* Performs a full bootstrap of Drupal during installation.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
@@ -1326,7 +1396,7 @@ function install_bootstrap_full(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; install required modules via a batch process.
|
||||
* Installs required modules via a batch process.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
@@ -1379,7 +1449,7 @@ function install_profile_modules(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; import languages via a batch process.
|
||||
* Imports languages via a batch process during installation.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
@@ -1413,15 +1483,14 @@ function install_import_locales(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; configure settings for the new site.
|
||||
* Form constructor for a form to configure the new site.
|
||||
*
|
||||
* @param $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @return
|
||||
* The form API definition for the site configuration form.
|
||||
* @see install_configure_form_validate()
|
||||
* @see install_configure_form_submit()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function install_configure_form($form, &$form_state, &$install_state) {
|
||||
drupal_set_title(st('Configure site'));
|
||||
@@ -1444,7 +1513,7 @@ function install_configure_form($form, &$form_state, &$install_state) {
|
||||
// Add JavaScript time zone detection.
|
||||
drupal_add_js('misc/timezone.js');
|
||||
// We add these strings as settings because JavaScript translation does not
|
||||
// work on install time.
|
||||
// work during installation.
|
||||
drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting');
|
||||
drupal_add_js('jQuery(function () { Drupal.cleanURLsInstallCheck(); });', 'inline');
|
||||
// Add JS to show / hide the 'Email administrator about site updates' elements
|
||||
@@ -1487,7 +1556,7 @@ function install_import_locales_remaining(&$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation task; perform final steps and display a 'finished' page.
|
||||
* Finishes importing files at end of installation.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
@@ -1503,13 +1572,13 @@ function install_finished(&$install_state) {
|
||||
|
||||
// Flush all caches to ensure that any full bootstraps during the installer
|
||||
// do not leave stale cached data, and that any content types or other items
|
||||
// registered by the install profile are registered correctly.
|
||||
// registered by the installation profile are registered correctly.
|
||||
drupal_flush_all_caches();
|
||||
|
||||
// Remember the profile which was used.
|
||||
variable_set('install_profile', drupal_get_profile());
|
||||
|
||||
// Install profiles are always loaded last
|
||||
// Installation profiles are always loaded last
|
||||
db_update('system')
|
||||
->fields(array('weight' => 1000))
|
||||
->condition('type', 'module')
|
||||
@@ -1528,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
|
||||
@@ -1541,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) {
|
||||
@@ -1674,7 +1747,15 @@ function install_check_requirements($install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms API array definition for site configuration.
|
||||
* Form constructor for a site configuration form.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @see install_configure_form()
|
||||
* @see install_configure_form_validate()
|
||||
* @see install_configure_form_submit()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function _install_configure_form($form, &$form_state, &$install_state) {
|
||||
include_once DRUPAL_ROOT . '/includes/locale.inc';
|
||||
@@ -1787,7 +1868,9 @@ function _install_configure_form($form, &$form_state, &$install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms API validate for the site configuration form.
|
||||
* Form validation handler for install_configure_form().
|
||||
*
|
||||
* @see install_configure_form_submit()
|
||||
*/
|
||||
function install_configure_form_validate($form, &$form_state) {
|
||||
if ($error = user_validate_name($form_state['values']['account']['name'])) {
|
||||
@@ -1802,7 +1885,9 @@ function install_configure_form_validate($form, &$form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms API submit for the site configuration form.
|
||||
* Form submission handler for install_configure_form().
|
||||
*
|
||||
* @see install_configure_form_validate()
|
||||
*/
|
||||
function install_configure_form_submit($form, &$form_state) {
|
||||
global $user;
|
||||
|
||||
Regular → Executable
+74
-41
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API functions for installing modules and themes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that a module has not been installed yet.
|
||||
*/
|
||||
@@ -71,7 +76,7 @@ define('FILE_NOT_WRITABLE', 64);
|
||||
define('FILE_NOT_EXECUTABLE', 128);
|
||||
|
||||
/**
|
||||
* Initialize the update system by loading all installed module's .install files.
|
||||
* Loads .install files for installed modules to initialize the update system.
|
||||
*/
|
||||
function drupal_load_updates() {
|
||||
foreach (drupal_get_installed_schema_version(NULL, FALSE, TRUE) as $module => $schema_version) {
|
||||
@@ -180,11 +185,11 @@ function drupal_set_installed_schema_version($module, $version) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the install profile, extracting its defined distribution name.
|
||||
* Loads the installation profile, extracting its defined distribution name.
|
||||
*
|
||||
* @return
|
||||
* The distribution name defined in the profile's .info file. Defaults to
|
||||
* "Drupal" if none is explicitly provided by the install profile.
|
||||
* "Drupal" if none is explicitly provided by the installation profile.
|
||||
*
|
||||
* @see install_profile_info()
|
||||
*/
|
||||
@@ -204,11 +209,12 @@ function drupal_install_profile_distribution_name() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto detect the base_url with PHP predefined variables.
|
||||
* Detects the base URL using the PHP $_SERVER variables.
|
||||
*
|
||||
* @param $file
|
||||
* The name of the file calling this function so we can strip it out of
|
||||
* the URI when generating the base_url.
|
||||
*
|
||||
* @return
|
||||
* The auto-detected $base_url that should be configured in settings.php
|
||||
*/
|
||||
@@ -223,7 +229,7 @@ function drupal_detect_baseurl($file = 'install.php') {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect all supported databases that are compiled into PHP.
|
||||
* Detects all supported databases that are compiled into PHP.
|
||||
*
|
||||
* @return
|
||||
* An array of database types compiled into PHP.
|
||||
@@ -239,7 +245,7 @@ function drupal_detect_database_types() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all supported database installer objects that are compiled into PHP.
|
||||
* Returns all supported database installer objects that are compiled into PHP.
|
||||
*
|
||||
* @return
|
||||
* An array of database installer objects compiled into PHP.
|
||||
@@ -414,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);
|
||||
}
|
||||
}
|
||||
@@ -576,7 +582,7 @@ class DatabaseTaskException extends Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace values in settings.php with values in the submitted array.
|
||||
* Replaces values in settings.php with values in the submitted array.
|
||||
*
|
||||
* @param $settings
|
||||
* An array of settings that need to be updated.
|
||||
@@ -647,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)));
|
||||
@@ -654,10 +667,11 @@ function drupal_rewrite_settings($settings = array(), $prefix = '') {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an install profile for installation.
|
||||
* Verifies an installation profile for installation.
|
||||
*
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @return
|
||||
* The list of modules to install.
|
||||
*/
|
||||
@@ -681,8 +695,8 @@ function drupal_verify_profile($install_state) {
|
||||
$present_modules[] = $present_module->name;
|
||||
}
|
||||
|
||||
// The install profile is also a module, which needs to be installed after all the other dependencies
|
||||
// have been installed.
|
||||
// The installation profile is also a module, which needs to be installed
|
||||
// after all the other dependencies have been installed.
|
||||
$present_modules[] = drupal_get_profile();
|
||||
|
||||
// Verify that all of the profile's required modules are present.
|
||||
@@ -706,7 +720,7 @@ function drupal_verify_profile($install_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to install the system module.
|
||||
* Installs the system module.
|
||||
*
|
||||
* Separated from the installation of other modules so core system
|
||||
* functions can be made available while other modules are installed.
|
||||
@@ -734,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) {
|
||||
@@ -759,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;
|
||||
}
|
||||
@@ -792,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);
|
||||
}
|
||||
|
||||
@@ -800,7 +822,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the state of the specified file.
|
||||
* Verifies the state of the specified file.
|
||||
*
|
||||
* @param $file
|
||||
* The file to check for.
|
||||
@@ -808,6 +830,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
* An optional bitmask created from various FILE_* constants.
|
||||
* @param $type
|
||||
* The type of file. Can be file (default), dir, or link.
|
||||
*
|
||||
* @return
|
||||
* TRUE on success or FALSE on failure. A message is set for the latter.
|
||||
*/
|
||||
@@ -879,7 +902,7 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory with specified permissions.
|
||||
* Creates a directory with the specified permissions.
|
||||
*
|
||||
* @param $file
|
||||
* The name of the directory to create;
|
||||
@@ -887,6 +910,7 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
|
||||
* The permissions of the directory to create.
|
||||
* @param $message
|
||||
* (optional) Whether to output messages. Defaults to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE/FALSE whether or not the directory was successfully created.
|
||||
*/
|
||||
@@ -918,7 +942,7 @@ function drupal_install_mkdir($file, $mask, $message = TRUE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to fix file permissions.
|
||||
* Attempts to fix file permissions.
|
||||
*
|
||||
* The general approach here is that, because we do not know the security
|
||||
* setup of the webserver, we apply our permission changes to all three
|
||||
@@ -935,6 +959,7 @@ function drupal_install_mkdir($file, $mask, $message = TRUE) {
|
||||
* The desired permissions for the file.
|
||||
* @param $message
|
||||
* (optional) Whether to output messages. Defaults to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE/FALSE whether or not we were able to fix the file's permissions.
|
||||
*/
|
||||
@@ -1000,7 +1025,7 @@ function drupal_install_fix_file($file, $mask, $message = TRUE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the user to a different installer page.
|
||||
* Sends the user to a different installer page.
|
||||
*
|
||||
* This issues an on-site HTTP redirect. Messages (and errors) are erased.
|
||||
*
|
||||
@@ -1078,7 +1103,7 @@ function drupal_requirements_url($severity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional equivalent of t(), used when some systems are not available.
|
||||
* Translates a string when some systems are not available.
|
||||
*
|
||||
* Used during the install process, when database, theme, and localization
|
||||
* system is possibly not yet available.
|
||||
@@ -1117,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]) {
|
||||
@@ -1138,12 +1162,12 @@ function st($string, array $args = array(), array $options = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an install profile's requirements.
|
||||
* Checks an installation profile's requirements.
|
||||
*
|
||||
* @param $profile
|
||||
* Name of install profile to check.
|
||||
* Name of installation profile to check.
|
||||
* @return
|
||||
* Array of the install profile's requirements.
|
||||
* Array of the installation profile's requirements.
|
||||
*/
|
||||
function drupal_check_profile($profile) {
|
||||
include_once DRUPAL_ROOT . '/includes/file.inc';
|
||||
@@ -1169,11 +1193,12 @@ function drupal_check_profile($profile) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract highest severity from requirements array.
|
||||
* Extracts the highest severity from the requirements array.
|
||||
*
|
||||
* @param $requirements
|
||||
* An array of requirements, in the same format as is returned by
|
||||
* hook_requirements().
|
||||
*
|
||||
* @return
|
||||
* The highest severity in the array.
|
||||
*/
|
||||
@@ -1188,12 +1213,13 @@ function drupal_requirements_severity(&$requirements) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a module's requirements.
|
||||
* Checks a module's requirements.
|
||||
*
|
||||
* @param $module
|
||||
* Machine name of module to check.
|
||||
*
|
||||
* @return
|
||||
* TRUE/FALSE depending on the requirements are in place.
|
||||
* TRUE or FALSE, depending on whether the requirements are met.
|
||||
*/
|
||||
function drupal_check_module($module) {
|
||||
module_load_install($module);
|
||||
@@ -1218,19 +1244,26 @@ function drupal_check_module($module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve info about an install profile from its .info file.
|
||||
* Retrieves information about an installation profile from its .info file.
|
||||
*
|
||||
* The information stored in a profile .info file is similar to that stored in
|
||||
* a normal Drupal module .info file. For example:
|
||||
* - name: The real name of the install profile for display purposes.
|
||||
* - name: The real name of the installation profile for display purposes.
|
||||
* - description: A brief description of the profile.
|
||||
* - dependencies: An array of shortnames of other modules this install profile requires.
|
||||
* - dependencies: An array of shortnames of other modules that this install
|
||||
* profile requires.
|
||||
*
|
||||
* Additional, less commonly-used information that can appear in a profile.info
|
||||
* file but not in a normal Drupal module .info file includes:
|
||||
* - distribution_name: The name of the Drupal distribution that is being
|
||||
* installed, to be shown throughout the installation process. Defaults to
|
||||
* 'Drupal'.
|
||||
* - exclusive: If the install profile is intended to be the only eligible
|
||||
* choice in a distribution, setting exclusive = TRUE will auto-select it
|
||||
* during installation, and the install profile selection screen will be
|
||||
* skipped. If more than one profile is found where exclusive = TRUE then
|
||||
* this property will have no effect and the profile selection screen will
|
||||
* be shown as normal with all available profiles shown.
|
||||
*
|
||||
* Note that this function does an expensive file system scan to get info file
|
||||
* information for dependencies. If you only need information from the info
|
||||
|
||||
Regular → Executable
+5
-2
@@ -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'),
|
||||
@@ -461,7 +464,7 @@ function _locale_get_predefined_list() {
|
||||
'tt' => array('Tatar', 'Tatarça'),
|
||||
'tw' => array('Twi'),
|
||||
'ty' => array('Tahitian'),
|
||||
'ug' => array('Uighur'),
|
||||
'ug' => array('Uyghur'),
|
||||
'uk' => array('Ukrainian', 'Українська'),
|
||||
'ur' => array('Urdu', /* Left-to-right marker "" */ 'اردو', LANGUAGE_RTL),
|
||||
'uz' => array('Uzbek', "o'zbek"),
|
||||
|
||||
Regular → Executable
Regular → Executable
+151
-44
@@ -2,7 +2,9 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Multiple language handling functionality.
|
||||
* Language Negotiation API.
|
||||
*
|
||||
* @see http://drupal.org/node/1497272
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -11,7 +13,95 @@
|
||||
define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||
|
||||
/**
|
||||
* Return all the defined language types.
|
||||
* @defgroup language_negotiation Language Negotiation API functionality
|
||||
* @{
|
||||
* Functions to customize the language types and the negotiation process.
|
||||
*
|
||||
* The language negotiation API is based on two major concepts:
|
||||
* - Language types: types of translatable data (the types of data that a user
|
||||
* can view or request).
|
||||
* - Language negotiation providers: functions for determining which language to
|
||||
* use to present a particular piece of data to the user.
|
||||
* Both language types and language negotiation providers are customizable.
|
||||
*
|
||||
* Drupal defines three built-in language types:
|
||||
* - Interface language: The page's main language, used to present translated
|
||||
* user interface elements such as titles, labels, help text, and messages.
|
||||
* - Content language: The language used to present content that is available
|
||||
* in more than one language (see
|
||||
* @link field_language Field Language API @endlink for details).
|
||||
* - URL language: The language associated with URLs. When generating a URL,
|
||||
* this value will be used by url() as a default if no explicit preference is
|
||||
* provided.
|
||||
* Modules can define additional language types through
|
||||
* hook_language_types_info(), and alter existing language type definitions
|
||||
* through hook_language_types_info_alter().
|
||||
*
|
||||
* Language types may be configurable or fixed. The language negotiation
|
||||
* providers associated with a configurable language type can be explicitly
|
||||
* set through the user interface. A fixed language type has predetermined
|
||||
* (module-defined) language negotiation settings and, thus, does not appear in
|
||||
* the configuration page. Here is a code snippet that makes the content
|
||||
* language (which by default inherits the interface language's values)
|
||||
* configurable:
|
||||
* @code
|
||||
* function mymodule_language_types_info_alter(&$language_types) {
|
||||
* unset($language_types[LANGUAGE_TYPE_CONTENT]['fixed']);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Every language type can have a different set of language negotiation
|
||||
* providers assigned to it. Different language types often share the same
|
||||
* language negotiation settings, but they can have independent settings if
|
||||
* needed. If two language types are configured the same way, their language
|
||||
* switcher configuration will be functionally identical and the same settings
|
||||
* will act on both language types.
|
||||
*
|
||||
* Drupal defines the following built-in language negotiation providers:
|
||||
* - URL: Determine the language from the URL (path prefix or domain).
|
||||
* - Session: Determine the language from a request/session parameter.
|
||||
* - User: Follow the user's language preference.
|
||||
* - Browser: Determine the language from the browser's language settings.
|
||||
* - Default language: Use the default site language.
|
||||
* Language negotiation providers are simple callback functions that implement a
|
||||
* particular logic to return a language code. For instance, the URL provider
|
||||
* searches for a valid path prefix or domain name in the current request URL.
|
||||
* If a language negotiation provider does not return a valid language code, the
|
||||
* next provider associated to the language type (based on provider weight) is
|
||||
* invoked.
|
||||
*
|
||||
* Modules can define additional language negotiation providers through
|
||||
* hook_language_negotiation_info(), and alter existing providers through
|
||||
* hook_language_negotiation_info_alter(). Here is an example snippet that lets
|
||||
* path prefixes be ignored for administrative paths:
|
||||
* @code
|
||||
* 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']['language'] = 'mymodule_from_url';
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
|
||||
* }
|
||||
*
|
||||
* function mymodule_from_url($languages) {
|
||||
* // Use the core URL language negotiation provider to get a valid language
|
||||
* // code.
|
||||
* module_load_include('language', 'inc', 'language.negotiation');
|
||||
* $langcode = language_from_url($languages);
|
||||
*
|
||||
* // If we are on an administrative path, override with the default language.
|
||||
* if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') {
|
||||
* return language_default()->langcode;
|
||||
* }
|
||||
* return $langcode;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* For more information, see
|
||||
* @link http://drupal.org/node/1497272 Language Negotiation API @endlink
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns all the defined language types.
|
||||
*
|
||||
* @return
|
||||
* An array of language type names. The name will be used as the global
|
||||
@@ -30,11 +120,11 @@ function language_types_info() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only the configurable language types.
|
||||
* Returns only the configurable language types.
|
||||
*
|
||||
* A language type maybe configurable or fixed. A fixed language type is a type
|
||||
* whose negotiation values are unchangeable and defined while defining the
|
||||
* language type itself.
|
||||
* whose language negotiation providers are module-defined and not altered
|
||||
* through the user interface.
|
||||
*
|
||||
* @param $stored
|
||||
* Optional. By default retrieves values from the 'language_types' variable to
|
||||
@@ -68,7 +158,7 @@ function language_types_configurable($stored = TRUE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the given language types.
|
||||
* Disables the given language types.
|
||||
*
|
||||
* @param $types
|
||||
* An array of language types.
|
||||
@@ -122,16 +212,17 @@ function language_types_set() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a language provider is enabled.
|
||||
* Checks whether a language negotiation provider is enabled for a language type.
|
||||
*
|
||||
* This has two possible behaviors:
|
||||
* - If $provider_id is given return its ID if enabled, FALSE otherwise.
|
||||
* - If no ID is passed the first enabled language provider is returned.
|
||||
* - If no ID is passed the first enabled language negotiation provider is
|
||||
* returned.
|
||||
*
|
||||
* @param $type
|
||||
* The language negotiation type.
|
||||
* The language negotiation provider type.
|
||||
* @param $provider_id
|
||||
* The language provider ID.
|
||||
* The language negotiation provider ID.
|
||||
*
|
||||
* @return
|
||||
* The provider ID if it is enabled, FALSE otherwise.
|
||||
@@ -155,14 +246,13 @@ function language_negotiation_get($type, $provider_id = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given language provider is enabled for any configurable language
|
||||
* type.
|
||||
* Checks if the language negotiation provider is enabled for any language type.
|
||||
*
|
||||
* @param $provider_id
|
||||
* The language provider ID.
|
||||
* The language negotiation provider ID.
|
||||
*
|
||||
* @return
|
||||
* TRUE if there is at least one language type for which the give language
|
||||
* TRUE if there is at least one language type for which the given language
|
||||
* provider is enabled, FALSE otherwise.
|
||||
*/
|
||||
function language_negotiation_get_any($provider_id) {
|
||||
@@ -176,7 +266,7 @@ function language_negotiation_get_any($provider_id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the language switch links for the given language.
|
||||
* Returns the language switch links for the given language.
|
||||
*
|
||||
* @param $type
|
||||
* The language negotiation type.
|
||||
@@ -190,6 +280,11 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
$links = FALSE;
|
||||
$negotiation = variable_get("language_negotiation_$type", array());
|
||||
|
||||
// Only get the languages if we have more than one.
|
||||
if (count(language_list()) >= 2) {
|
||||
$language = language_initialize($type);
|
||||
}
|
||||
|
||||
foreach ($negotiation as $id => $provider) {
|
||||
if (isset($provider['callbacks']['switcher'])) {
|
||||
if (isset($provider['file'])) {
|
||||
@@ -199,6 +294,12 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
$callback = $provider['callbacks']['switcher'];
|
||||
$result = $callback($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']['xml:lang'] = $langcode;
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
// Allow modules to provide translations for specific links.
|
||||
drupal_alter('language_switch_links', $result, $type, $path);
|
||||
@@ -212,7 +313,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates language configuration to remove any language provider that is no longer defined.
|
||||
* Removes any unused language negotiation providers from the configuration.
|
||||
*/
|
||||
function language_negotiation_purge() {
|
||||
// Ensure that we are getting the defined language negotiation information. An
|
||||
@@ -235,12 +336,12 @@ function language_negotiation_purge() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a list of language providers.
|
||||
* Saves a list of language negotiation providers.
|
||||
*
|
||||
* @param $type
|
||||
* The language negotiation type.
|
||||
* @param $language_providers
|
||||
* An array of language provider weights keyed by id.
|
||||
* An array of language negotiation provider weights keyed by provider ID.
|
||||
* @see language_provider_weight()
|
||||
*/
|
||||
function language_negotiation_set($type, $language_providers) {
|
||||
@@ -266,7 +367,7 @@ function language_negotiation_set($type, $language_providers) {
|
||||
// If the provider does not express any preference about types, make it
|
||||
// available for any configurable type.
|
||||
$types = array_flip(isset($provider['types']) ? $provider['types'] : $default_types);
|
||||
// Check if the provider is defined and has the right type.
|
||||
// Check whether the provider is defined and has the right type.
|
||||
if (isset($types[$type])) {
|
||||
$provider_data = array();
|
||||
foreach ($provider_fields as $field) {
|
||||
@@ -283,10 +384,10 @@ function language_negotiation_set($type, $language_providers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the defined language providers.
|
||||
* Returns all the defined language negotiation providers.
|
||||
*
|
||||
* @return
|
||||
* An array of language providers.
|
||||
* An array of language negotiation providers.
|
||||
*/
|
||||
function language_negotiation_info() {
|
||||
$language_providers = &drupal_static(__FUNCTION__);
|
||||
@@ -295,7 +396,7 @@ function language_negotiation_info() {
|
||||
// Collect all the module-defined language negotiation providers.
|
||||
$language_providers = module_invoke_all('language_negotiation_info');
|
||||
|
||||
// Add the default language provider.
|
||||
// Add the default language negotiation provider.
|
||||
$language_providers[LANGUAGE_NEGOTIATION_DEFAULT] = array(
|
||||
'callbacks' => array('language' => 'language_from_default'),
|
||||
'weight' => 10,
|
||||
@@ -303,7 +404,7 @@ function language_negotiation_info() {
|
||||
'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->native)),
|
||||
);
|
||||
|
||||
// Let other modules alter the list of language providers.
|
||||
// Let other modules alter the list of language negotiation providers.
|
||||
drupal_alter('language_negotiation_info', $language_providers);
|
||||
}
|
||||
|
||||
@@ -311,16 +412,17 @@ function language_negotiation_info() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function used to cache the language providers results.
|
||||
* Helper function used to cache the language negotiation providers results.
|
||||
*
|
||||
* @param $provider_id
|
||||
* The language provider ID.
|
||||
* The language negotiation provider's identifier.
|
||||
* @param $provider
|
||||
* The language provider to be invoked. If not passed it will be explicitly
|
||||
* loaded through language_negotiation_info().
|
||||
* (optional) An associative array of information about the provider to be
|
||||
* invoked (see hook_language_negotiation_info() for details). If not passed
|
||||
* in, it will be loaded through language_negotiation_info().
|
||||
*
|
||||
* @return
|
||||
* The language provider's return value.
|
||||
* A language object representing the language chosen by the provider.
|
||||
*/
|
||||
function language_provider_invoke($provider_id, $provider = NULL) {
|
||||
$results = &drupal_static(__FUNCTION__);
|
||||
@@ -341,25 +443,26 @@ function language_provider_invoke($provider_id, $provider = NULL) {
|
||||
require_once DRUPAL_ROOT . '/' . $provider['file'];
|
||||
}
|
||||
|
||||
// If the language provider has no cache preference or this is satisfied
|
||||
// we can execute the callback.
|
||||
// If the language negotiation provider has no cache preference or this is
|
||||
// satisfied we can execute the callback.
|
||||
$cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', 0);
|
||||
$callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE;
|
||||
$langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
|
||||
$results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
|
||||
}
|
||||
|
||||
// Since objects are resources we need to return a clone to prevent the
|
||||
// provider cache to be unintentionally altered. The same providers might be
|
||||
// used with different language types based on configuration.
|
||||
// Since objects are resources, we need to return a clone to prevent the
|
||||
// language negotiation provider cache from being unintentionally altered. The
|
||||
// same providers might be used with different language types based on
|
||||
// configuration.
|
||||
return !empty($results[$provider_id]) ? clone($results[$provider_id]) : $results[$provider_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the passed language provider weight or a default value.
|
||||
* Returns the passed language negotiation provider weight or a default value.
|
||||
*
|
||||
* @param $provider
|
||||
* A language provider data structure.
|
||||
* A language negotiation provider data structure.
|
||||
*
|
||||
* @return
|
||||
* A numeric weight.
|
||||
@@ -370,16 +473,16 @@ function language_provider_weight($provider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a language for the given type based on language negotiation settings.
|
||||
* Chooses a language based on language negotiation provider settings.
|
||||
*
|
||||
* @param $type
|
||||
* The language type.
|
||||
* The language type key to find the language for.
|
||||
*
|
||||
* @return
|
||||
* The negotiated language object.
|
||||
*/
|
||||
function language_initialize($type) {
|
||||
// Execute the language providers in the order they were set up and return the
|
||||
// Execute the language negotiation providers in the order they were set up and return the
|
||||
// first valid language found.
|
||||
$negotiation = variable_get("language_negotiation_$type", array());
|
||||
|
||||
@@ -398,7 +501,7 @@ function language_initialize($type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default language provider.
|
||||
* Returns the default language negotiation provider.
|
||||
*
|
||||
* @return
|
||||
* The default language code.
|
||||
@@ -408,10 +511,10 @@ function language_from_default() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the given path into prefix and actual path.
|
||||
* Splits the given path into prefix and actual path.
|
||||
*
|
||||
* Parse the given path and return the language object identified by the
|
||||
* prefix and the actual path.
|
||||
* Parse the given path and return the language object identified by the prefix
|
||||
* and the actual path.
|
||||
*
|
||||
* @param $path
|
||||
* The path to split.
|
||||
@@ -440,10 +543,10 @@ function language_url_split_prefix($path, $languages) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the possible fallback languages ordered by language weight.
|
||||
* Returns the possible fallback languages ordered by language weight.
|
||||
*
|
||||
* @param
|
||||
* The language type.
|
||||
* (optional) The language type. Defaults to LANGUAGE_TYPE_CONTENT.
|
||||
*
|
||||
* @return
|
||||
* An array of language codes.
|
||||
@@ -471,3 +574,7 @@ function language_fallback_get_candidates($type = LANGUAGE_TYPE_CONTENT) {
|
||||
|
||||
return $fallback_candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "language_negotiation"
|
||||
*/
|
||||
|
||||
Regular → Executable
+58
-8
@@ -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.
|
||||
*/
|
||||
|
||||
Regular → Executable
+1
-1
@@ -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).
|
||||
*
|
||||
|
||||
Regular → Executable
+39
-32
@@ -10,10 +10,10 @@
|
||||
*
|
||||
* $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");
|
||||
|
||||
/**
|
||||
* Compose and optionally send an e-mail message.
|
||||
* Composes and optionally sends an e-mail message.
|
||||
*
|
||||
* Sending an e-mail works with defining an e-mail template (subject, text
|
||||
* and possibly e-mail headers) and the replacement values to use in the
|
||||
@@ -93,7 +93,9 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
|
||||
* will be {$module}_{$key}.
|
||||
* @param $to
|
||||
* The e-mail address or addresses where the message will be sent to. The
|
||||
* formatting of this string must comply with RFC 2822. Some examples are:
|
||||
* formatting of this string will be validated with the
|
||||
* @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink
|
||||
* Some examples are:
|
||||
* - user@example.com
|
||||
* - user@example.com, anotheruser@example.com
|
||||
* - User <user@example.com>
|
||||
@@ -191,7 +193,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object that implements the MailSystemInterface.
|
||||
* Returns an object that implements the MailSystemInterface interface.
|
||||
*
|
||||
* Allows for one or more custom mail backends to format and send mail messages
|
||||
* composed using drupal_mail().
|
||||
@@ -212,9 +214,9 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
|
||||
* 'mail_system', which is a keyed array. The default implementation
|
||||
* is the class whose name is the value of 'default-system' key. A more specific
|
||||
* match first to key and then to module will be used in preference to the
|
||||
* default. To specificy a different class for all mail sent by one module, set
|
||||
* default. To specify a different class for all mail sent by one module, set
|
||||
* the class name as the value for the key corresponding to the module name. To
|
||||
* specificy a class for a particular message sent by one module, set the class
|
||||
* specify a class for a particular message sent by one module, set the class
|
||||
* name as the value for the array key that is the message id, which is
|
||||
* "${module}_${key}".
|
||||
*
|
||||
@@ -307,19 +309,21 @@ interface MailSystemInterface {
|
||||
* - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy',
|
||||
* 'user_password_reset'.
|
||||
* - to: The mail address or addresses where the message will be sent to.
|
||||
* The formatting of this string must comply with RFC 2822. Some examples:
|
||||
* The formatting of this string will be validated with the
|
||||
* @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink
|
||||
* Some examples are:
|
||||
* - user@example.com
|
||||
* - user@example.com, anotheruser@example.com
|
||||
* - User <user@example.com>
|
||||
* - User <user@example.com>, Another User <anotheruser@example.com>
|
||||
* - subject: Subject of the e-mail to be sent. This must not contain any
|
||||
* newline characters, or the mail may not be sent properly.
|
||||
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
|
||||
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
|
||||
* smart plain text wrapping.
|
||||
* - headers: Associative array containing all additional mail headers not
|
||||
* defined by one of the other parameters. PHP's mail() looks for Cc
|
||||
* and Bcc headers and sends the mail to addresses in these headers too.
|
||||
* - subject: Subject of the e-mail to be sent. This must not contain any
|
||||
* newline characters, or the mail may not be sent properly.
|
||||
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
|
||||
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
|
||||
* smart plain text wrapping.
|
||||
* - headers: Associative array containing all additional mail headers not
|
||||
* defined by one of the other parameters. PHP's mail() looks for Cc and
|
||||
* Bcc headers and sends the mail to addresses in these headers too.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the mail was successfully accepted for delivery, otherwise FALSE.
|
||||
@@ -328,18 +332,21 @@ interface MailSystemInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform format=flowed soft wrapping for mail (RFC 3676).
|
||||
* Performs format=flowed soft wrapping for mail (RFC 3676).
|
||||
*
|
||||
* We use delsp=yes wrapping, but only break non-spaced languages when
|
||||
* absolutely necessary to avoid compatibility issues.
|
||||
*
|
||||
* 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 string
|
||||
* The content of the email as a string with formatting applied.
|
||||
*/
|
||||
function drupal_wrap_mail($text, $indent = '') {
|
||||
// Convert CRLF into LF.
|
||||
@@ -349,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)));
|
||||
@@ -371,8 +379,7 @@ function drupal_wrap_mail($text, $indent = '') {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an HTML string into plain text, preserving the structure of the
|
||||
* markup. Useful for preparing the body of a node to be sent by e-mail.
|
||||
* Transforms an HTML string into plain text, preserving its structure.
|
||||
*
|
||||
* The output will be suitable for use as 'format=flowed; delsp=yes' text
|
||||
* (RFC 3676) and can be passed directly to drupal_mail() for sending.
|
||||
@@ -551,21 +558,21 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for array_walk in drupal_wrap_mail().
|
||||
*
|
||||
* Wraps words on a single line.
|
||||
*
|
||||
* Callback for array_walk() winthin drupal_wrap_mail().
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for drupal_html_to_text().
|
||||
*
|
||||
* Keeps track of URLs and replaces them with placeholder tokens.
|
||||
*
|
||||
* Callback for preg_replace_callback() within drupal_html_to_text().
|
||||
*/
|
||||
function _drupal_html_to_mail_urls($match = NULL, $reset = FALSE) {
|
||||
global $base_url, $base_path;
|
||||
@@ -590,18 +597,18 @@ function _drupal_html_to_mail_urls($match = NULL, $reset = FALSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for drupal_wrap_mail() and drupal_html_to_text().
|
||||
* Replaces non-quotation markers from a given piece of indentation with spaces.
|
||||
*
|
||||
* Replace all non-quotation markers from a given piece of indentation with spaces.
|
||||
* Callback for array_map() within drupal_html_to_text().
|
||||
*/
|
||||
function _drupal_html_to_text_clean($indent) {
|
||||
return preg_replace('/[^>]/', ' ', $indent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for drupal_html_to_text().
|
||||
* Pads the last line with the given character.
|
||||
*
|
||||
* Pad the last line with the given character.
|
||||
* @see drupal_html_to_text()
|
||||
*/
|
||||
function _drupal_html_to_text_pad($text, $pad, $prefix = '') {
|
||||
// Remove last line break.
|
||||
|
||||
Regular → Executable
+183
-98
@@ -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
|
||||
@@ -417,9 +425,9 @@ function menu_unserialize($data, $map) {
|
||||
* @param $path
|
||||
* The path.
|
||||
* @param $router_item
|
||||
* The router item. Usually you take a router entry from menu_get_item and
|
||||
* set it back either modified or to a different path. This lets you modify the
|
||||
* navigation block, the page title, the breadcrumb and the page help in one
|
||||
* The router item. Usually a router entry from menu_get_item() is either
|
||||
* modified or set to a different path. This allows the navigation block,
|
||||
* the page title, the breadcrumb, and the page help to be modified in one
|
||||
* call.
|
||||
*/
|
||||
function menu_set_item($path, $router_item) {
|
||||
@@ -427,21 +435,22 @@ function menu_set_item($path, $router_item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a 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.
|
||||
*
|
||||
* @return
|
||||
* The router item, an associate array corresponding to one row in the
|
||||
* menu_router table. The value of key map holds the loaded objects. The
|
||||
* value of key access is TRUE if the current user can access this page.
|
||||
* The values for key title, page_arguments, access_arguments, and
|
||||
* theme_arguments will be filled in based on the database values and the
|
||||
* objects loaded.
|
||||
* The router item or, if an error occurs in _menu_translate(), FALSE. A
|
||||
* router item is an associative array corresponding to one row in the
|
||||
* menu_router table. The value corresponding to the key 'map' holds the
|
||||
* loaded objects. The value corresponding to the key 'access' is TRUE if the
|
||||
* current user can access this page. The values corresponding to the keys
|
||||
* 'title', 'page_arguments', 'access_arguments', and 'theme_arguments' will
|
||||
* be filled in based on the database values and the objects loaded.
|
||||
*/
|
||||
function menu_get_item($path = NULL, $router_item = NULL) {
|
||||
$router_items = &drupal_static(__FUNCTION__);
|
||||
@@ -455,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);
|
||||
|
||||
@@ -541,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.
|
||||
@@ -606,17 +617,18 @@ function _menu_load_objects(&$item, &$map) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check access to a menu item using the access callback
|
||||
* Checks access to a menu item using the access callback.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
function _menu_check_access(&$item, $map) {
|
||||
$item['access'] = FALSE;
|
||||
// Determine access callback, which will decide whether or not the current
|
||||
// user has access to this path.
|
||||
$callback = empty($item['access_callback']) ? 0 : trim($item['access_callback']);
|
||||
@@ -638,7 +650,7 @@ function _menu_check_access(&$item, $map) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Localize the router item title using t() or another callback.
|
||||
* Localizes the router item title using t() or another callback.
|
||||
*
|
||||
* Translate the title and description to allow storage of English title
|
||||
* strings in the database, yet display of them in the language required
|
||||
@@ -736,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.
|
||||
@@ -746,7 +758,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
|
||||
* $item['load_functions']. $item['access'] becomes TRUE if the item is
|
||||
* accessible, FALSE otherwise. $item['href'] is set according to the map.
|
||||
* If an error occurs during calling the load_functions (like trying to load
|
||||
* a non existing node) then this function return FALSE.
|
||||
* a non-existent node) then this function returns FALSE.
|
||||
*/
|
||||
function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
||||
if ($to_arg && !empty($router_item['to_arg_functions'])) {
|
||||
@@ -796,14 +808,14 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function translates the path elements in the map using any to_arg
|
||||
* helper function. These functions take an argument and return an object.
|
||||
* See http://drupal.org/node/109153 for more information.
|
||||
* 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()
|
||||
*/
|
||||
function _menu_link_map_translate(&$map, $to_arg_functions) {
|
||||
$to_arg_functions = unserialize($to_arg_functions);
|
||||
@@ -820,14 +832,14 @@ function _menu_link_map_translate(&$map, $to_arg_functions) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path as one string from the argument we are currently at.
|
||||
* Returns a string containing the path relative to the current index.
|
||||
*/
|
||||
function menu_tail_to_arg($arg, $map, $index) {
|
||||
return implode('/', array_slice($map, $index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads path as one string from the argument we are currently at.
|
||||
* Loads the path as one string relative to the current index.
|
||||
*
|
||||
* To use this load function, you must specify the load arguments
|
||||
* in the router item as:
|
||||
@@ -844,8 +856,10 @@ function menu_tail_load($arg, &$map, $index) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is similar to _menu_translate() but does link-specific
|
||||
* preparation such as always calling to_arg functions
|
||||
* Provides menu link access control, translation, and argument handling.
|
||||
*
|
||||
* This function is similar to _menu_translate(), but it also does
|
||||
* link-specific preparation (such as always calling to_arg() functions).
|
||||
*
|
||||
* @param $item
|
||||
* A menu link.
|
||||
@@ -939,7 +953,7 @@ function _menu_link_translate(&$item, $translate = FALSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a loaded object from a router item.
|
||||
* Gets a loaded object from a router item.
|
||||
*
|
||||
* menu_get_object() provides access to objects loaded by the current router
|
||||
* item. For example, on the page node/%node, the router loads the %node object,
|
||||
@@ -996,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.
|
||||
@@ -1079,7 +1093,7 @@ function menu_tree_output($tree) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data structure representing a named menu tree.
|
||||
* Gets the data structure representing a named menu tree.
|
||||
*
|
||||
* Since this can be the full tree including hidden items, the data returned
|
||||
* may be used for generating an an admin interface or a select.
|
||||
@@ -1147,7 +1161,7 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path for determining the active trail of the specified menu tree.
|
||||
* Sets the path for determining the active trail of the specified menu tree.
|
||||
*
|
||||
* This path will also affect the breadcrumbs under some circumstances.
|
||||
* Breadcrumbs are built using the preferred link returned by
|
||||
@@ -1172,7 +1186,7 @@ function menu_tree_set_path($menu_name, $path = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path for determining the active trail of the specified menu tree.
|
||||
* Gets the path for determining the active trail of the specified menu tree.
|
||||
*
|
||||
* @param $menu_name
|
||||
* The menu name of the requested tree.
|
||||
@@ -1186,7 +1200,7 @@ function menu_tree_get_path($menu_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data structure representing a named menu tree, based on the current page.
|
||||
* Gets the data structure for a named menu tree, based on the current page.
|
||||
*
|
||||
* The tree order is maintained by storing each parent in an individual
|
||||
* field, see http://drupal.org/node/141866 for more.
|
||||
@@ -1320,7 +1334,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a menu tree, translate links, and check access.
|
||||
* Builds a menu tree, translates links, and checks access.
|
||||
*
|
||||
* @param $menu_name
|
||||
* The name of the menu.
|
||||
@@ -1335,8 +1349,8 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
|
||||
* trail. This option is ignored, if 'expanded' is non-empty. Internally
|
||||
* used for breadcrumbs.
|
||||
* - min_depth: The minimum depth of menu links in the resulting tree.
|
||||
* Defaults to 1, which is the default to build a whole tree for a menu, i.e.
|
||||
* excluding menu container itself.
|
||||
* Defaults to 1, which is the default to build a whole tree for a menu
|
||||
* (excluding menu container itself).
|
||||
* - max_depth: The maximum depth of menu links in the resulting tree.
|
||||
* - conditions: An associative array of custom database select query
|
||||
* condition key/value pairs; see _menu_build_tree() for the actual query.
|
||||
@@ -1353,7 +1367,7 @@ function menu_build_tree($menu_name, array $parameters = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a menu tree.
|
||||
* Builds a menu tree.
|
||||
*
|
||||
* This function may be used build the data for a menu tree only, for example
|
||||
* to further massage the data manually before further processing happens.
|
||||
@@ -1449,7 +1463,7 @@ function _menu_build_tree($menu_name, array $parameters = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function - collect node links.
|
||||
* Collects node links from a given menu tree recursively.
|
||||
*
|
||||
* @param $tree
|
||||
* The menu tree you wish to collect node links from.
|
||||
@@ -1472,7 +1486,7 @@ function menu_tree_collect_node_links(&$tree, &$node_links) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check access and perform other dynamic operations for each link in the tree.
|
||||
* Checks access and performs dynamic operations for each link in the tree.
|
||||
*
|
||||
* @param $tree
|
||||
* The menu tree you wish to operate on.
|
||||
@@ -1481,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');
|
||||
@@ -1499,7 +1513,7 @@ function menu_tree_check_access(&$tree, $node_links = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function for menu_tree_check_access()
|
||||
* Sorts the menu tree and recursively checks access for each item.
|
||||
*/
|
||||
function _menu_tree_check_access(&$tree) {
|
||||
$new_tree = array();
|
||||
@@ -1522,7 +1536,7 @@ function _menu_tree_check_access(&$tree) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the data representing a menu tree.
|
||||
* Sorts and returns the built data representing a menu tree.
|
||||
*
|
||||
* @param $links
|
||||
* A flat array of menu links that are part of the menu. Each array element
|
||||
@@ -1554,7 +1568,7 @@ function menu_tree_data(array $links, array $parents = array(), $depth = 1) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function to build the data representing a menu tree.
|
||||
* Builds the data representing a menu tree.
|
||||
*
|
||||
* The function is a bit complex because the rendering of a link depends on
|
||||
* the next menu link.
|
||||
@@ -1589,9 +1603,10 @@ function _menu_tree_data(&$links, $parents, $depth) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocesses the rendered tree for theme_menu_tree().
|
||||
* Implements template_preprocess_HOOK() for theme_menu_tree().
|
||||
*/
|
||||
function template_preprocess_menu_tree(&$variables) {
|
||||
$variables['#tree'] = $variables['tree'];
|
||||
$variables['tree'] = $variables['tree']['#children'];
|
||||
}
|
||||
|
||||
@@ -1783,7 +1798,7 @@ function menu_get_names() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array containing the names of system-defined (default) menus.
|
||||
* Returns an array containing the names of system-defined (default) menus.
|
||||
*/
|
||||
function menu_list_system_menus() {
|
||||
return array(
|
||||
@@ -1795,14 +1810,14 @@ function menu_list_system_menus() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of links to be rendered as the Main menu.
|
||||
* Returns an array of links to be rendered as the Main menu.
|
||||
*/
|
||||
function menu_main_menu() {
|
||||
return menu_navigation_links(variable_get('menu_main_links_source', 'main-menu'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of links to be rendered as the Secondary links.
|
||||
* Returns an array of links to be rendered as the Secondary links.
|
||||
*/
|
||||
function menu_secondary_menu() {
|
||||
|
||||
@@ -1817,7 +1832,7 @@ function menu_secondary_menu() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of links for a navigation menu.
|
||||
* Returns an array of links for a navigation menu.
|
||||
*
|
||||
* @param $menu_name
|
||||
* The name of the menu.
|
||||
@@ -1922,13 +1937,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();
|
||||
@@ -2109,14 +2132,12 @@ function menu_local_tasks($level = 0) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve contextual links for a system object based on registered local tasks.
|
||||
* Retrieves contextual links for a path based on registered local tasks.
|
||||
*
|
||||
* This leverages the menu system to retrieve the first layer of registered
|
||||
* local tasks for a given system path. All local tasks of the tab type
|
||||
* MENU_CONTEXT_INLINE are taken into account.
|
||||
*
|
||||
* @see hook_menu()
|
||||
*
|
||||
* For example, when considering the following registered local tasks:
|
||||
* - node/%node/view (default local task) with no 'context' defined
|
||||
* - node/%node/edit with context: MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE
|
||||
@@ -2137,13 +2158,14 @@ 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
|
||||
* A list of menu router items that are local tasks for the passed-in path.
|
||||
*
|
||||
* @see contextual_links_preprocess()
|
||||
* @see hook_menu()
|
||||
*/
|
||||
function menu_contextual_links($module, $parent_path, $args) {
|
||||
static $path_empty = array();
|
||||
@@ -2237,7 +2259,7 @@ function menu_local_actions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the router path, or the path of the parent tab of a default local task.
|
||||
* Returns the router path, or the path for a default local task's parent.
|
||||
*/
|
||||
function menu_tab_root_path() {
|
||||
$links = menu_local_tasks();
|
||||
@@ -2258,7 +2280,13 @@ function menu_local_tabs() {
|
||||
/**
|
||||
* Returns HTML for primary and secondary local tasks.
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - primary: (optional) An array of local tasks (tabs).
|
||||
* - secondary: (optional) An array of local tasks (tabs).
|
||||
*
|
||||
* @ingroup themeable
|
||||
* @see menu_local_tasks()
|
||||
*/
|
||||
function theme_menu_local_tasks(&$variables) {
|
||||
$output = '';
|
||||
@@ -2280,7 +2308,9 @@ function theme_menu_local_tasks(&$variables) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set (or get) the active menu for the current page - determines the active trail.
|
||||
* Sets (or gets) the active menu for the current page.
|
||||
*
|
||||
* The active menu for the page determines the active trail.
|
||||
*
|
||||
* @return
|
||||
* An array of menu machine names, in order of preference. The
|
||||
@@ -2302,17 +2332,17 @@ function menu_set_active_menu_names($menu_names = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active menu for the current page - determines the active trail.
|
||||
* Gets the active menu for the current page.
|
||||
*/
|
||||
function menu_get_active_menu_names() {
|
||||
return menu_set_active_menu_names();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active path, which determines which page is loaded.
|
||||
* Sets the active path, which determines which page is loaded.
|
||||
*
|
||||
* Note that this may not have the desired effect unless invoked very early
|
||||
* in the page load, such as during hook_boot, or unless you call
|
||||
* in the page load, such as during hook_boot(), or unless you call
|
||||
* menu_execute_active_handler() to generate your page output.
|
||||
*
|
||||
* @param $path
|
||||
@@ -2326,7 +2356,7 @@ function menu_set_active_item($path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active trail (path to menu tree root) of the current page.
|
||||
* Sets the active trail (path to the menu tree root) of the current page.
|
||||
*
|
||||
* Any trail set by this function will only be used for functionality that calls
|
||||
* menu_get_active_trail(). Drupal core only uses trails set here for
|
||||
@@ -2390,7 +2420,7 @@ function menu_set_active_trail($new_trail = NULL) {
|
||||
// argument placeholders (%). Such links are not contained in regular
|
||||
// menu trees, and have only been loaded for the additional
|
||||
// translation that happens here, so as to be able to display them in
|
||||
// the breadcumb for the current page.
|
||||
// the breadcrumb for the current page.
|
||||
// @see _menu_tree_check_access()
|
||||
// @see _menu_link_translate()
|
||||
if (strpos($link['href'], '%') !== FALSE) {
|
||||
@@ -2416,10 +2446,10 @@ function menu_set_active_trail($new_trail = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the preferred menu link for a given system path.
|
||||
* 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.
|
||||
@@ -2476,6 +2506,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();
|
||||
@@ -2536,7 +2567,7 @@ function menu_get_active_trail() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the breadcrumb for the current page, as determined by the active trail.
|
||||
* Gets the breadcrumb for the current page, as determined by the active trail.
|
||||
*
|
||||
* @see menu_set_active_trail()
|
||||
*/
|
||||
@@ -2587,20 +2618,40 @@ function menu_get_active_breadcrumb() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the current page, as determined by the active trail.
|
||||
* Gets the title of the current page, as determined by the active trail.
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a menu link by its mlid, access checked and link translated for rendering.
|
||||
* Gets a translated, access-checked menu link that is ready for rendering.
|
||||
*
|
||||
* This function should never be called from within node_load() or any other
|
||||
* function used as a menu object load function since an infinite recursion may
|
||||
@@ -2632,7 +2683,7 @@ function menu_link_load($mlid) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached cached data for a single named menu.
|
||||
* Clears the cached data for a single named menu.
|
||||
*/
|
||||
function menu_cache_clear($menu_name = 'navigation') {
|
||||
$cache_cleared = &drupal_static(__FUNCTION__, array());
|
||||
@@ -2651,7 +2702,9 @@ function menu_cache_clear($menu_name = 'navigation') {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all cached menu data. This should be called any time broad changes
|
||||
* Clears all cached menu data.
|
||||
*
|
||||
* This should be called any time broad changes
|
||||
* might have been made to the router items or menu links.
|
||||
*/
|
||||
function menu_cache_clear_all() {
|
||||
@@ -2672,10 +2725,25 @@ function menu_reset_static_cache() {
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)populate the database tables used by various menu functions.
|
||||
* 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.
|
||||
*
|
||||
* This function will clear and populate the {menu_router} table, add entries
|
||||
* to {menu_links} for new router items, then remove stale items from
|
||||
* to {menu_links} for new router items, and then remove stale items from
|
||||
* {menu_links}. If called from update.php or install.php, it will also
|
||||
* schedule a call to itself on the first real page load from
|
||||
* menu_execute_active_handler(), because the maintenance page environment
|
||||
@@ -2691,6 +2759,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;
|
||||
}
|
||||
|
||||
@@ -2715,13 +2791,19 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect and alter the menu definitions.
|
||||
* Collects and alters the menu definitions.
|
||||
*/
|
||||
function menu_router_build() {
|
||||
// We need to manually call each module so that we can know which module
|
||||
@@ -2745,7 +2827,7 @@ function menu_router_build() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to store the menu router if we have it in memory.
|
||||
* Stores the menu router if we have it in memory.
|
||||
*/
|
||||
function _menu_router_cache($new_menu = NULL) {
|
||||
$menu = &drupal_static(__FUNCTION__);
|
||||
@@ -2757,7 +2839,7 @@ function _menu_router_cache($new_menu = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the menu router.
|
||||
* Gets the menu router.
|
||||
*/
|
||||
function menu_get_router() {
|
||||
// Check first if we have it in memory already.
|
||||
@@ -2794,7 +2876,7 @@ function _menu_link_build($item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build menu links for the items in the menu router.
|
||||
* Builds menu links for the items in the menu router.
|
||||
*/
|
||||
function _menu_navigation_links_rebuild($menu) {
|
||||
// Add normal and suggested items as links.
|
||||
@@ -2894,7 +2976,7 @@ function _menu_navigation_links_rebuild($menu) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone an array of menu links.
|
||||
* Clones an array of menu links.
|
||||
*
|
||||
* @param $links
|
||||
* An array of menu links to clone.
|
||||
@@ -2985,12 +3067,14 @@ function menu_link_delete($mlid, $path = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for menu_link_delete; deletes a single menu link.
|
||||
* Deletes a single menu link.
|
||||
*
|
||||
* @param $item
|
||||
* Item to be deleted.
|
||||
* @param $force
|
||||
* Forces deletion. Internal use only, setting to TRUE is discouraged.
|
||||
*
|
||||
* @see menu_link_delete()
|
||||
*/
|
||||
function _menu_delete_item($item, $force = FALSE) {
|
||||
$item = is_object($item) ? get_object_vars($item) : $item;
|
||||
@@ -3202,7 +3286,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a possible parent for a given menu link.
|
||||
* Finds a possible parent for a given menu link.
|
||||
*
|
||||
* Because the parent of a given link might not exist anymore in the database,
|
||||
* we apply a set of heuristics to determine a proper parent:
|
||||
@@ -3216,6 +3300,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a
|
||||
* A menu link.
|
||||
* @param $parent_candidates
|
||||
* An array of menu links keyed by mlid.
|
||||
*
|
||||
* @return
|
||||
* A menu link structure of the possible parent or FALSE if no valid parent
|
||||
* has been found.
|
||||
@@ -3281,7 +3366,7 @@ function _menu_link_find_parent($menu_link, $parent_candidates = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to clear the page and block caches at most twice per page load.
|
||||
* Clears the page and block caches at most twice per page load.
|
||||
*/
|
||||
function _menu_clear_page_cache() {
|
||||
$cache_cleared = &drupal_static(__FUNCTION__, 0);
|
||||
@@ -3303,7 +3388,7 @@ function _menu_clear_page_cache() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to update a list of menus with expanded items
|
||||
* Updates a list of menus with expanded items.
|
||||
*/
|
||||
function _menu_set_expanded_menus() {
|
||||
$names = db_query("SELECT menu_name FROM {menu_links} WHERE expanded <> 0 GROUP BY menu_name")->fetchCol();
|
||||
@@ -3311,7 +3396,7 @@ function _menu_set_expanded_menus() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the router path which will serve this path.
|
||||
* Finds the router path which will serve this path.
|
||||
*
|
||||
* @param $link_path
|
||||
* The path for we are looking up its router path.
|
||||
@@ -3353,7 +3438,7 @@ function _menu_find_router_path($link_path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert, update or delete an uncustomized menu link related to a module.
|
||||
* Inserts, updates, or deletes an uncustomized menu link related to a module.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module.
|
||||
@@ -3393,7 +3478,7 @@ function menu_link_maintain($module, $op, $link_path, $link_title) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the depth of an item's children relative to its depth.
|
||||
* Finds the depth of an item's children relative to its depth.
|
||||
*
|
||||
* For example, if the item has a depth of 2, and the maximum of any child in
|
||||
* the menu link tree is 5, the relative depth is 3.
|
||||
@@ -3425,7 +3510,7 @@ function menu_link_children_relative_depth($item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the children of a menu link that's being moved.
|
||||
* Updates the children of a menu link that is being moved.
|
||||
*
|
||||
* The menu name, parents (p1 - p6), and depth are updated for all children of
|
||||
* the link, and the has_children status of the previous parent is updated.
|
||||
@@ -3474,7 +3559,7 @@ function _menu_link_move_children($item, $existing_item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and update the has_children status for the parent of a link.
|
||||
* Checks and updates the 'has_children' status for the parent of a link.
|
||||
*/
|
||||
function _menu_update_parental_status($item, $exclude = FALSE) {
|
||||
// If plid == 0, there is nothing to update.
|
||||
@@ -3498,7 +3583,7 @@ function _menu_update_parental_status($item, $exclude = FALSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that sets the p1..p9 values for a menu link being saved.
|
||||
* Sets the p1 through p9 values for a menu link being saved.
|
||||
*/
|
||||
function _menu_link_parents_set(&$item, $parent) {
|
||||
$i = 1;
|
||||
@@ -3516,7 +3601,7 @@ function _menu_link_parents_set(&$item, $parent) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build the router table based on the data from hook_menu.
|
||||
* Builds the router table based on the data from hook_menu().
|
||||
*/
|
||||
function _menu_router_build($callbacks) {
|
||||
// First pass: separate callbacks from paths, making paths ready for
|
||||
@@ -3743,7 +3828,7 @@ function _menu_router_build($callbacks) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to save data from menu_router_build() to the router table.
|
||||
* Saves data from menu_router_build() to the router table.
|
||||
*/
|
||||
function _menu_router_save($menu, $masks) {
|
||||
// Delete the existing router since we have some data to replace it.
|
||||
|
||||
Regular → Executable
+156
-42
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load all the modules that have been enabled in the system table.
|
||||
* Loads all the modules that have been enabled in the system table.
|
||||
*
|
||||
* @param $bootstrap
|
||||
* Whether to load only the reduced set of modules loaded in "bootstrap mode"
|
||||
@@ -102,7 +102,7 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of bootstrap modules and enabled modules and themes.
|
||||
* Builds a list of bootstrap modules and enabled modules and themes.
|
||||
*
|
||||
* @param $type
|
||||
* The type of list to return:
|
||||
@@ -181,6 +181,7 @@ function system_list($type) {
|
||||
foreach ($lists['theme'] as $key => $theme) {
|
||||
if (!empty($theme->info['base theme'])) {
|
||||
// Make a list of the theme's base themes.
|
||||
require_once DRUPAL_ROOT . '/includes/theme.inc';
|
||||
$lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
|
||||
// Don't proceed if there was a problem with the root base theme.
|
||||
if (!current($lists['theme'][$key]->base_themes)) {
|
||||
@@ -218,7 +219,7 @@ function system_list($type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all system_list() caches.
|
||||
* Resets all system_list() caches.
|
||||
*/
|
||||
function system_list_reset() {
|
||||
drupal_static_reset('system_list');
|
||||
@@ -226,10 +227,14 @@ 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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Find dependencies any level deep and fill in required by information too.
|
||||
* Determines which modules require and are required by each module.
|
||||
*
|
||||
* @param $files
|
||||
* The array of filesystem objects used to rebuild the cache.
|
||||
@@ -262,13 +267,13 @@ function _module_build_dependencies($files) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a given module exists.
|
||||
* 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();
|
||||
@@ -276,7 +281,7 @@ function module_exists($module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a module's installation hooks.
|
||||
* Loads a module's installation hooks.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module (without the .module extension).
|
||||
@@ -292,7 +297,7 @@ function module_load_install($module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a module include file.
|
||||
* Loads a module include file.
|
||||
*
|
||||
* Examples:
|
||||
* @code
|
||||
@@ -319,23 +324,33 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an include file for each of the modules that have been enabled in
|
||||
* the system table.
|
||||
* Loads an include file for each module enabled in the {system} table.
|
||||
*/
|
||||
function module_load_all_includes($type, $name = NULL) {
|
||||
$modules = module_list();
|
||||
@@ -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) {
|
||||
@@ -503,14 +520,17 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a given set of modules.
|
||||
* 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,11 +630,42 @@ 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
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine whether a module implements a hook.
|
||||
* Determines whether a module implements a hook.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module (without the .module extension).
|
||||
@@ -643,14 +694,18 @@ function module_hook($module, $hook) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which modules are implementing a 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,13 +823,21 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
|
||||
$implementations['#write_cache'] = TRUE;
|
||||
}
|
||||
}
|
||||
$verified[$hook] = TRUE;
|
||||
}
|
||||
|
||||
return array_keys($implementations[$hook]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of what hooks are explicitly declared.
|
||||
* Retrieves a list of hooks that are declared through hook_hook_info().
|
||||
*
|
||||
* @return
|
||||
* An associative array whose keys are hook names and whose values are an
|
||||
* associative array containing a group name. The structure of the array
|
||||
* is the same as the return value of hook_hook_info().
|
||||
*
|
||||
* @see hook_hook_info()
|
||||
*/
|
||||
function module_hook_info() {
|
||||
// This function is indirectly invoked from bootstrap_invoke_all(), in which
|
||||
@@ -795,18 +888,23 @@ 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');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a hook in a particular module.
|
||||
* 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).
|
||||
@@ -817,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();
|
||||
@@ -828,7 +928,10 @@ function module_invoke($module, $hook) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a hook in all enabled modules that implement it.
|
||||
* 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.
|
||||
@@ -837,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();
|
||||
@@ -865,13 +972,13 @@ function module_invoke_all($hook) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Array of modules required by core.
|
||||
* Returns an array of modules required by core.
|
||||
*/
|
||||
function drupal_required_modules() {
|
||||
$files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules', 'name', 0);
|
||||
$required = array();
|
||||
|
||||
// An install profile is required and one must always be loaded.
|
||||
// An installation profile is required and one must always be loaded.
|
||||
$required[] = drupal_get_profile();
|
||||
|
||||
foreach ($files as $name => $file) {
|
||||
@@ -885,15 +992,16 @@ function drupal_required_modules() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Hands off alterable variables to type-specific *_alter implementations.
|
||||
* Passes alterable variables to specific hook_TYPE_alter() implementations.
|
||||
*
|
||||
* This dispatch function hands off the passed-in variables to type-specific
|
||||
* hook_TYPE_alter() implementations in modules. It ensures a consistent
|
||||
* interface for all altering operations.
|
||||
*
|
||||
* A maximum of 2 alterable arguments is supported. In case more arguments need
|
||||
* to be passed and alterable, modules provide additional variables assigned by
|
||||
* reference in the last $context argument:
|
||||
* A maximum of 2 alterable arguments is supported (a third is supported for
|
||||
* legacy reasons, but should not be used in new code). In case more arguments
|
||||
* need to be passed and alterable, modules provide additional variables
|
||||
* assigned by reference in the last $context argument:
|
||||
* @code
|
||||
* $context = array(
|
||||
* 'alterable' => &$alterable,
|
||||
@@ -932,8 +1040,14 @@ function drupal_required_modules() {
|
||||
* (optional) An additional variable that is passed by reference. If more
|
||||
* context needs to be provided to implementations, then this should be an
|
||||
* associative array as described above.
|
||||
* @param $context3
|
||||
* (optional) An additional variable that is passed by reference. This
|
||||
* parameter is deprecated and will not exist in Drupal 8; consequently, it
|
||||
* should not be used for new Drupal 7 code either. It is here only for
|
||||
* backwards compatibility with older code that passed additional arguments
|
||||
* to drupal_alter().
|
||||
*/
|
||||
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
|
||||
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
|
||||
// Use the advanced drupal_static() pattern, since this is called very often.
|
||||
static $drupal_static_fast;
|
||||
if (!isset($drupal_static_fast)) {
|
||||
@@ -1046,6 +1160,6 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
|
||||
}
|
||||
|
||||
foreach ($functions[$cid] as $function) {
|
||||
$function($data, $context1, $context2);
|
||||
$function($data, $context1, $context2, $context3);
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
Regular → Executable
+6
-2
@@ -43,7 +43,7 @@ function _password_itoa64() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode bytes into printable base 64 using the *nix standard from crypt().
|
||||
* Encodes bytes into printable base 64 using the *nix standard from crypt().
|
||||
*
|
||||
* @param $input
|
||||
* The string containing bytes to encode.
|
||||
@@ -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);
|
||||
|
||||
|
||||
Regular → Executable
+10
-9
@@ -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()
|
||||
*/
|
||||
@@ -386,7 +387,7 @@ function drupal_path_alias_whitelist_rebuild($source = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a specific URL alias from the database.
|
||||
* Fetches a specific URL alias from the database.
|
||||
*
|
||||
* @param $conditions
|
||||
* A string representing the source, a number representing the pid, or an
|
||||
@@ -475,11 +476,11 @@ function path_delete($criteria) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a path is in the administrative section of the site.
|
||||
* Determines whether a path is in the administrative section of the site.
|
||||
*
|
||||
* By default, paths are considered to be non-administrative. If a path does not
|
||||
* match any of the patterns in path_get_admin_paths(), or if it matches both
|
||||
* administrative and non-administrative patterns, it is considered
|
||||
* By default, paths are considered to be non-administrative. If a path does
|
||||
* not match any of the patterns in path_get_admin_paths(), or if it matches
|
||||
* both administrative and non-administrative patterns, it is considered
|
||||
* non-administrative.
|
||||
*
|
||||
* @param $path
|
||||
@@ -503,7 +504,7 @@ function path_is_admin($path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of administrative and non-administrative paths.
|
||||
* Gets a list of administrative and non-administrative paths.
|
||||
*
|
||||
* @return array
|
||||
* An associative array containing the following keys:
|
||||
@@ -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);
|
||||
|
||||
Regular → Executable
+7
-4
@@ -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(
|
||||
|
||||
Regular → Executable
+28
-8
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +274,7 @@ function drupal_session_initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully starts a session, preserving already set session data.
|
||||
* Starts a session forcefully, preserving already set session data.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
@@ -349,13 +349,18 @@ function drupal_session_started($set = NULL) {
|
||||
*/
|
||||
function drupal_session_regenerate() {
|
||||
global $user, $is_https;
|
||||
// Nothing to do if we are not allowed to change the session.
|
||||
if (!drupal_save_session()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($is_https && variable_get('https', FALSE)) {
|
||||
$insecure_session_name = substr(session_name(), 1);
|
||||
if (!isset($GLOBALS['lazy_session']) && isset($_COOKIE[$insecure_session_name])) {
|
||||
$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.
|
||||
@@ -367,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();
|
||||
@@ -418,6 +423,11 @@ function drupal_session_regenerate() {
|
||||
function _drupal_session_destroy($sid) {
|
||||
global $user, $is_https;
|
||||
|
||||
// Nothing to do if we are not allowed to change the session.
|
||||
if (!drupal_save_session()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Delete session data.
|
||||
db_delete('sessions')
|
||||
->condition($is_https ? 'ssid' : 'sid', $sid)
|
||||
@@ -436,6 +446,8 @@ function _drupal_session_destroy($sid) {
|
||||
elseif (variable_get('https', FALSE)) {
|
||||
_drupal_session_delete_cookie('S' . session_name(), TRUE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,6 +477,11 @@ function _drupal_session_delete_cookie($name, $secure = NULL) {
|
||||
* User ID.
|
||||
*/
|
||||
function drupal_session_destroy_uid($uid) {
|
||||
// Nothing to do if we are not allowed to change the session.
|
||||
if (!drupal_save_session()) {
|
||||
return;
|
||||
}
|
||||
|
||||
db_delete('sessions')
|
||||
->condition('uid', $uid)
|
||||
->execute();
|
||||
@@ -507,7 +524,10 @@ function _drupal_session_garbage_collection($lifetime) {
|
||||
* FALSE if writing session data has been disabled. Otherwise, TRUE.
|
||||
*/
|
||||
function drupal_save_session($status = NULL) {
|
||||
$save_session = &drupal_static(__FUNCTION__, TRUE);
|
||||
// PHP session ID, session, and cookie handling happens in the global scope.
|
||||
// This value has to persist across calls to drupal_static_reset(), since a
|
||||
// potentially wrong or disallowed session would be written otherwise.
|
||||
static $save_session = TRUE;
|
||||
if (isset($status)) {
|
||||
$save_session = $status;
|
||||
}
|
||||
|
||||
Regular → Executable
+173
-27
@@ -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);
|
||||
@@ -133,7 +133,7 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
|
||||
* @param $uri
|
||||
* A string containing the URI that should be used for this instance.
|
||||
*/
|
||||
function setUri($uri);
|
||||
public function setUri($uri);
|
||||
|
||||
/**
|
||||
* Returns the stream resource URI.
|
||||
@@ -219,7 +219,6 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
|
||||
public function dirname($uri = NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drupal stream wrapper base class for local files.
|
||||
*
|
||||
@@ -401,7 +400,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 +428,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 +447,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 +462,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 +474,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 +491,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 +505,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 +517,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 +530,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,22 +542,171 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets metadata on the stream.
|
||||
*
|
||||
* WARNING: Do not call this method directly! It will be called internally by
|
||||
* PHP itself when one of the following functions is called on a stream URL:
|
||||
*
|
||||
* @param string $uri
|
||||
* A string containing the URI to the file to set metadata on.
|
||||
* @param int $option
|
||||
* One of:
|
||||
* - STREAM_META_TOUCH: The method was called in response to touch().
|
||||
* - STREAM_META_OWNER_NAME: The method was called in response to chown()
|
||||
* with string parameter.
|
||||
* - STREAM_META_OWNER: The method was called in response to chown().
|
||||
* - STREAM_META_GROUP_NAME: The method was called in response to chgrp().
|
||||
* - STREAM_META_GROUP: The method was called in response to chgrp().
|
||||
* - STREAM_META_ACCESS: The method was called in response to chmod().
|
||||
* @param mixed $value
|
||||
* If option is:
|
||||
* - STREAM_META_TOUCH: Array consisting of two arguments of the touch()
|
||||
* function.
|
||||
* - STREAM_META_OWNER_NAME or STREAM_META_GROUP_NAME: The name of the owner
|
||||
* user/group as string.
|
||||
* - STREAM_META_OWNER or STREAM_META_GROUP: The value of the owner
|
||||
* user/group as integer.
|
||||
* - STREAM_META_ACCESS: The argument of the chmod() as integer.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE on success or FALSE on failure. If $option is not
|
||||
* implemented, FALSE should be returned.
|
||||
*
|
||||
* @see touch()
|
||||
* @see chmod()
|
||||
* @see chown()
|
||||
* @see chgrp()
|
||||
* @link http://php.net/manual/streamwrapper.stream-metadata.php
|
||||
*/
|
||||
public function stream_metadata($uri, $option, $value) {
|
||||
$target = $this->getLocalPath($uri);
|
||||
$return = FALSE;
|
||||
switch ($option) {
|
||||
case STREAM_META_TOUCH:
|
||||
if (!empty($value)) {
|
||||
$return = touch($target, $value[0], $value[1]);
|
||||
}
|
||||
else {
|
||||
$return = touch($target);
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_META_OWNER_NAME:
|
||||
case STREAM_META_OWNER:
|
||||
$return = chown($target, $value);
|
||||
break;
|
||||
|
||||
case STREAM_META_GROUP_NAME:
|
||||
case STREAM_META_GROUP:
|
||||
$return = chgrp($target, $value);
|
||||
break;
|
||||
|
||||
case STREAM_META_ACCESS:
|
||||
$return = chmod($target, $value);
|
||||
break;
|
||||
}
|
||||
if ($return) {
|
||||
// For convenience clear the file status cache of the underlying file,
|
||||
// since metadata operations are often followed by file status checks.
|
||||
clearstatcache(TRUE, $target);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate stream.
|
||||
*
|
||||
* Will respond to truncation; e.g., through ftruncate().
|
||||
*
|
||||
* @param int $new_size
|
||||
* The new size.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE on success, FALSE otherwise.
|
||||
*/
|
||||
public function stream_truncate($new_size) {
|
||||
return ftruncate($this->handle, $new_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the underlying stream resource.
|
||||
*
|
||||
* This method is called in response to stream_select().
|
||||
*
|
||||
* @param int $cast_as
|
||||
* Can be STREAM_CAST_FOR_SELECT when stream_select() is calling
|
||||
* stream_cast() or STREAM_CAST_AS_STREAM when stream_cast() is called for
|
||||
* other uses.
|
||||
*
|
||||
* @return resource|false
|
||||
* The underlying stream resource or FALSE if stream_select() is not
|
||||
* supported.
|
||||
*
|
||||
* @see stream_select()
|
||||
* @link http://php.net/manual/streamwrapper.stream-cast.php
|
||||
*/
|
||||
public function stream_cast($cast_as) {
|
||||
return $this->handle ? $this->handle : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change stream options.
|
||||
*
|
||||
* This method is called to set options on the stream.
|
||||
*
|
||||
* Since Windows systems do not allow it and it is not needed for most use
|
||||
* cases anyway, this method is not supported on local files and will trigger
|
||||
* an error and return false. If needed, custom subclasses can provide
|
||||
* OS-specific implementations for advanced use cases.
|
||||
*
|
||||
* @param int $option
|
||||
* One of:
|
||||
* - STREAM_OPTION_BLOCKING: The method was called in response to
|
||||
* stream_set_blocking().
|
||||
* - STREAM_OPTION_READ_TIMEOUT: The method was called in response to
|
||||
* stream_set_timeout().
|
||||
* - STREAM_OPTION_WRITE_BUFFER: The method was called in response to
|
||||
* stream_set_write_buffer().
|
||||
* @param int $arg1
|
||||
* If option is:
|
||||
* - STREAM_OPTION_BLOCKING: The requested blocking mode:
|
||||
* - 1 means blocking.
|
||||
* - 0 means not blocking.
|
||||
* - STREAM_OPTION_READ_TIMEOUT: The timeout in seconds.
|
||||
* - STREAM_OPTION_WRITE_BUFFER: The buffer mode, STREAM_BUFFER_NONE or
|
||||
* STREAM_BUFFER_FULL.
|
||||
* @param int $arg2
|
||||
* If option is:
|
||||
* - STREAM_OPTION_BLOCKING: This option is not set.
|
||||
* - STREAM_OPTION_READ_TIMEOUT: The timeout in microseconds.
|
||||
* - STREAM_OPTION_WRITE_BUFFER: The requested buffer size.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE on success, FALSE otherwise. If $option is not implemented, FALSE
|
||||
* should be returned.
|
||||
*/
|
||||
public function stream_set_option($option, $arg1, $arg2) {
|
||||
trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for unlink().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the uri to the resource to delete.
|
||||
* A string containing the URI to the resource to delete.
|
||||
*
|
||||
* @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;
|
||||
@@ -569,14 +717,14 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* Support for rename().
|
||||
*
|
||||
* @param $from_uri,
|
||||
* The uri to the file to rename.
|
||||
* The URI to the file to rename.
|
||||
* @param $to_uri
|
||||
* The new uri for file.
|
||||
* The new URI for file.
|
||||
*
|
||||
* @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 +770,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 +802,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 +826,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 +852,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 +867,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 +879,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 +895,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 +936,6 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
*
|
||||
* Provides support for storing privately accessible files with the Drupal file
|
||||
* interface.
|
||||
*
|
||||
* Extends DrupalPublicStreamWrapper.
|
||||
*/
|
||||
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
/**
|
||||
|
||||
Regular → Executable
+13
-10
@@ -46,16 +46,15 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the table sort context.
|
||||
* Initializes the table sort context.
|
||||
*/
|
||||
protected function init() {
|
||||
$ts = $this->order();
|
||||
@@ -115,7 +114,7 @@ function tablesort_init($header) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a column header.
|
||||
* Formats a column header.
|
||||
*
|
||||
* If the cell in question is the column header for the current sort criterion,
|
||||
* it gets special formatting. All possible sort criteria become links.
|
||||
@@ -126,6 +125,7 @@ function tablesort_init($header) {
|
||||
* An array of column headers in the format described in theme_table().
|
||||
* @param $ts
|
||||
* The current table sort context as returned from tablesort_init().
|
||||
*
|
||||
* @return
|
||||
* A properly formatted cell, ready for _theme_table_cell().
|
||||
*/
|
||||
@@ -151,7 +151,7 @@ function tablesort_header($cell, $header, $ts) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a table cell.
|
||||
* Formats a table cell.
|
||||
*
|
||||
* Adds a class attribute to all cells in the currently active column.
|
||||
*
|
||||
@@ -163,6 +163,7 @@ function tablesort_header($cell, $header, $ts) {
|
||||
* The current table sort context as returned from tablesort_init().
|
||||
* @param $i
|
||||
* The index of the cell's table column.
|
||||
*
|
||||
* @return
|
||||
* A properly formatted cell, ready for _theme_table_cell().
|
||||
*/
|
||||
@@ -179,7 +180,7 @@ function tablesort_cell($cell, $header, $ts, $i) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a URL query parameter array for table sorting links.
|
||||
* Composes a URL query parameter array for table sorting links.
|
||||
*
|
||||
* @return
|
||||
* A URL query parameter array that consists of all components of the current
|
||||
@@ -190,10 +191,11 @@ function tablesort_get_query_parameters() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the current sort criterion.
|
||||
* Determines the current sort criterion.
|
||||
*
|
||||
* @param $headers
|
||||
* An array of column headers in the format described in theme_table().
|
||||
*
|
||||
* @return
|
||||
* An associative array describing the criterion, containing the keys:
|
||||
* - "name": The localized title of the table column.
|
||||
@@ -226,10 +228,11 @@ function tablesort_get_order($headers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the current sort direction.
|
||||
* Determines the current sort direction.
|
||||
*
|
||||
* @param $headers
|
||||
* An array of column headers in the format described in theme_table().
|
||||
*
|
||||
* @return
|
||||
* The current sort direction ("asc" or "desc").
|
||||
*/
|
||||
|
||||
Regular → Executable
+226
-96
@@ -65,7 +65,7 @@ function _drupal_theme_access($theme) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the theme system by loading the theme.
|
||||
* Initializes the theme system by loading the theme.
|
||||
*/
|
||||
function drupal_theme_initialize() {
|
||||
global $theme, $user, $theme_key;
|
||||
@@ -113,8 +113,9 @@ function drupal_theme_initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the theme system given already loaded information. This
|
||||
* function is useful to initialize a theme when no database is present.
|
||||
* Initializes the theme system given already loaded information.
|
||||
*
|
||||
* This function is useful to initialize a theme when no database is present.
|
||||
*
|
||||
* @param $theme
|
||||
* An object with the following information:
|
||||
@@ -235,7 +236,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the theme registry.
|
||||
* Gets the theme registry.
|
||||
*
|
||||
* @param $complete
|
||||
* Optional boolean to indicate whether to return the complete theme registry
|
||||
@@ -280,7 +281,7 @@ function theme_get_registry($complete = TRUE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callback that will be used by theme_get_registry() to fetch the registry.
|
||||
* Sets the callback that will be used by theme_get_registry().
|
||||
*
|
||||
* @param $callback
|
||||
* The name of the callback function.
|
||||
@@ -296,7 +297,7 @@ function _theme_registry_callback($callback = NULL, array $arguments = array())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the theme_registry cache; if it doesn't exist, build it.
|
||||
* Gets the theme_registry cache; if it doesn't exist, builds it.
|
||||
*
|
||||
* @param $theme
|
||||
* The loaded $theme object as returned by list_themes().
|
||||
@@ -336,16 +337,17 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL,
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the theme_registry cache into the database.
|
||||
* Writes the theme_registry cache into the database.
|
||||
*/
|
||||
function _theme_save_registry($theme, $registry) {
|
||||
cache_set("theme_registry:$theme->name", $registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the system to rebuild the theme registry; this should be called
|
||||
* when modules are added to the system, or when a dynamic system needs
|
||||
* to add more theme hooks.
|
||||
* Forces the system to rebuild the theme registry.
|
||||
*
|
||||
* This function should be called when modules are added to the system, or when
|
||||
* a dynamic system needs to add more theme hooks.
|
||||
*/
|
||||
function drupal_theme_rebuild() {
|
||||
drupal_static_reset('theme_get_registry');
|
||||
@@ -506,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()
|
||||
*/
|
||||
@@ -635,7 +637,8 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
|
||||
$cache = $result + $cache;
|
||||
}
|
||||
|
||||
// Let themes have variable processors even if they didn't register a template.
|
||||
// Let themes have variable processors even if they didn't register a
|
||||
// template.
|
||||
if ($type == 'theme' || $type == 'base_theme') {
|
||||
foreach ($cache as $hook => $info) {
|
||||
// Check only if not registered by the theme or engine.
|
||||
@@ -662,7 +665,7 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the theme registry cache.
|
||||
* Builds the theme registry cache.
|
||||
*
|
||||
* @param $theme
|
||||
* The loaded $theme object as returned by list_themes().
|
||||
@@ -724,7 +727,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all currently available themes.
|
||||
* Returns a list of all currently available themes.
|
||||
*
|
||||
* Retrieved from the database, if available and the site is not in maintenance
|
||||
* mode; otherwise compiled freshly from the filesystem.
|
||||
@@ -766,7 +769,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
|
||||
* their base theme), direct sub-themes of sub-themes, etc. The keys are
|
||||
* the themes' machine names, and the values are the themes' human-readable
|
||||
* names. This element is not set if there are no themes on the system that
|
||||
* declare this theme as their base theme.
|
||||
* declare this theme as their base theme.
|
||||
*/
|
||||
function list_themes($refresh = FALSE) {
|
||||
$list = &drupal_static(__FUNCTION__, array());
|
||||
@@ -866,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()
|
||||
@@ -882,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
|
||||
@@ -894,21 +905,22 @@ 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
|
||||
* executed (if they exist), in the following order (note that in the following
|
||||
* list, HOOK indicates the theme hook name, MODULE indicates a module name,
|
||||
* THEME indicates a theme name, and ENGINE indicates a theme engine name):
|
||||
* - template_preprocess(&$variables, $hook): Creates a default set of variables
|
||||
* for all theme hooks with template implementations.
|
||||
* - template_preprocess(&$variables, $hook): Creates a default set of
|
||||
* variables for all theme hooks with template implementations.
|
||||
* - template_preprocess_HOOK(&$variables): Should be implemented by the module
|
||||
* that registers the theme hook, to set up default variables.
|
||||
* - MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all
|
||||
* implementing modules.
|
||||
* - MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on
|
||||
* all implementing modules, so that modules that didn't define the theme hook
|
||||
* can alter the variables.
|
||||
* all implementing modules, so that modules that didn't define the theme
|
||||
* hook can alter the variables.
|
||||
* - ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to
|
||||
* set necessary variables for all theme hooks with template implementations.
|
||||
* - ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set
|
||||
@@ -942,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,
|
||||
@@ -963,10 +977,10 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* @param $hook
|
||||
* The name of the theme hook to call. If the name contains a
|
||||
* double-underscore ('__') and there isn't an implementation for the full
|
||||
* name, the part before the '__' is checked. This allows a fallback to a more
|
||||
* generic implementation. For example, if theme('links__node', ...) is
|
||||
* called, but there is no implementation of that theme hook, then the 'links'
|
||||
* implementation is used. This process is iterative, so if
|
||||
* name, the part before the '__' is checked. This allows a fallback to a
|
||||
* more generic implementation. For example, if theme('links__node', ...) is
|
||||
* called, but there is no implementation of that theme hook, then the
|
||||
* 'links' implementation is used. This process is iterative, so if
|
||||
* theme('links__contextual__node', ...) is called, theme() checks for the
|
||||
* following implementations, and uses the first one that exists:
|
||||
* - links__contextual__node
|
||||
@@ -989,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()
|
||||
@@ -1014,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.
|
||||
@@ -1030,7 +1046,7 @@ function theme($hook, $variables = array()) {
|
||||
// Only log a message when not trying theme suggestions ($hook being an
|
||||
// array).
|
||||
if (!isset($candidate)) {
|
||||
watchdog('theme', 'Theme key "@key" not found.', array('@key' => $hook), WATCHDOG_WARNING);
|
||||
watchdog('theme', 'Theme hook %hook not found.', array('%hook' => $hook), WATCHDOG_WARNING);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -1042,7 +1058,8 @@ function theme($hook, $variables = array()) {
|
||||
// point path_to_theme() to the currently used theme path:
|
||||
$theme_path = $info['theme path'];
|
||||
|
||||
// Include a file if the theme function or variable processor is held elsewhere.
|
||||
// Include a file if the theme function or variable processor is held
|
||||
// elsewhere.
|
||||
if (!empty($info['includes'])) {
|
||||
foreach ($info['includes'] as $include_file) {
|
||||
include_once DRUPAL_ROOT . '/' . $include_file;
|
||||
@@ -1074,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
|
||||
@@ -1182,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()
|
||||
@@ -1191,14 +1215,14 @@ function theme($hook, $variables = array()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path to the current themed element.
|
||||
* Returns the path to the current themed element.
|
||||
*
|
||||
* It can point to the active theme or the module handling a themed implementation.
|
||||
* For example, when invoked within the scope of a theming call it will depend
|
||||
* on where the theming function is handled. If implemented from a module, it
|
||||
* will point to the module. If implemented from the active theme, it will point
|
||||
* to the active theme. When called outside the scope of a theming call, it will
|
||||
* always point to the active theme.
|
||||
* It can point to the active theme or the module handling a themed
|
||||
* implementation. For example, when invoked within the scope of a theming call
|
||||
* it will depend on where the theming function is handled. If implemented from
|
||||
* a module, it will point to the module. If implemented from the active theme,
|
||||
* it will point to the active theme. When called outside the scope of a
|
||||
* theming call, it will always point to the active theme.
|
||||
*/
|
||||
function path_to_theme() {
|
||||
global $theme_path;
|
||||
@@ -1211,7 +1235,7 @@ function path_to_theme() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow themes and/or theme engines to easily discover overridden theme functions.
|
||||
* Allows themes and/or theme engines to discover overridden theme functions.
|
||||
*
|
||||
* @param $cache
|
||||
* The existing cache of theme hooks to test against.
|
||||
@@ -1224,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) {
|
||||
@@ -1240,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);
|
||||
@@ -1268,7 +1293,7 @@ function drupal_find_theme_functions($cache, $prefixes) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow themes and/or theme engines to easily discover overridden templates.
|
||||
* Allows themes and/or theme engines to easily discover overridden templates.
|
||||
*
|
||||
* @param $cache
|
||||
* The existing cache of theme hooks to test against.
|
||||
@@ -1345,7 +1370,8 @@ function drupal_find_theme_templates($cache, $extension, $path) {
|
||||
if ($matches) {
|
||||
foreach ($matches as $match) {
|
||||
$file = substr($match, 0, strpos($match, '.'));
|
||||
// Put the underscores back in for the hook name and register this pattern.
|
||||
// Put the underscores back in for the hook name and register this
|
||||
// pattern.
|
||||
$arg_name = isset($info['variables']) ? 'variables' : 'render element';
|
||||
$implementations[strtr($file, '-', '_')] = array(
|
||||
'template' => $file,
|
||||
@@ -1361,7 +1387,7 @@ function drupal_find_theme_templates($cache, $extension, $path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a setting for the current theme or for a given theme.
|
||||
* Retrieves a setting for the current theme or for a given theme.
|
||||
*
|
||||
* The final setting is obtained from the last value found in the following
|
||||
* sources:
|
||||
@@ -1479,7 +1505,7 @@ function theme_get_setting($setting_name, $theme = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a system default template, which is essentially a PHP template.
|
||||
* Renders a system default template, which is essentially a PHP template.
|
||||
*
|
||||
* @param $template_file
|
||||
* The filename of the template to render.
|
||||
@@ -1490,14 +1516,87 @@ function theme_get_setting($setting_name, $theme = NULL) {
|
||||
* The output generated by the template.
|
||||
*/
|
||||
function theme_render_template($template_file, $variables) {
|
||||
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
|
||||
ob_start(); // Start output buffering
|
||||
include DRUPAL_ROOT . '/' . $template_file; // Include the template file
|
||||
return ob_get_clean(); // End buffering and return its contents
|
||||
// Extract the variables to a local namespace
|
||||
extract($variables, EXTR_SKIP);
|
||||
|
||||
// Start output buffering
|
||||
ob_start();
|
||||
|
||||
// Include the template file
|
||||
include DRUPAL_ROOT . '/' . $template_file;
|
||||
|
||||
// End buffering and return its contents
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a given list of themes.
|
||||
* 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.
|
||||
*
|
||||
* @param $theme_list
|
||||
* An array of theme names.
|
||||
@@ -1522,7 +1621,7 @@ function theme_enable($theme_list) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a given list of themes.
|
||||
* Disables a given list of themes.
|
||||
*
|
||||
* @param $theme_list
|
||||
* An array of theme names.
|
||||
@@ -1593,7 +1692,7 @@ function theme_status_messages($variables) {
|
||||
$output .= " </ul>\n";
|
||||
}
|
||||
else {
|
||||
$output .= $messages[0];
|
||||
$output .= reset($messages);
|
||||
}
|
||||
$output .= "</div>\n";
|
||||
}
|
||||
@@ -1608,15 +1707,33 @@ function theme_status_messages($variables) {
|
||||
* theme('link') for rendering the anchor tag.
|
||||
*
|
||||
* To optimize performance for sites that don't need custom theming of links,
|
||||
* the l() function includes an inline copy of this function, and uses that copy
|
||||
* if none of the enabled modules or the active theme implement any preprocess
|
||||
* or process functions or override this theme implementation.
|
||||
* the l() function includes an inline copy of this function, and uses that
|
||||
* 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>';
|
||||
@@ -1635,15 +1752,16 @@ function theme_link($variables) {
|
||||
* item in the links list.
|
||||
* - html: (optional) Whether or not 'title' is HTML. If set, the title
|
||||
* will not be passed through check_plain().
|
||||
* - attributes: (optional) Attributes for the anchor, or for the <span> tag
|
||||
* used in its place if no 'href' is supplied. If element 'class' is
|
||||
* - attributes: (optional) Attributes for the anchor, or for the <span>
|
||||
* tag used in its place if no 'href' is supplied. If element 'class' is
|
||||
* included, it must be an array of one or more class names.
|
||||
* If the 'href' element is supplied, the entire link array is passed to l()
|
||||
* as its $options parameter.
|
||||
* If the 'href' element is supplied, the entire link array is passed to
|
||||
* l() as its $options parameter.
|
||||
* - attributes: A keyed array of attributes for the UL containing the
|
||||
* list of links.
|
||||
* - heading: (optional) A heading to precede the links. May be an associative
|
||||
* array or a string. If it's an array, it can have the following elements:
|
||||
* - heading: (optional) A heading to precede the links. May be an
|
||||
* associative array or a string. If it's an array, it can have the
|
||||
* following elements:
|
||||
* - text: The heading text.
|
||||
* - level: The heading level (e.g. 'h2', 'h3').
|
||||
* - class: (optional) An array of the CSS classes for the heading.
|
||||
@@ -1665,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)) {
|
||||
@@ -1694,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';
|
||||
}
|
||||
@@ -1712,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']);
|
||||
}
|
||||
@@ -1747,8 +1865,8 @@ function theme_links($variables) {
|
||||
* attribute to be omitted in some cases. Therefore, this variable defaults
|
||||
* to an empty string, but can be set to NULL for the attribute to be
|
||||
* omitted. Usually, neither omission nor an empty string satisfies
|
||||
* accessibility requirements, so it is strongly encouraged for code calling
|
||||
* theme('image') to pass a meaningful value for this variable.
|
||||
* accessibility requirements, so it is strongly encouraged for code
|
||||
* calling theme('image') to pass a meaningful value for this variable.
|
||||
* - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
|
||||
* - http://www.w3.org/TR/xhtml1/dtds.html
|
||||
* - http://dev.w3.org/html5/spec/Overview.html#alt
|
||||
@@ -1801,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
|
||||
@@ -1960,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;
|
||||
}
|
||||
@@ -2005,7 +2124,8 @@ function theme_table($variables) {
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - style: Set to either 'asc' or 'desc', this determines which icon to show.
|
||||
* - style: Set to either 'asc' or 'desc', this determines which icon to
|
||||
* show.
|
||||
*/
|
||||
function theme_tablesort_indicator($variables) {
|
||||
if ($variables['style'] == "asc") {
|
||||
@@ -2069,10 +2189,12 @@ function theme_item_list($variables) {
|
||||
if (!empty($items)) {
|
||||
$output .= "<$type" . drupal_attributes($attributes) . '>';
|
||||
$num_items = count($items);
|
||||
foreach ($items as $i => $item) {
|
||||
$i = 0;
|
||||
foreach ($items as $item) {
|
||||
$attributes = array();
|
||||
$children = array();
|
||||
$data = '';
|
||||
$i++;
|
||||
if (is_array($item)) {
|
||||
foreach ($item as $key => $value) {
|
||||
if ($key == 'data') {
|
||||
@@ -2093,10 +2215,10 @@ function theme_item_list($variables) {
|
||||
// Render nested list.
|
||||
$data .= theme_item_list(array('items' => $children, 'title' => NULL, 'type' => $type, 'attributes' => $attributes));
|
||||
}
|
||||
if ($i == 0) {
|
||||
if ($i == 1) {
|
||||
$attributes['class'][] = 'first';
|
||||
}
|
||||
if ($i == $num_items - 1) {
|
||||
if ($i == $num_items) {
|
||||
$attributes['class'][] = 'last';
|
||||
}
|
||||
$output .= '<li' . drupal_attributes($attributes) . '>' . $data . "</li>\n";
|
||||
@@ -2112,7 +2234,7 @@ function theme_item_list($variables) {
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - url: The url for the link.
|
||||
* - url: The URL for the link.
|
||||
*/
|
||||
function theme_more_help_link($variables) {
|
||||
return '<div class="more-help-link">' . l(t('More help'), $variables['url']) . '</div>';
|
||||
@@ -2128,7 +2250,7 @@ function theme_more_help_link($variables) {
|
||||
* - title: A descriptive title of the feed.
|
||||
*/
|
||||
function theme_feed_icon($variables) {
|
||||
$text = t('Subscribe to @feed-title', array('@feed-title' => $variables['title']));
|
||||
$text = t('Subscribe to !feed-title', array('!feed-title' => $variables['title']));
|
||||
if ($image = theme('image', array('path' => 'misc/feed.png', 'width' => 16, 'height' => 16, 'alt' => $text))) {
|
||||
return l($image, $variables['url'], array('html' => TRUE, 'attributes' => array('class' => array('feed-icon'), 'title' => $text)));
|
||||
}
|
||||
@@ -2146,7 +2268,8 @@ function theme_feed_icon($variables) {
|
||||
* - script: To load JavaScript.
|
||||
* - #attributes: (optional) An array of HTML attributes to apply to the
|
||||
* tag.
|
||||
* - #value: (optional) A string containing tag content, such as inline CSS.
|
||||
* - #value: (optional) A string containing tag content, such as inline
|
||||
* CSS.
|
||||
* - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA
|
||||
* wrapper prefix.
|
||||
* - #value_suffix: (optional) A string to append to #value, e.g. a CDATA
|
||||
@@ -2177,7 +2300,7 @@ function theme_html_tag($variables) {
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - url: The url of the main page.
|
||||
* - url: The URL of the main page.
|
||||
* - title: A descriptive verb for the link, like 'Read more'.
|
||||
*/
|
||||
function theme_more_link($variables) {
|
||||
@@ -2314,8 +2437,9 @@ function template_preprocess(&$variables, $hook) {
|
||||
global $user;
|
||||
static $count = array();
|
||||
|
||||
// Track run count for each hook to provide zebra striping.
|
||||
// See "template_preprocess_block()" which provides the same feature specific to blocks.
|
||||
// Track run count for each hook to provide zebra striping. See
|
||||
// "template_preprocess_block()" which provides the same feature specific to
|
||||
// blocks.
|
||||
$count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
|
||||
$variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
|
||||
$variables['id'] = $count[$hook]++;
|
||||
@@ -2515,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.
|
||||
@@ -2675,13 +2802,13 @@ function theme_get_suggestions($args, $base, $delimiter = '__') {
|
||||
}
|
||||
|
||||
/**
|
||||
* The variables array generated here is a mirror of template_preprocess_page().
|
||||
* This preprocessor will run its course when theme_maintenance_page() is
|
||||
* invoked.
|
||||
* Process variables for maintenance-page.tpl.php.
|
||||
*
|
||||
* An alternate template file of "maintenance-page--offline.tpl.php" can be
|
||||
* used when the database is offline to hide errors and completely replace the
|
||||
* content.
|
||||
* The variables array generated here is a mirror of
|
||||
* template_preprocess_page(). This preprocessor will run its course when
|
||||
* theme_maintenance_page() is invoked. An alternate template file of
|
||||
* maintenance-page--offline.tpl.php can be used when the database is offline to
|
||||
* hide errors and completely replace the content.
|
||||
*
|
||||
* The $variables array contains the following arguments:
|
||||
* - $content
|
||||
@@ -2775,10 +2902,13 @@ function template_preprocess_maintenance_page(&$variables) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme process function for theme_maintenance_field().
|
||||
*
|
||||
* The variables array generated here is a mirror of template_process_html().
|
||||
* This processor will run its course when theme_maintenance_page() is invoked.
|
||||
*
|
||||
* @see maintenance-page.tpl.php
|
||||
* @see template_process_html()
|
||||
*/
|
||||
function template_process_maintenance_page(&$variables) {
|
||||
$variables['head'] = drupal_get_html_head();
|
||||
@@ -2790,7 +2920,7 @@ function template_process_maintenance_page(&$variables) {
|
||||
/**
|
||||
* Preprocess variables for region.tpl.php
|
||||
*
|
||||
* Prepare the values passed to the theme_region function to be passed into a
|
||||
* Prepares the values passed to the theme_region function to be passed into a
|
||||
* pluggable template engine. Uses the region name to generate a template file
|
||||
* suggestions. If none are found, the default region.tpl.php is used.
|
||||
*
|
||||
|
||||
Regular → Executable
+5
-5
@@ -10,9 +10,9 @@
|
||||
*
|
||||
* Used for site installs, updates and when the site is in maintenance mode.
|
||||
* It also applies when the database is unavailable or bootstrap was not
|
||||
* complete. Seven is always used for the initial install and update operations.
|
||||
* In other cases, Bartik is used, but this can be overridden by setting a
|
||||
* "maintenance_theme" key in the $conf variable in settings.php.
|
||||
* complete. Seven is always used for the initial install and update
|
||||
* operations. In other cases, Bartik is used, but this can be overridden by
|
||||
* setting a "maintenance_theme" key in the $conf variable in settings.php.
|
||||
*/
|
||||
function _drupal_maintenance_theme() {
|
||||
global $theme, $theme_key, $conf;
|
||||
@@ -85,7 +85,7 @@ function _drupal_maintenance_theme() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This builds the registry when the site needs to bypass any database calls.
|
||||
* Builds the registry when the site needs to bypass any database calls.
|
||||
*/
|
||||
function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) {
|
||||
return _theme_build_registry($theme, $base_theme, $theme_engine);
|
||||
@@ -160,7 +160,7 @@ function theme_update_page($variables) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for a report of the results from an operation run via authorize.php.
|
||||
* Returns HTML for a results report of an operation run by authorize.php.
|
||||
*
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
|
||||
Regular → Executable
+10
-8
@@ -113,13 +113,13 @@ function token_replace($text, array $data = array(), array $options = array()) {
|
||||
*/
|
||||
function token_scan($text) {
|
||||
// Matches tokens with the following pattern: [$type:$name]
|
||||
// $type and $name may not contain [ ] or whitespace characters.
|
||||
// $type may not contain : characters, but $name may.
|
||||
// $type and $name may not contain [ ] characters.
|
||||
// $type may not contain : or whitespace characters, but $name may.
|
||||
preg_match_all('/
|
||||
\[ # [ - pattern start
|
||||
([^\s\[\]:]*) # match $type not containing whitespace : [ or ]
|
||||
: # : - separator
|
||||
([^\s\[\]]*) # match $name not containing whitespace [ or ]
|
||||
([^\[\]]*) # match $name not containing [ or ]
|
||||
\] # ] - pattern end
|
||||
/x', $text, $matches);
|
||||
|
||||
@@ -190,10 +190,10 @@ function token_generate($type, array $tokens, array $data = array(), array $opti
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of tokens, returns those that begin with a specific prefix.
|
||||
* Returns a list of tokens that begin with a specific prefix.
|
||||
*
|
||||
* Used to extract a group of 'chained' tokens (such as [node:author:name]) from
|
||||
* the full list of tokens found in text. For example:
|
||||
* Used to extract a group of 'chained' tokens (such as [node:author:name])
|
||||
* from the full list of tokens found in text. For example:
|
||||
* @code
|
||||
* $data = array(
|
||||
* 'author:name' => '[node:author:name]',
|
||||
@@ -230,8 +230,10 @@ function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') {
|
||||
/**
|
||||
* Returns metadata describing supported tokens.
|
||||
*
|
||||
* The metadata array contains token type, name, and description data as well as
|
||||
* an optional pointer indicating that the token chains to another set of tokens.
|
||||
* The metadata array contains token type, name, and description data as well
|
||||
* as an optional pointer indicating that the token chains to another set of
|
||||
* tokens.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* $data['types']['node'] = array(
|
||||
|
||||
Regular → Executable
Regular → Executable
+114
-39
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides Unicode-related conversions and operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates an error during check for PHP unicode support.
|
||||
*/
|
||||
@@ -19,8 +24,6 @@ define('UNICODE_MULTIBYTE', 1);
|
||||
/**
|
||||
* Matches Unicode characters that are word boundaries.
|
||||
*
|
||||
* @see http://unicode.org/glossary
|
||||
*
|
||||
* Characters with the following General_category (gc) property values are used
|
||||
* as word boundaries. While this does not fully conform to the Word Boundaries
|
||||
* algorithm described in http://unicode.org/reports/tr29, as PCRE does not
|
||||
@@ -39,6 +42,8 @@ define('UNICODE_MULTIBYTE', 1);
|
||||
* Note that the PCRE property matcher is not used because we wanted to be
|
||||
* compatible with Unicode 5.2.0 regardless of the PCRE version used (and any
|
||||
* bugs in PCRE property tables).
|
||||
*
|
||||
* @see http://unicode.org/glossary
|
||||
*/
|
||||
define('PREG_CLASS_UNICODE_WORD_BOUNDARY',
|
||||
'\x{0}-\x{2F}\x{3A}-\x{40}\x{5B}-\x{60}\x{7B}-\x{A9}\x{AB}-\x{B1}\x{B4}' .
|
||||
@@ -96,7 +101,7 @@ function unicode_check() {
|
||||
* Whether to report any fatal errors with form_set_error().
|
||||
*/
|
||||
function _unicode_check() {
|
||||
// Ensure translations don't break at install time
|
||||
// Ensure translations don't break during installation.
|
||||
$t = get_t();
|
||||
|
||||
// Check for mbstring extension
|
||||
@@ -111,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
|
||||
@@ -125,10 +134,10 @@ function _unicode_check() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Unicode library status and errors.
|
||||
* Returns Unicode library status and errors.
|
||||
*/
|
||||
function unicode_requirements() {
|
||||
// Ensure translations don't break at install time
|
||||
// Ensure translations don't break during installation.
|
||||
$t = get_t();
|
||||
|
||||
$libraries = array(
|
||||
@@ -157,14 +166,14 @@ function unicode_requirements() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a new XML parser.
|
||||
* Prepares a new XML parser.
|
||||
*
|
||||
* This is a wrapper around xml_parser_create() which extracts the encoding from
|
||||
* the XML data first and sets the output encoding to UTF-8. This function should
|
||||
* be used instead of xml_parser_create(), because PHP 4's XML parser doesn't
|
||||
* check the input encoding itself. "Starting from PHP 5, the input encoding is
|
||||
* automatically detected, so that the encoding parameter specifies only the
|
||||
* output encoding."
|
||||
* This is a wrapper around xml_parser_create() which extracts the encoding
|
||||
* from the XML data first and sets the output encoding to UTF-8. This function
|
||||
* should be used instead of xml_parser_create(), because PHP 4's XML parser
|
||||
* doesn't check the input encoding itself. "Starting from PHP 5, the input
|
||||
* encoding is automatically detected, so that the encoding parameter specifies
|
||||
* only the output encoding."
|
||||
*
|
||||
* This is also where unsupported encodings will be converted. Callers should
|
||||
* take this into account: $data might have been changed after the call.
|
||||
@@ -213,7 +222,7 @@ function drupal_xml_parser_create(&$data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to UTF-8
|
||||
* Converts data to UTF-8.
|
||||
*
|
||||
* Requires the iconv, GNU recode or mbstring PHP extension.
|
||||
*
|
||||
@@ -244,15 +253,15 @@ function drupal_convert_to_utf8($data, $encoding) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a UTF-8-encoded string safely to a number of bytes.
|
||||
* Truncates a UTF-8-encoded string safely to a number of bytes.
|
||||
*
|
||||
* If the end position is in the middle of a UTF-8 sequence, it scans backwards
|
||||
* until the beginning of the byte sequence.
|
||||
*
|
||||
* Use this function whenever you want to chop off a string at an unsure
|
||||
* location. On the other hand, if you're sure that you're splitting on a
|
||||
* character boundary (e.g. after using strpos() or similar), you can safely use
|
||||
* substr() instead.
|
||||
* character boundary (e.g. after using strpos() or similar), you can safely
|
||||
* use substr() instead.
|
||||
*
|
||||
* @param $string
|
||||
* The string to truncate.
|
||||
@@ -306,7 +315,7 @@ function drupal_truncate_bytes($string, $len) {
|
||||
* boundaries, giving you "See myverylongurl..." (assuming you had set
|
||||
* $add_ellipses to TRUE).
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The truncated string.
|
||||
*/
|
||||
function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis = FALSE, $min_wordsafe_length = 1) {
|
||||
@@ -356,8 +365,7 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes MIME/HTTP header values that contain non-ASCII, UTF-8 encoded
|
||||
* characters.
|
||||
* Encodes MIME/HTTP header values that contain incorrectly encoded characters.
|
||||
*
|
||||
* For example, mime_header_encode('tést.txt') returns "=?UTF-8?B?dMOpc3QudHh0?=".
|
||||
*
|
||||
@@ -369,6 +377,14 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
|
||||
* each chunk starts and ends on a character boundary.
|
||||
* - Using \n as the chunk separator may cause problems on some systems and may
|
||||
* have to be changed to \r\n or \r.
|
||||
*
|
||||
* @param $string
|
||||
* The header to encode.
|
||||
*
|
||||
* @return string
|
||||
* The mime-encoded header.
|
||||
*
|
||||
* @see mime_header_decode()
|
||||
*/
|
||||
function mime_header_encode($string) {
|
||||
if (preg_match('/[^\x20-\x7E]/', $string)) {
|
||||
@@ -388,7 +404,15 @@ function mime_header_encode($string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Complement to mime_header_encode
|
||||
* Decodes MIME/HTTP encoded header values.
|
||||
*
|
||||
* @param $header
|
||||
* The header to decode.
|
||||
*
|
||||
* @return string
|
||||
* The mime-decoded header.
|
||||
*
|
||||
* @see mime_header_encode()
|
||||
*/
|
||||
function mime_header_decode($header) {
|
||||
// First step: encoded chunks followed by other encoded chunks (need to collapse whitespace)
|
||||
@@ -398,7 +422,17 @@ function mime_header_decode($header) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to mime_header_decode
|
||||
* Decodes encoded header data passed from mime_header_decode().
|
||||
*
|
||||
* Callback for preg_replace_callback() within mime_header_decode().
|
||||
*
|
||||
* @param $matches
|
||||
* The array of matches from preg_replace_callback().
|
||||
*
|
||||
* @return string
|
||||
* The mime-decoded string.
|
||||
*
|
||||
* @see mime_header_decode()
|
||||
*/
|
||||
function _mime_header_decode($matches) {
|
||||
// Regexp groups:
|
||||
@@ -415,9 +449,9 @@ function _mime_header_decode($matches) {
|
||||
/**
|
||||
* Decodes all HTML entities (including numerical ones) to regular UTF-8 bytes.
|
||||
*
|
||||
* Double-escaped entities will only be decoded once ("&lt;" becomes "<",
|
||||
* not "<"). Be careful when using this function, as decode_entities can revert
|
||||
* previous sanitization efforts (<script> will become <script>).
|
||||
* Double-escaped entities will only be decoded once ("&lt;" becomes "<"
|
||||
* , not "<"). Be careful when using this function, as decode_entities can
|
||||
* revert previous sanitization efforts (<script> will become <script>).
|
||||
*
|
||||
* @param $text
|
||||
* The text to decode entities in.
|
||||
@@ -430,8 +464,15 @@ function decode_entities($text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the amount of characters in a UTF-8 string. This is less than or
|
||||
* equal to the byte count.
|
||||
* Counts the number of characters in a UTF-8 string.
|
||||
*
|
||||
* This is less than or equal to the byte count.
|
||||
*
|
||||
* @param $text
|
||||
* The string to run the operation on.
|
||||
*
|
||||
* @return integer
|
||||
* The length of the string.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
@@ -449,6 +490,12 @@ function drupal_strlen($text) {
|
||||
/**
|
||||
* Uppercase a UTF-8 string.
|
||||
*
|
||||
* @param $text
|
||||
* The string to run the operation on.
|
||||
*
|
||||
* @return string
|
||||
* The string in uppercase.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
function drupal_strtoupper($text) {
|
||||
@@ -468,6 +515,12 @@ function drupal_strtoupper($text) {
|
||||
/**
|
||||
* Lowercase a UTF-8 string.
|
||||
*
|
||||
* @param $text
|
||||
* The string to run the operation on.
|
||||
*
|
||||
* @return string
|
||||
* The string in lowercase.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
function drupal_strtolower($text) {
|
||||
@@ -485,15 +538,28 @@ function drupal_strtolower($text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for case conversion of Latin-1.
|
||||
* Used for flipping U+C0-U+DE to U+E0-U+FD and back.
|
||||
* Flips U+C0-U+DE to U+E0-U+FD and back.
|
||||
*
|
||||
* @param $matches
|
||||
* An array of matches.
|
||||
*
|
||||
* @return array
|
||||
* The Latin-1 version of the array of matches.
|
||||
*
|
||||
* @see drupal_strtolower()
|
||||
*/
|
||||
function _unicode_caseflip($matches) {
|
||||
return $matches[0][0] . chr(ord($matches[0][1]) ^ 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalize the first letter of a UTF-8 string.
|
||||
* Capitalizes the first letter of a UTF-8 string.
|
||||
*
|
||||
* @param $text
|
||||
* The string to convert.
|
||||
*
|
||||
* @return
|
||||
* The string with the first letter as uppercase.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
@@ -503,12 +569,21 @@ function drupal_ucfirst($text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut off a piece of a string based on character indices and counts. Follows
|
||||
* the same behavior as PHP's own substr() function.
|
||||
* Cuts off a piece of a string based on character indices and counts.
|
||||
*
|
||||
* Note that for cutting off a string at a known character/substring
|
||||
* location, the usage of PHP's normal strpos/substr is safe and
|
||||
* much faster.
|
||||
* Follows the same behavior as PHP's own substr() function. Note that for
|
||||
* cutting off a string at a known character/substring location, the usage of
|
||||
* PHP's normal strpos/substr is safe and much faster.
|
||||
*
|
||||
* @param $text
|
||||
* The input string.
|
||||
* @param $start
|
||||
* The position at which to start reading.
|
||||
* @param $length
|
||||
* The number of characters to read.
|
||||
*
|
||||
* @return
|
||||
* The shortened string.
|
||||
*
|
||||
* @ingroup php_wrappers
|
||||
*/
|
||||
|
||||
Regular → Executable
+28
-29
@@ -38,7 +38,7 @@ function update_fix_compatibility() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to test compatibility of a module or theme.
|
||||
* Tests the compatibility of a module or theme.
|
||||
*/
|
||||
function update_check_incompatibility($name, $type = 'module') {
|
||||
static $themes, $modules;
|
||||
@@ -785,16 +785,24 @@ function update_fix_d7_requirements() {
|
||||
/**
|
||||
* Register the currently installed profile in the system table.
|
||||
*
|
||||
* Install profiles are now treated as modules by Drupal, and have an upgrade
|
||||
* path based on their schema version in the system table.
|
||||
* Installation profiles are now treated as modules by Drupal, and have an
|
||||
* upgrade path based on their schema version in the system table.
|
||||
*
|
||||
* The install profile will be set to schema_version 0, as it has already been
|
||||
* installed. Any other hook_update_N functions provided by the install profile
|
||||
* will be run by update.php.
|
||||
* The installation profile will be set to schema_version 0, as it has already
|
||||
* been installed. Any other hook_update_N functions provided by the
|
||||
* installation profile will be run by update.php.
|
||||
*/
|
||||
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)
|
||||
@@ -828,10 +836,10 @@ function update_fix_d7_install_profile() {
|
||||
'owner' => '',
|
||||
);
|
||||
|
||||
// Install profile hooks are always executed last by the module system
|
||||
// Installation profile hooks are always executed last by the module system
|
||||
$values['weight'] = 1000;
|
||||
|
||||
// Initializing the system table entry for the install profile
|
||||
// Initializing the system table entry for the installation profile
|
||||
db_insert('system')
|
||||
->fields(array_keys($values))
|
||||
->values($values)
|
||||
@@ -840,7 +848,8 @@ function update_fix_d7_install_profile() {
|
||||
// Reset the cached schema version.
|
||||
drupal_get_installed_schema_version($profile, TRUE);
|
||||
|
||||
// Load the updates again to make sure the install profile updates are loaded
|
||||
// Load the updates again to make sure the installation profile updates
|
||||
// are loaded.
|
||||
drupal_load_updates();
|
||||
}
|
||||
}
|
||||
@@ -895,7 +904,7 @@ function update_get_d6_session_name() {
|
||||
}
|
||||
else {
|
||||
// Otherwise use $base_url as session name, without the protocol
|
||||
// to use the same session identifiers across http and https.
|
||||
// to use the same session identifiers across HTTP and HTTPS.
|
||||
list( , $session_name) = explode('://', $base_url, 2);
|
||||
}
|
||||
|
||||
@@ -907,7 +916,9 @@ function update_get_d6_session_name() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform one update and store the results for display on finished page.
|
||||
* 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
|
||||
* as a string indicating success, for example:
|
||||
@@ -1007,7 +1018,7 @@ function update_do_one($module, $number, $dependency_map, &$context) {
|
||||
class DrupalUpdateException extends Exception { }
|
||||
|
||||
/**
|
||||
* Start the database update batch process.
|
||||
* Starts the database update batch process.
|
||||
*
|
||||
* @param $start
|
||||
* An array whose keys contain the names of modules to be updated during the
|
||||
@@ -1077,7 +1088,9 @@ function update_batch($start, $redirect = NULL, $url = NULL, $batch = array(), $
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the update process and store results for eventual display.
|
||||
* 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
|
||||
* stored into the session (for example, to be displayed on the update results
|
||||
@@ -1114,7 +1127,7 @@ function update_finished($success, $results, $operations) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all the pending database updates.
|
||||
* Returns a list of all the pending database updates.
|
||||
*
|
||||
* @return
|
||||
* An associative array keyed by module name which contains all information
|
||||
@@ -1408,7 +1421,7 @@ function update_already_performed($module, $number) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke hook_update_dependencies() in all installed modules.
|
||||
* Invokes hook_update_dependencies() in all installed modules.
|
||||
*
|
||||
* This function is similar to module_invoke_all(), with the main difference
|
||||
* that it does not require that a module be enabled to invoke its hook, only
|
||||
@@ -1474,17 +1487,3 @@ function update_retrieve_dependencies() {
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup update-api-6.x-to-7.x Update versions of API functions
|
||||
* @{
|
||||
* Functions similar to normal API function but not firing hooks.
|
||||
*
|
||||
* During update, it is impossible to judge the consequences of firing a hook
|
||||
* as it might hit a module not yet updated. So simplified versions of some
|
||||
* core APIs are provided.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @} End of "defgroup update-api-6.x-to-7.x".
|
||||
*/
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
@@ -12,6 +12,7 @@
|
||||
* The variable to export.
|
||||
* @param $prefix
|
||||
* A prefix that will be added at the beginning of every lines of the output.
|
||||
*
|
||||
* @return
|
||||
* The variable exported in a way compatible to Drupal's coding standards.
|
||||
*/
|
||||
|
||||
Regular → Executable
+35
-1
@@ -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);
|
||||
|
||||
Regular → Executable
+11
-1
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,12 +6,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Root directory of Drupal installation.
|
||||
* Defines the root directory of the Drupal installation.
|
||||
*/
|
||||
define('DRUPAL_ROOT', getcwd());
|
||||
|
||||
/**
|
||||
* Global flag to indicate that site is in installation mode.
|
||||
* Global flag to indicate the site is in installation mode.
|
||||
*/
|
||||
define('MAINTENANCE_MODE', 'install');
|
||||
|
||||
|
||||
@@ -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);
|
||||
Executable
+81
@@ -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>
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": "/Users/bachir/Sites/materio/base_d7"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,807 +0,0 @@
|
||||
{
|
||||
"auto_complete":
|
||||
{
|
||||
"selected_items":
|
||||
[
|
||||
[
|
||||
"font",
|
||||
"font-size"
|
||||
],
|
||||
[
|
||||
"mat",
|
||||
"matches"
|
||||
],
|
||||
[
|
||||
"preg",
|
||||
"preg_match"
|
||||
],
|
||||
[
|
||||
"ima",
|
||||
"images"
|
||||
],
|
||||
[
|
||||
"alt",
|
||||
"images_alts"
|
||||
],
|
||||
[
|
||||
"titles",
|
||||
"images_titles"
|
||||
],
|
||||
[
|
||||
"for",
|
||||
"foreach foreach …"
|
||||
],
|
||||
[
|
||||
"field",
|
||||
"field_imago_list"
|
||||
],
|
||||
[
|
||||
"query",
|
||||
"query_translated"
|
||||
],
|
||||
[
|
||||
"que",
|
||||
"query_neu"
|
||||
],
|
||||
[
|
||||
"su",
|
||||
"summary"
|
||||
],
|
||||
[
|
||||
"ti",
|
||||
"title"
|
||||
],
|
||||
[
|
||||
"ar",
|
||||
"args"
|
||||
],
|
||||
[
|
||||
"materio",
|
||||
"materio_search_api"
|
||||
],
|
||||
[
|
||||
"key",
|
||||
"keys"
|
||||
],
|
||||
[
|
||||
"form",
|
||||
"form_state"
|
||||
],
|
||||
[
|
||||
"mater",
|
||||
"materiobase"
|
||||
],
|
||||
[
|
||||
"cal",
|
||||
"callback"
|
||||
],
|
||||
[
|
||||
"fo",
|
||||
"form"
|
||||
],
|
||||
[
|
||||
"ty",
|
||||
"typed"
|
||||
],
|
||||
[
|
||||
"fun",
|
||||
"function"
|
||||
],
|
||||
[
|
||||
"min",
|
||||
"min-width"
|
||||
],
|
||||
[
|
||||
"ba",
|
||||
"background-position"
|
||||
]
|
||||
]
|
||||
},
|
||||
"buffers":
|
||||
[
|
||||
{
|
||||
"file": "sites/all/themes/gui/materiobasetheme/less/layout.less",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 704,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/themes/gui/materiobasetheme/less/styles.less",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1269,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/modules/gui/materiobasemod/materio_search_api_ajax.module",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1075,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/modules/gui/materiobasemod/js/materio_search_api_ajax.js",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3132,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/modules/contrib/search/search_api_page/search_api_page.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 8151,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/modules/contrib/search/search_api_ajax/search_api_ajax.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3972,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/modules/contrib/search/search_api_autocomplete/search_api_autocomplete.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3419,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "sites/all/themes/gui/materiobasetheme/js/script.js",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1120,
|
||||
"line_ending": "Unix"
|
||||
}
|
||||
}
|
||||
],
|
||||
"build_system": "",
|
||||
"command_palette":
|
||||
{
|
||||
"height": 49.0,
|
||||
"selected_items":
|
||||
[
|
||||
[
|
||||
"docu",
|
||||
"Goto Documentation"
|
||||
],
|
||||
[
|
||||
"todo",
|
||||
"Show TODOs: Open files only"
|
||||
],
|
||||
[
|
||||
"install",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"package",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"in",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"pack",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"goto",
|
||||
"Goto Documentation"
|
||||
],
|
||||
[
|
||||
"packa",
|
||||
"Package Control: List Packages"
|
||||
],
|
||||
[
|
||||
"do",
|
||||
"Goto Documentation"
|
||||
],
|
||||
[
|
||||
"doc",
|
||||
"Goto Documentation"
|
||||
],
|
||||
[
|
||||
"inst",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"go",
|
||||
"Goto Documentation"
|
||||
],
|
||||
[
|
||||
"packe",
|
||||
"Package Control: Remove Package"
|
||||
],
|
||||
[
|
||||
"insta",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"side",
|
||||
"View: Toggle Side Bar"
|
||||
],
|
||||
[
|
||||
"pac",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"git",
|
||||
"Git: Fetch"
|
||||
],
|
||||
[
|
||||
"pa",
|
||||
"Package Control: Install Package"
|
||||
],
|
||||
[
|
||||
"Package CO",
|
||||
"Package Control: Install Package"
|
||||
]
|
||||
],
|
||||
"width": 588.0
|
||||
},
|
||||
"console":
|
||||
{
|
||||
"height": 132.0
|
||||
},
|
||||
"distraction_free":
|
||||
{
|
||||
"menu_visible": true,
|
||||
"show_minimap": false,
|
||||
"show_open_files": false,
|
||||
"show_tabs": false,
|
||||
"side_bar_visible": false,
|
||||
"status_bar_visible": false
|
||||
},
|
||||
"file_history":
|
||||
[
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/users/ajax_register/ajax_register.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/users/ajax_register/ajax_register.pages.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api.info",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api_ajax.info",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/materiobasetheme.info",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/less/misc.less",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/templates/page.tpl.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api.pages.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/js/materio_search_api_ajax.js",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api_ajax.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api_ajax.pages.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/js/script.js",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/less/layout.less",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/less/styles.less",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api.module",
|
||||
"/Users/bachir/Library/Application Support/Sublime Text 2/Packages/User/Default (OSX).sublime-keymap",
|
||||
"/Users/bachir/Sites/materio/base_d7/ac_select_event-365241-54.patch",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/preprocess/page.pre.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/css/styles.css",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/js/materiobaseajax-ck.js",
|
||||
"/Users/bachir/Library/Application Support/Sublime Text 2/Packages/User/Preferences.sublime-settings",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference-1.0-rc1/plugins/selection/EntityReference_SelectionHandler_Generic.class.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/entityreference-user-role-status-filters-1354482-9.patch",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/plugins/behavior/EntityReferenceBehavior_ViewsFilterSelect.class.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/patch url.txt",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/patch url",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/fields/entityreference/README.txt",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materio_search_api.admin.inc",
|
||||
"/Users/bachir/Library/Application Support/Sublime Text 2/Packages/Default/Default (OSX).sublime-keymap",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api_solr/service.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.info",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.company.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.basic.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.materiau.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.breves.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/print-query.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/sb.basebeta.materio.com/settings.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/default/settings.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/migrate_materio/migrate_materio.admin.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/js/materiobaseajax.js",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materiobaseajax.pages.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api_page/search_api_page.pages.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api/search_api.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api_page/search_api_page.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/materiobaseajax.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api_page/search_api_page.admin.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/materio.sublime-project",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/editmenu/editmenu.admin.inc",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/editmenu/editmenu.module",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/contrib/search/search_api/search_api.api.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/templates/materiobase-results.tpl.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/templates/search-api-page-results.tpl.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/modules/gui/materiobasemod/templates/materiobase-search-block.tpl.php",
|
||||
"/Users/bachir/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/inc/template.theme-overrides.inc",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/modules/contrib/views/views_field_view/views_field_view_handler_field_view.inc",
|
||||
"/Users/bachir/Sites/kadist.org/_kadist.sublime-project",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/PkgInfo",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/version.plist",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/Info.plist",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/MacOS/GeForce",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/_CodeSignature/CodeDirectory",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/_CodeSignature/CodeRequirements",
|
||||
"/System/Library/Extensions/GeForce.kext/Contents/_CodeSignature/CodeResources",
|
||||
"/Users/bachir/Sites/apache.tmproj",
|
||||
"/Users/bachir/Sites/lesveilleursderennes.com/sites/all/themes/custom/lesveilleursderennes/templates/calendar-month-node.tpl.php",
|
||||
"/Users/bachir/Sites/lesveilleursderennes.com/_leslveilleursderennes.sublime-project",
|
||||
"/Volumes/mbp_bach_72hd/Documents/__taff/leslabos/2012/backup kimsufi/mysqldumps/cleanroom.sql",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/modules/gui/location_filter/location_filter.module",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/modules/gui/kadistqueries/plugins/content_types/kadistqueries_medium_pane.inc",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/less/kadist.less",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/modules/gui/kadistqueries/plugins/content_types/kadistqueries_artistes_pane.inc",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/modules/gui/kadistqueries/kadistqueries.module",
|
||||
"/Users/bachir/Library/Application Support/Sublime Text 2/Packages/User/goToSideBar.py",
|
||||
"/Users/bachir/Sites/kadist.org/sites/kadist.org/drushrc.php",
|
||||
"/Users/bachir/Library/Application Support/Sublime Text 2/Packages/Default/Preferences.sublime-settings",
|
||||
"/Users/bachir/Sites/kadist.org/.htaccess",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/templates/block--menu-bar.tpl.php",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/templates/block--search.tpl.php",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/preprocess/block.pre.php",
|
||||
"/Users/bachir/Sites/kadist.org/MAINTAINERS.txt",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/preprocess/search-result.pre.php",
|
||||
"/Users/bachir/Sites/kadist.org/sites/all/themes/gui/kadist/preprocess/page.pre.php"
|
||||
],
|
||||
"find":
|
||||
{
|
||||
"height": 35.0
|
||||
},
|
||||
"find_in_files":
|
||||
{
|
||||
"height": 0.0,
|
||||
"where_history":
|
||||
[
|
||||
""
|
||||
]
|
||||
},
|
||||
"find_state":
|
||||
{
|
||||
"case_sensitive": false,
|
||||
"find_history":
|
||||
[
|
||||
"materiobaseajax",
|
||||
"sublime",
|
||||
"materio_search_api",
|
||||
"page",
|
||||
"width",
|
||||
"An",
|
||||
"function materiobasemod",
|
||||
"hello world",
|
||||
"location_filter_item",
|
||||
"dsm",
|
||||
"leslabos",
|
||||
"leslabosblock-typo",
|
||||
"block-typo",
|
||||
"\n()",
|
||||
"location_filter_block_info",
|
||||
"function",
|
||||
"super+k",
|
||||
"super+alt+0",
|
||||
"f1",
|
||||
"fold",
|
||||
"width",
|
||||
"focus",
|
||||
"side",
|
||||
"file",
|
||||
"reve",
|
||||
"reveal",
|
||||
"side"
|
||||
],
|
||||
"highlight": true,
|
||||
"in_selection": false,
|
||||
"preserve_case": false,
|
||||
"regex": false,
|
||||
"replace_history":
|
||||
[
|
||||
"materio_search_api_ajax",
|
||||
"function materio_search_api"
|
||||
],
|
||||
"reverse": false,
|
||||
"show_context": true,
|
||||
"use_buffer2": true,
|
||||
"whole_word": false,
|
||||
"wrap": true
|
||||
},
|
||||
"groups":
|
||||
[
|
||||
{
|
||||
"selected": 5,
|
||||
"sheets":
|
||||
[
|
||||
{
|
||||
"buffer": 0,
|
||||
"file": "sites/all/themes/gui/materiobasetheme/less/layout.less",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 704,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
704,
|
||||
704
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "ca87ca81",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/LESS/LESS.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 0.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 1,
|
||||
"file": "sites/all/themes/gui/materiobasetheme/less/styles.less",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1269,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
422,
|
||||
422
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "9ad02ee5",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/LESS/LESS.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 0.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 2,
|
||||
"file": "sites/all/modules/gui/materiobasemod/materio_search_api_ajax.module",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1075,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
487,
|
||||
487
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "7c9ae530",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/HTML/HTML.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 0.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 3,
|
||||
"file": "sites/all/modules/gui/materiobasemod/js/materio_search_api_ajax.js",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3132,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
2039,
|
||||
2039
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "afdc4774",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/JavaScript/JavaScript.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 768.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 4,
|
||||
"file": "sites/all/modules/contrib/search/search_api_page/search_api_page.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 8151,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
3168,
|
||||
3168
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "7e3a7836",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/HTML/HTML.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 0.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 5,
|
||||
"file": "sites/all/modules/contrib/search/search_api_ajax/search_api_ajax.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3972,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
2007,
|
||||
2040
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "b86e8334",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/HTML/HTML.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 581.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 6,
|
||||
"file": "sites/all/modules/contrib/search/search_api_autocomplete/search_api_autocomplete.pages.inc",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 3419,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "72908de8",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/HTML/HTML.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 615.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"buffer": 7,
|
||||
"file": "sites/all/themes/gui/materiobasetheme/js/script.js",
|
||||
"settings":
|
||||
{
|
||||
"buffer_size": 1120,
|
||||
"regions":
|
||||
{
|
||||
},
|
||||
"selection":
|
||||
[
|
||||
[
|
||||
21,
|
||||
21
|
||||
]
|
||||
],
|
||||
"settings":
|
||||
{
|
||||
"buffer_scroll_name": "6067f9fe",
|
||||
"incomplete_sync": null,
|
||||
"remote_loading": false,
|
||||
"synced": false,
|
||||
"syntax": "Packages/JavaScript/JavaScript.tmLanguage",
|
||||
"tab_size": 2,
|
||||
"translate_tabs_to_spaces": true
|
||||
},
|
||||
"translation.x": 0.0,
|
||||
"translation.y": 0.0,
|
||||
"zoom_level": 1.0
|
||||
},
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"incremental_find":
|
||||
{
|
||||
"height": 0.0
|
||||
},
|
||||
"input":
|
||||
{
|
||||
"height": 35.0
|
||||
},
|
||||
"layout":
|
||||
{
|
||||
"cells":
|
||||
[
|
||||
[
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1
|
||||
]
|
||||
],
|
||||
"cols":
|
||||
[
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"rows":
|
||||
[
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"menu_visible": true,
|
||||
"output.exec":
|
||||
{
|
||||
"height": 124.0
|
||||
},
|
||||
"output.git":
|
||||
{
|
||||
"height": 106.0
|
||||
},
|
||||
"output.sftp":
|
||||
{
|
||||
"height": 0.0
|
||||
},
|
||||
"replace":
|
||||
{
|
||||
"height": 66.0
|
||||
},
|
||||
"save_all_on_build": true,
|
||||
"select_file":
|
||||
{
|
||||
"height": 0.0,
|
||||
"selected_items":
|
||||
[
|
||||
[
|
||||
"select",
|
||||
"ac_select_event-365241-54.patch"
|
||||
],
|
||||
[
|
||||
"service",
|
||||
"sites/all/modules/contrib/search/search_api_solr/service.inc"
|
||||
],
|
||||
[
|
||||
".less",
|
||||
"sites/all/themes/gui/kadist/less/kadist.less"
|
||||
],
|
||||
[
|
||||
"progra",
|
||||
"sites/all/modules/gui/location_filter/programs.module"
|
||||
],
|
||||
[
|
||||
"font",
|
||||
"sites/all/themes/gui/kadist/less/fonts.less"
|
||||
],
|
||||
[
|
||||
"less",
|
||||
"sites/all/themes/gui/kadist/less/kadist.less"
|
||||
],
|
||||
[
|
||||
"querie",
|
||||
"sites/all/modules/gui/kadistqueries/plugins/content_types/kadistqueries_artistes_pane.inc"
|
||||
],
|
||||
[
|
||||
"kadist.less",
|
||||
"sites/all/themes/gui/kadist/less/kadist.less"
|
||||
],
|
||||
[
|
||||
"block--menu",
|
||||
"sites/all/themes/gui/kadist/templates/block--menu-bar.tpl.php"
|
||||
],
|
||||
[
|
||||
"prepro",
|
||||
"sites/all/themes/gui/kadist/preprocess/block.pre.php"
|
||||
],
|
||||
[
|
||||
"kadist.le",
|
||||
"sites/all/themes/gui/kadist/less/kadist.less"
|
||||
],
|
||||
[
|
||||
"",
|
||||
".htaccess"
|
||||
],
|
||||
[
|
||||
"preprocess",
|
||||
"sites/all/themes/gui/kadist/preprocess/search-result.pre.php"
|
||||
],
|
||||
[
|
||||
"kadis.less",
|
||||
"sites/all/themes/gui/kadist/less/kadist.less"
|
||||
]
|
||||
],
|
||||
"width": 0.0
|
||||
},
|
||||
"select_project":
|
||||
{
|
||||
"height": 500.0,
|
||||
"selected_items":
|
||||
[
|
||||
[
|
||||
"",
|
||||
"/Users/bachir/Sites/kadist.org/kadist.sublime-project"
|
||||
]
|
||||
],
|
||||
"width": 380.0
|
||||
},
|
||||
"show_minimap": true,
|
||||
"show_open_files": false,
|
||||
"show_tabs": true,
|
||||
"side_bar_visible": true,
|
||||
"side_bar_width": 357.0,
|
||||
"status_bar_visible": true
|
||||
}
|
||||
Regular → Executable
+63
-8
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +424,7 @@ Drupal.ajax.prototype.success = function (response, status) {
|
||||
Drupal.freezeHeight();
|
||||
|
||||
for (var i in response) {
|
||||
if (response[i]['command'] && this.commands[response[i]['command']]) {
|
||||
if (response.hasOwnProperty(i) && response[i]['command'] && this.commands[response[i]['command']]) {
|
||||
this.commands[response[i]['command']](this, response[i], status);
|
||||
}
|
||||
}
|
||||
@@ -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']);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Regular → Executable
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
Regular → Executable
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
Regular → Executable
Regular → Executable
+9
-5
@@ -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)
|
||||
@@ -270,8 +271,11 @@ Drupal.ACDB.prototype.search = function (searchString) {
|
||||
var db = this;
|
||||
this.searchString = searchString;
|
||||
|
||||
// See if this string needs to be searched for anyway.
|
||||
searchString = searchString.replace(/^\s+|\s+$/, '');
|
||||
// See if this string needs to be searched for anyway. The pattern ../ is
|
||||
// stripped since it may be misinterpreted by the browser.
|
||||
searchString = searchString.replace(/^\s+|\.{2,}\/|\s+$/g, '');
|
||||
// Skip empty search strings, or search strings ending with a comma, since
|
||||
// that is the separator between search terms.
|
||||
if (searchString.length <= 0 ||
|
||||
searchString.charAt(searchString.length - 1) == ',') {
|
||||
return;
|
||||
@@ -306,7 +310,7 @@ Drupal.ACDB.prototype.search = function (searchString) {
|
||||
}
|
||||
},
|
||||
error: function (xmlhttp) {
|
||||
alert(Drupal.ajaxError(xmlhttp, db.uri));
|
||||
Drupal.displayAjaxError(Drupal.ajaxError(xmlhttp, db.uri));
|
||||
}
|
||||
});
|
||||
}, this.delay);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user