Compare commits

...

255 Commits

Author SHA1 Message Date
Thibault GUILLAUME
225a632560 Merge branch 'keycms-suppl-color' into 'master'
add color keycms

See merge request dev-antadis/versionecologique!1
2017-12-05 17:00:55 +01:00
Rémy
c1d1a2ad7a add color keycms 2017-12-05 16:57:22 +01:00
Rémy
9db2113e12 fix souci placeholder color on firefox 2017-12-04 11:01:14 +01:00
Rémy
91d265a6b2 fix souci hover sur search 2017-11-29 12:57:11 +01:00
Michael RICOIS
761cf404a1 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-11-17 16:44:32 +01:00
Michael RICOIS
68059f4b59 Remplace info by comment 2017-11-17 16:44:17 +01:00
Rémy
be80babf8a add bold sur page produit 2017-11-16 15:32:27 +01:00
Rémy
4e0764c2dc add picto linkedIn dans bloc social 2017-11-16 11:45:40 +01:00
Rémy
c752bd35a6 fix souci picto linkedIn 2017-11-16 11:39:56 +01:00
Rémy
1472a81f99 ajout new icomoon (add picto linkedIn) 2017-11-16 11:39:23 +01:00
Rémy
eb6c978786 fix souci (pas de lien) sur bouton contact sur page devis (+ menu mobile) 2017-11-16 11:12:53 +01:00
Rémy
60f17e76aa modif slider home sur mobile (centrage et alignement du texte) 2017-11-14 17:45:46 +01:00
Rémy
2f8bf36072 test CSS sur slider home 2017-11-14 17:41:29 +01:00
Rémy
579fae8d12 test CSS sur slider home 2017-11-14 17:40:34 +01:00
Rémy
1c3ff02be0 test JS sur slider home 2017-11-14 17:39:13 +01:00
Rémy
a5df30085d test sur slider home 2017-11-14 17:35:56 +01:00
Rémy
d719aeca2c disable autoplay sur slider home 2017-11-14 17:18:14 +01:00
Preprod mutu
52dc9d46f6 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-11-14 17:15:25 +01:00
Preprod mutu
4c4ccdf501 modif pp 2017-11-14 17:15:13 +01:00
root
276920a579 Translation 2017-11-10 09:59:57 +01:00
root
1cef4e7abf Google property 2017-11-10 09:58:21 +01:00
root
3fc2d3863c seoexpert 2017-11-10 09:57:40 +01:00
root
9ba669400b gsitemap 2017-11-10 09:49:49 +01:00
root
1c05f8c54f advpicto 2017-11-10 09:43:33 +01:00
root
c472fa8043 Fix theme 2017-11-10 09:42:17 +01:00
root
d2095664ef ganalytics 2017-11-10 09:41:31 +01:00
root
7a05fd7497 kwk_sync and display_errors 2017-11-10 09:40:34 +01:00
root
ac8d0d42bf fix image link array 2017-11-09 17:42:37 +01:00
Michael RICOIS
f2a5a4a287 Sujet du mail en FR 2017-11-08 10:27:56 +01:00
Preprod mutu
2fc4fc3293 Before MEL 2017-11-08 09:27:57 +01:00
Michael RICOIS
2c08780b7c Typo 2017-11-07 17:52:03 +01:00
Preprod mutu
1634cfab49 New modules and translation 2017-11-07 15:20:00 +01:00
Preprod mutu
46e7f0396c Design panier 2017-11-07 15:17:48 +01:00
Preprod mutu
2ee9cddf42 blocknewsletter 2017-11-07 15:15:15 +01:00
Preprod mutu
71df3b8348 blockwishlist 2017-11-07 15:14:11 +01:00
Preprod mutu
1b02b05f99 sendtoafriend 2017-11-07 15:13:44 +01:00
Preprod mutu
2906ba8ba6 mailalerts 2017-11-07 15:13:13 +01:00
Preprod mutu
d4f64ba07c Mails 2017-11-07 15:11:04 +01:00
Preprod mutu
909a5a9eaa fix bug inté 2017-11-07 10:02:16 +01:00
Michael RICOIS
76ba22df34 Ajout informations supplémentaires 2017-10-26 15:24:15 +02:00
Michael RICOIS
a87c056cb7 Smarty var 2017-10-26 14:38:29 +02:00
Michael RICOIS
8132411c6c Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-10-25 12:19:29 +02:00
Michael RICOIS
c0cc419408 Traitemement champ newsletter 2017-10-25 12:19:13 +02:00
Preprod mutu
b48f4e5bb4 fixs slider + toggle affichage cp de coeur 2017-10-24 09:51:52 +02:00
Michael RICOIS
6c7bd4dbbe Define from email 2017-10-20 14:31:44 +02:00
Rémy
5d1f4997b2 add link sur bouton "decouvrir les coups de <3" + panel coups de <3 qui s'ouvre lorsqu'on arrive via ce bouton 2017-10-18 10:41:13 +02:00
Rémy
f4596f1673 rectif faute d'ortho 2017-10-12 16:32:38 +02:00
Rémy
74bf8ae031 rectif faute d'ortho 2017-10-12 16:30:43 +02:00
Michael RICOIS
02a1b49c5a Comment 2017-10-04 10:51:26 +02:00
Michael RICOIS
a4c3aa111f Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-10-04 10:05:53 +02:00
Michael RICOIS
563f2f58c3 Permission directory 2017-10-04 10:01:29 +02:00
Rémy
0b1c95c30f fix souci image moche sur listing produit 2017-10-03 12:56:00 +02:00
Rémy
80a4bb59e8 recette - ligne 20 2017-10-03 12:15:12 +02:00
Rémy
c861fda0a7 recette - ligne 24/27/28 2017-10-03 11:33:03 +02:00
Rémy
72bcd5be0f recette - ligne 22 2017-10-03 10:25:40 +02:00
Rémy
9b8da01bce recette - ligne 21 2017-10-03 10:11:48 +02:00
Rémy
0ea550752c changement logo sur desktop 2017-09-28 15:29:11 +02:00
Rémy
4f6c68664d fix décalage pictos sur page produit (2) 2017-09-27 14:41:35 +02:00
Rémy
9b9830ea15 fix décalage pictos sur page produit 2017-09-27 14:40:54 +02:00
Rémy
9087d871a4 fix décalage texte slider home 2017-09-27 14:36:20 +02:00
Rémy
011c357c27 fix souci bouton "continuer mes achats" 2017-09-27 13:01:02 +02:00
Rémy
ca20b49cb6 fix recette (finish) 2017-09-27 12:56:09 +02:00
Rémy
f8e0c73070 Merge remote-tracking branch 'origin/master' 2017-09-27 12:37:43 +02:00
Rémy
7422fbc063 fix souci overlay sur page produit 2017-09-27 12:37:25 +02:00
Michael RICOIS
0a0fa41e70 Qty condition 2017-09-27 12:16:08 +02:00
Michael RICOIS
63ead952c1 Check qty is numeric 2017-09-27 12:10:34 +02:00
Rémy
3f2cea987f fix souci recette page about 2017-09-27 12:02:51 +02:00
Rémy
1c045fbaf2 fix recette (3 a 15) 2017-09-27 11:51:59 +02:00
Rémy
908235ac51 fix souci icons social dans template mail 2017-09-13 12:01:08 +02:00
Michael RICOIS
807acd0d2d QTY requirement be less strict 2017-09-13 10:54:02 +02:00
Rémy
d4995a6097 fix trad minimal quantity 2017-09-12 12:11:40 +02:00
Rémy
cd53567509 fix icon couleur texture sur product page 2017-09-08 11:08:13 +02:00
Michael RICOIS
6e4008814d Prise en compte de tout type de MARQUAGE 2017-09-07 11:36:26 +02:00
Michael RICOIS
639ad665bb Update tpl antadisconfigurator 2017-09-07 10:45:07 +02:00
Michael RICOIS
de806ccae7 Suppression separator 2017-09-07 10:44:40 +02:00
Michael RICOIS
337deb3354 Update module antadisconfigurator 2017-09-07 10:17:17 +02:00
Rémy
8d73f8734e Merge remote-tracking branch 'origin/master' 2017-09-05 16:17:01 +02:00
Rémy
cc123a64f1 fix recette client 2017-09-05 16:16:52 +02:00
Michael RICOIS
df83ca784e Script 2017-09-05 16:12:19 +02:00
Rémy
26bb447516 Merge remote-tracking branch 'origin/master' 2017-09-05 15:55:18 +02:00
Rémy
93c2c25ae1 fix recette client 2017-09-05 15:55:04 +02:00
Michael RICOIS
672f933bad Basic association from csv file 2017-09-04 17:32:37 +02:00
Michael RICOIS
545f602be7 Oups 2017-08-31 14:40:55 +02:00
Michael RICOIS
137d335eb6 Specify reply_to 2017-08-31 14:38:35 +02:00
Michael RICOIS
72d552d4b1 Add mail template to change title 2017-08-31 14:37:49 +02:00
Michael RICOIS
d9d859a4f8 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-08-31 12:47:58 +02:00
Michael RICOIS
d9b0a05f40 Merge branch 'contact'
Conflicts:
	synchro.sh
2017-08-31 12:47:45 +02:00
Rémy
8a045ebf56 modif short desc categ 2017-08-31 12:15:36 +02:00
Rémy
d8013c0912 fix recette 2017-08-31 12:02:10 +02:00
Michael RICOIS
ff7c7e63e6 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-08-31 11:57:59 +02:00
Michael RICOIS
83477e5b55 Synchro with only pull 2017-08-31 11:57:43 +02:00
Rémy
5dd19e3352 Merge remote-tracking branch 'origin/master' 2017-08-31 10:06:09 +02:00
Rémy
4fbc7e613d add autoplay slider home 2017-08-31 10:05:43 +02:00
Michael RICOIS
ad310af1aa Synchro without database update 2017-08-08 16:46:54 +02:00
Michael RICOIS
929f96f4a6 Utilisation contact original 2017-08-08 16:46:34 +02:00
Michael RICOIS
45610ceb23 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-08-07 09:26:09 +02:00
Michael RICOIS
e8c3430510 Better copy options 2017-08-07 09:25:51 +02:00
Rémy
01a8852aad ajout filtre par prix + fix pb icon 2017-07-31 12:18:55 +02:00
Rémy
948489f816 fix remontées tab coups de coeur/nouveautés 2017-07-27 12:00:26 +02:00
Rémy
398baa2254 fix picto €€€€€ sur page product 2017-07-26 17:06:39 +02:00
Rémy
404cce467b fix picto <3 sur page product 2017-07-26 16:51:54 +02:00
Michael RICOIS
8105e2fa6e stopPropagation 2017-07-26 16:13:35 +02:00
Michael RICOIS
238ce922df id_lang 2017-07-26 16:09:54 +02:00
Michael RICOIS
450591ba8d Space 2017-07-26 16:09:36 +02:00
Michael RICOIS
6bbe3e9dfa Remove debug 2017-07-26 15:08:02 +02:00
Michael RICOIS
cff743dca6 PS_BASE_URL 2017-07-25 14:16:11 +02:00
Rémy
010a608f9f fix mails 2017-07-25 12:48:48 +02:00
Michael RICOIS
5a7601f0aa Fix typo 2017-07-25 12:35:12 +02:00
Rémy
331bae1e72 fix mails 2017-07-25 12:31:26 +02:00
Rémy
5901775621 fix mails 2017-07-25 12:22:56 +02:00
Rémy
efb2d19661 fix mails 2017-07-25 12:13:24 +02:00
Michael RICOIS
7ed40cc2c7 contact_link 2017-07-25 11:56:23 +02:00
Rémy
3357d69627 fix mails 2017-07-25 11:50:39 +02:00
Rémy
3207d11962 fix mails 2017-07-25 11:48:37 +02:00
Michael RICOIS
e7966e2258 Default minimal quantity without attributes 2017-07-24 16:02:01 +02:00
Michael RICOIS
cad4e95bc9 Add options on all products after import (set the first with options to
copy)
2017-07-24 15:41:53 +02:00
Michael RICOIS
c68083c0a3 Value of options 2017-07-24 15:41:20 +02:00
Michael RICOIS
9ed8ce6b35 Add visibilty in sql request 2017-07-24 15:14:57 +02:00
Rémy
95c973eca6 fix text qui s'affiche sur home + fix modal ajout au devis 2017-07-24 10:11:46 +02:00
Michael RICOIS
36ea3d8e49 Change db name 2017-07-24 10:04:12 +02:00
Michael RICOIS
9d6104dd5a Prise en compte de la langue 2017-07-21 17:51:16 +02:00
Rémy
9d8a2c59ac fix picto + fancybox + titre slider (FF) 2017-07-21 10:45:12 +02:00
Michael RICOIS
f53ff92234 Fix template js on quantities 2017-07-20 16:44:57 +02:00
Rémy
335ccee1cd ajout images pour templates mails 2017-07-20 16:09:45 +02:00
Rémy
b7764e0951 skin template mail + fix divers 2017-07-20 16:08:24 +02:00
Michael RICOIS
5645572b3a Fix language 2017-07-20 15:22:48 +02:00
Michael RICOIS
2570ae9a8a Deleting file 2017-07-20 12:49:13 +02:00
Michael RICOIS
89cb414eb0 Fix check minimal qty 2017-07-20 10:11:12 +02:00
Michael RICOIS
8cfc1dad29 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-19 16:47:17 +02:00
Michael RICOIS
5d9a1795fe Revert "Fix condition pour confirmation bonne envoi d'email"
This reverts commit a014ee1203.
2017-07-19 16:46:02 +02:00
Michael RICOIS
a014ee1203 Fix condition pour confirmation bonne envoi d'email 2017-07-19 16:43:19 +02:00
Rémy
65f428ada0 fix divers 2017-07-19 16:42:14 +02:00
Michael RICOIS
5191ee8604 Mail 2017-07-19 15:26:14 +02:00
Michael RICOIS
604ccb935e Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-19 15:05:22 +02:00
Michael RICOIS
c5f958ef5b Requirement on quantities 2017-07-19 15:05:13 +02:00
Michael RICOIS
f34a96d9bb When error occured re-fill all fields 2017-07-19 12:50:04 +02:00
Rémy
5391eadff9 fix divers 2017-07-19 11:23:47 +02:00
Rémy
bfcec99791 fix bug form contact 2017-07-19 10:12:14 +02:00
Rémy
ab7a879b36 Recette mobile/tablet 2017-07-18 16:15:40 +02:00
Michael RICOIS
26d2994987 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-18 15:05:55 +02:00
Michael RICOIS
2650080b4f Export parseConfigurator in module 2017-07-18 14:38:06 +02:00
Michael RICOIS
9ce098d3c6 checkRequirement 2017-07-18 14:37:34 +02:00
Rémy
34ca4520b6 recette HP slider fix 2017-07-18 13:01:09 +02:00
Romu
87b99cdc8f remonté produit category 2017-07-18 03:29:30 -07:00
Rémy
f3057be517 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	www/translations/fr.gzip
2017-07-18 12:16:15 +02:00
Rémy
cb7f2a0e5b fix recette 2017-07-18 12:15:09 +02:00
Rémy
70162a2515 fix recette 2017-07-18 12:11:25 +02:00
Michael RICOIS
ff71f69d07 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-17 17:37:04 +02:00
Michael RICOIS
c07481c23e Where is fr.gzip 2017-07-17 17:36:54 +02:00
Rémy
acee018a5c Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-17 17:17:57 +02:00
Rémy
d9ca6fa68e fix recette 2017-07-17 17:17:35 +02:00
Michael RICOIS
c6f2baa255 DB_PREFIX 2017-07-17 15:25:34 +02:00
Michael RICOIS
9bba8e0381 CS 2017-07-17 12:48:02 +02:00
Michael RICOIS
e22830139f Remove ajax change price event 2017-07-17 12:32:27 +02:00
Michael RICOIS
987735a01f CS 2017-07-17 12:32:00 +02:00
Michael RICOIS
426d32d49b DocBlock 2017-07-17 12:31:21 +02:00
Michael RICOIS
3b052a3cd2 Doc 2017-07-17 12:31:03 +02:00
Michael RICOIS
ed738d32cd Doc 2017-07-17 12:30:46 +02:00
Michael RICOIS
d8fb1f04ea CS 2017-07-17 12:30:33 +02:00
Michael RICOIS
10ca188d91 Return error message 2017-07-17 10:17:51 +02:00
Michael RICOIS
7efc7f205e Display error message 2017-07-17 09:46:41 +02:00
Michael RICOIS
0f13f2aadb Quantity field display 2017-07-13 17:39:19 +02:00
Rémy
8c305b16e2 Merge remote-tracking branch 'origin/master' 2017-07-13 15:25:43 +02:00
Rémy
dabf775474 skin submenu resp 2017-07-13 15:25:27 +02:00
Michael RICOIS
bc56b27778 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-13 15:01:10 +02:00
Michael RICOIS
bb9ff6ba65 Validate email on quote 2017-07-13 15:00:53 +02:00
Rémy
38a825bab3 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-13 12:07:12 +02:00
Rémy
7241ceab7d skin submenu resp + page search + fix divers 2017-07-13 12:06:23 +02:00
Michael RICOIS
6fde2728d6 Check mail contact 2017-07-13 11:41:33 +02:00
Michael RICOIS
a31cefa25f Override contact to receive specific form 2017-07-12 17:57:48 +02:00
Michael RICOIS
c005822fd1 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-12 17:45:00 +02:00
Michael RICOIS
06f889dbd6 Minimal quantity 2017-07-12 17:44:39 +02:00
Rémy
894543a334 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-12 17:27:27 +02:00
Rémy
ccc18979b7 fix divers 2017-07-12 17:27:13 +02:00
Romu
c7d15a8214 menu mobile 2017-07-12 08:26:15 -07:00
Rémy
b3c32f8a8d fix divers 2017-07-12 15:29:14 +02:00
Rémy
cc681c609c fix's homePage 2017-07-12 11:34:04 +02:00
Rémy
5ed7817627 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-12 11:04:31 +02:00
Rémy
985fc182fb page contact 2017-07-12 11:04:22 +02:00
Michael RICOIS
a295a9c576 Remove quantityDisplayed 2017-07-12 10:54:17 +02:00
Michael RICOIS
acc46fc638 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-12 09:53:22 +02:00
Michael RICOIS
d119d84d41 Synchro 2017-07-12 09:37:16 +02:00
Rémy
45ee186ecd responsive pages CMS + fix reassurance footer 2017-07-11 17:24:08 +02:00
Michael RICOIS
556d5c6288 Typo 2017-07-11 15:32:15 +02:00
Rémy
139938f26f Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-11 11:44:28 +02:00
Rémy
6dcc0a0922 pages CMS OK 2017-07-11 11:44:08 +02:00
Michael RICOIS
50ef83eeab Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-10 17:49:42 +02:00
Michael RICOIS
370154db0d Typo 2017-07-10 17:49:23 +02:00
Rémy
3f37dc2d21 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-10 17:24:18 +02:00
Rémy
9a16ab0bf5 pages CMS 2017-07-10 17:24:03 +02:00
Romu
45bbf592f5 category advreassurance 2017-07-10 08:21:04 -07:00
Michael RICOIS
f823fbcacf File 2017-07-10 16:48:07 +02:00
Michael RICOIS
39ff686e10 Update sql install 2017-07-10 12:01:46 +02:00
Michael RICOIS
90b270a6d5 Set import dir at first level 2017-07-10 11:43:32 +02:00
Michael RICOIS
d25715aa6c Email tpl 2017-07-10 11:38:54 +02:00
Michael RICOIS
f36892a88b Add nb options in templates 2017-07-10 11:33:46 +02:00
Michael RICOIS
b04ba4e571 Add redirect when delete 2017-07-10 10:11:21 +02:00
Michael RICOIS
bbf4a4010b ajax cart 2017-07-07 17:50:26 +02:00
Michael RICOIS
98c73de012 Id configurator 2017-07-07 10:29:41 +02:00
Michael RICOIS
234d909e49 Get options properly to display in mail 2017-07-07 10:21:32 +02:00
Michael RICOIS
75fff36b85 Space 2017-07-07 10:19:42 +02:00
Michael RICOIS
0c9b73a960 Real product list in cart 2017-07-07 10:16:11 +02:00
Michael RICOIS
df811dd137 Template mails with product configurator 2017-07-06 15:35:04 +02:00
Michael RICOIS
5e301bb942 Complete tpl for errors 2017-07-06 13:11:02 +02:00
Michael RICOIS
d1b11fd366 Email for a quote 2017-07-06 12:51:44 +02:00
Rémy
f491754ef4 page confirmation ok 2017-07-06 12:32:27 +02:00
Rémy
c0c8789abe responsive page devis 2017-07-05 16:18:35 +02:00
Rémy
b69d2c0c16 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-07-05 15:19:27 +02:00
Rémy
8404625b5e page formulaire devis 2017-07-05 15:19:15 +02:00
Michael RICOIS
ffec75e0f3 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-05 10:24:24 +02:00
Michael RICOIS
5375d37a40 Import products and images 2017-07-05 09:57:47 +02:00
Rémy
9361330335 fix typo 2017-07-04 17:05:47 +02:00
Michael RICOIS
d860e78552 UTF8 charset 2017-07-04 11:37:29 +02:00
Michael RICOIS
ebc9e907a0 Validation des imports 2017-07-04 11:37:28 +02:00
Michael RICOIS
86678ab540 Script import on all tables with product informations 2017-07-04 11:37:28 +02:00
Michael RICOIS
e417aa0b0f Prepare SQL 2017-07-04 11:37:28 +02:00
Michael RICOIS
f7ba2465bf Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-07-04 11:25:14 +02:00
Michael RICOIS
6558391b77 Add description and visibility 2017-07-04 11:03:46 +02:00
Rémy
a8ee89d7a2 vérifs formulaire devis 2017-07-04 10:21:37 +02:00
Rémy
eefb63a084 configurateur devis 2017-07-03 18:08:24 +02:00
Rémy
ace151b8a9 configurateur 2017-06-30 18:19:25 +02:00
Rémy
ed82f0a3ed Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-06-30 17:43:58 +02:00
Rémy
900d5e7e26 configurateur 2017-06-30 17:43:46 +02:00
Michael RICOIS
827fc71e19 Merge branch 'master' of git@gitlab.antadis.net:dev-antadis/versionecologique.git 2017-06-30 17:36:14 +02:00
Michael RICOIS
c26f8e925f Fix optValue not define 2017-06-30 17:35:37 +02:00
Rémy
655947e280 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-06-30 16:56:39 +02:00
Rémy
8e606c2dc7 product page 2017-06-30 16:56:15 +02:00
Michael RICOIS
73a1cafd81 Oups DB_PREFIX 2017-06-30 15:10:48 +02:00
Michael RICOIS
8d637ab1e0 Configurator : hook to display configuration values in order 2017-06-30 10:21:20 +02:00
Michael RICOIS
2b667e6c63 Add hidden field 2017-06-29 16:10:32 +02:00
Michael RICOIS
bf64874d8c Change redirect url 2017-06-29 15:51:19 +02:00
Michael RICOIS
ca085ccba7 Fix SQL install 2017-06-29 15:17:25 +02:00
Michael RICOIS
7582950314 Install module and check override 2017-06-29 15:09:39 +02:00
Michael RICOIS
cb40306680 Add module configurator 2017-06-29 12:49:15 +02:00
Thibault UBUNTU
501711f7ba soucis update category 2017-06-29 11:44:55 +02:00
Rémy
801beda969 blocklayered avancement 2017-06-28 12:27:35 +02:00
Rémy
401367300a page sous-cat + block layered + début page produit 2017-06-28 10:11:01 +02:00
Rémy
4fa973ffa1 Page univers + page listing produits 2017-06-23 17:47:40 +02:00
Rémy
cdc723ee45 Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-06-22 16:43:58 +02:00
Rémy
08cb446a3b avancement HP + page categories 2017-06-22 13:45:00 +02:00
Thibault UBUNTU
a79bd4165d synchro preprod 2017-06-16 14:55:51 +02:00
Thibault UBUNTU
62572fe07b Merge branch 'master' of gitlab.antadis.net:dev-antadis/versionecologique 2017-06-16 12:57:01 +02:00
Thibault UBUNTU
83a9db00ca add script migration 2017-06-16 12:56:51 +02:00
Rémy
4de94e9202 ajout section univers sur home 2017-06-15 16:17:37 +02:00
Rémy
a5ba24af6e ajout bloc CMS dans listing produits 2017-06-14 16:39:07 +02:00
Rémy
8b8ff008f5 inté siteReviews et trustedbrands 2017-06-14 14:53:09 +02:00
Rémy
1d300e5e0c fix conflict 2017-06-14 11:51:54 +02:00
Rémy
85a89a346a fichier de translation 2017-06-14 11:46:31 +02:00
Romu
894e51e6d0 ajout category associé advmenu + featuredcategories + img category + block constructor dans les listings produit + des bisous <3 2017-06-14 02:30:00 -07:00
Rémy
268babbb92 page home : ajout plusieurs section + début responsive 2017-06-13 17:57:55 +02:00
Rémy
2730610805 ajustement footer + avancement slider 2017-06-09 10:45:58 +02:00
Rémy
a0f2daa687 avancement header + footer + début slider 2017-06-08 17:00:13 +02:00
Rémy
f63942c7ef avancement header 2017-06-07 17:10:01 +02:00
Rémy
85416bcf19 avancement header 2017-06-07 10:47:24 +02:00
Rémy
5a32adbbfd theme 2017-06-02 15:25:27 +02:00
1441 changed files with 170235 additions and 420 deletions

View File

@ -0,0 +1,98 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// New database
$config = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$db = new PDO($config['dsn'], $config['user'], $config['pass']);
$table = 'ps_product';
$cols = array(
'reference',
'id_category_default',
);
echo "Start association category\n";
$row = 0;
if (($handle = fopen('ps_product.csv', 'r')) !== false) {
try {
$db->beginTransaction();
while (($data = fgetcsv($handle, 1000, ',', '"')) !== false) {
$row++;
// Head
if ($row == 1) {
continue;
}
echo "Ligne $row\n";
// Data id_product, id_advpicto(s)
$csvProductId = $data[0];
$csvName = trim($data[1]);
$csvReference = trim($data[2]);
$csvCategoryId = trim($data[3]);
if (empty($csvCategoryId)) {
continue;
}
// Construct SQL ps_product
$sql = 'UPDATE '.$table;
$sql.= ' SET ';
foreach ($cols as $c) {
$sql.= $c.'=:'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ' WHERE id_product=:id_product';
echo $sql."\n";
echo "$csvProductId, $csvCategoryId\n";
$stmtImport = $db->prepare($sql);
$stmtImport->bindValue('id_product', $csvProductId);
$stmtImport->bindValue('id_category_default', $csvCategoryId);
$stmtImport->bindValue('reference', $csvReference);
if ($stmtImport->execute() === false) {
echo "Error\n";
//exit;
}
// Construct SQL ps_product
$sql = 'UPDATE ps_product_lang';
$sql.= ' SET ';
$sql.= 'name=:name, ';
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ' WHERE id_product=:id_product';
echo $sql."\n";
$stmtImport = $db->prepare($sql);
$stmtImport->bindValue('id_product', $csvProductId);
$stmtImport->bindValue('name', $csvName);
if ($stmtImport->execute() === false) {
echo "Error\n";
//exit;
}
}
if ($db->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$db->rollBack();
echo "Error on $table - $e->getMessage()\n";
exit;
}
fclose($handle);
} else {
echo "Can't open file\n";
}

View File

@ -0,0 +1,75 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// New database
$configNew = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$dbNew = new PDO($configNew['dsn'], $configNew['user'], $configNew['pass']);
// Truncate ?
$truncate = false;
if ($truncate) {
Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'product_configurator_opt_group`');
Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'product_configurator_opt_impact`');
Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'configurator_storage`');
}
/*
DELETE FROM `ps_product_configurator_opt_group` WHERE id_product!=791
DELETE FROM `ps_product_configurator_opt_impact` WHERE id_product!=791
Supprimer dans le BO l'option TYPE DE MARQUAGE
TRUNCATE ps_configurator_storage
*/
// Get products id already imported
$productCpt = 0;
$sql = "SELECT id_product AS id_product FROM "._DB_PREFIX_."product ORDER BY id_product ASC";
$stmtNew = $dbNew->query($sql);
$productTotal = $stmtNew->rowCount();
if ($productTotal == 0) {
echo "No products ?\n"; exit;
} else {
while($item = $stmtNew->fetch(PDO::FETCH_OBJ)) {
$productCpt++;
// First product must have a configurator
if ($productCpt == 1) {
$id_product_from = $item->id_product;
continue;
}
$id_product_to = $item->id_product;
// Start copying
echo "Copy options on product $productCpt / $productTotal\n";
$result1 = Db::getInstance()->execute(
'INSERT INTO `'._DB_PREFIX_.'product_configurator_opt_group` (`id_product`, `id_configurator_opt_group`, `required`, `visibility`, `position`)
SELECT '.(int)$id_product_to.' AS `id_product`, `id_configurator_opt_group`, `required`, `visibility`, `position`
FROM `'._DB_PREFIX_.'product_configurator_opt_group` WHERE `id_product` = '.(int)$id_product_from);
$groupSql = 'SELECT `id_product_configurator_opt_group`, `id_configurator_opt_group`
FROM `'._DB_PREFIX_.'product_configurator_opt_group` WHERE `id_product` = '.(int)$id_product_to;
$groupResult = Db::getInstance()->executeS($groupSql);
foreach ($groupResult as $item) {
$impactSql = 'INSERT INTO `'._DB_PREFIX_.'product_configurator_opt_impact` (`id_product`, `id_product_configurator_opt_group`, `id_configurator_opt`, `price`)
SELECT '.(int)$id_product_to.' AS `id_product`, '.$item['id_product_configurator_opt_group'].' AS `id_product_configurator_opt_group`, `id_configurator_opt`, `price`
FROM `'._DB_PREFIX_.'configurator_opt` WHERE `id_configurator_opt_group`='.(int)$item['id_configurator_opt_group'];
$result2 = Db::getInstance()->execute($impactSql);
if(!$result2) {
break;
}
}
if (!$result1 && !$result2) {
echo "Error\n";
exit;
}
}
}

View File

@ -0,0 +1,88 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// New database
$config = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$db = new PDO($config['dsn'], $config['user'], $config['pass']);
$table = 'ps_advpicto_product';
$cols = array(
'id_product',
'id_advpicto',
);
echo "Start association picto\n";
$row = 0;
if (($handle = fopen('ps_advpicto_product.csv', 'r')) !== false) {
try {
$db->beginTransaction();
while (($data = fgetcsv($handle, 1000, ',', '"')) !== false) {
$row++;
// Head
if ($row == 1) {
continue;
}
echo "Ligne $row\n";
// Data id_product, id_advpicto(s)
$csvProductId = $data[0];
$csvPicto = trim($data[1]);
if (empty($csvPicto)) {
continue;
}
$pictos = explode(',', $data[1]);
// Liste des pictos
foreach($pictos as $p) {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
echo $sql."\n";
echo "$csvProductId, $p\n";
$stmtImport = $db->prepare($sql);
$stmtImport->bindValue('id_product', $csvProductId);
$stmtImport->bindValue('id_advpicto', $p);
if ($stmtImport->execute() === false) {
echo "Error\n";
//exit;
}
}
}
if ($db->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$db->rollBack();
echo "Error on $table - $e->getMessage()\n";
exit;
}
fclose($handle);
} else {
echo "Can't open file\n";
}

View File

@ -0,0 +1,148 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require '../www/config/config.inc.php';
fwrite(STDOUT, 'START IMPORTING CATEGORIES'.PHP_EOL);
/* Connexion à une base ODBC avec l'invocation de pilote */
$dsn = 'mysql:dbname=versionecologique_old;host=192.168.0.41';
$user = 'root';
$password = '';
$old_bdd = new PDO($dsn, $user, $password);
$categories = array(
340,
341,
342,
343,
344,
345,
346,
347,
348,
350,
351
);
$stmt = $old_bdd->query('
SELECT c.id_category, cl.name, cl.description, cl.link_rewrite, cl.meta_title, cl.meta_keywords, cl.meta_description, c.id_parent
FROM ps_category c
LEFT JOIN ps_category_lang cl ON (cl.id_category = c.id_category)
WHERE c.id_category IN (' .implode(',', $categories) .')
', PDO::FETCH_OBJ);
$results = $stmt->fetchAll();
$data_insert = array();
foreach ($results as $key => $result) {
$data_insert[] = array(
'id' => $result->id_category,
'name' => $result->name,
'description' => $result->description,
'link_rewrite' => $result->link_rewrite,
'meta_title' => $result->meta_title,
'meta_keywords' => $result->meta_keywords,
'meta_description' => $result->meta_description,
'id_parent' => $result->id_parent
);
$childs = $old_bdd->query('
SELECT c.id_category, cl.name, cl.description, cl.link_rewrite, cl.meta_title, cl.meta_keywords, cl.meta_description, c.id_parent
FROM ps_category c
LEFT JOIN ps_category_lang cl ON (cl.id_category = c.id_category)
WHERE c.id_parent = ' .$result->id_category
, PDO::FETCH_OBJ);
foreach ($childs as $child) {
$data_insert[] = array(
'id' => $child->id_category,
'name' => $child->name,
'description' => $child->description,
'link_rewrite' => $child->link_rewrite,
'meta_title' => $child->meta_title,
'meta_keywords' => $child->meta_keywords,
'meta_description' => $child->meta_description,
'id_parent' => $child->id_parent
);
}
}
$query = 'INSERT INTO `ps_category` VALUES';
$query_lang = 'INSERT INTO `ps_category_lang` VALUES';
$query_shop = 'INSERT INTO `ps_category_shop` VALUES';
$query_groups = 'INSERT INTO `ps_category_group` VALUES';
$langs = Language::getLanguages();
$shops = Shop::getShops(false);
foreach ($data_insert as $key => $data) {
$query.= '(
'.(int) $data['id'].',
'.(int) $data['id_parent'].',
1,
1,
2,
3,
1,
"'.date('Y-m-d H:i:s').'",
"'.date('Y-m-d H:i:s').'",
'.Category::getLastPosition($data['id_parent'],1).',
0
),';
foreach ($shops as $shop) {
foreach ($langs as $key => $lang) {
$query_lang.= '(
'.(int) $data['id'].',
'.(int) $shop['id_shop'].',
'.(int) $lang['id_lang'].',
"'.pSQL($data['name']).'",
"'.pSQL($data['description']).'",
"",
"'.pSQL($data['link_rewrite']).'",
"'.pSQL($data['meta_title']).'",
"'.pSQL($data['meta_keywords']).'",
"'.pSQL($data['meta_description']).'"
),';
}
$query_shop.= '('.(int) $data['id'].', '.(int) $shop['id_shop'].', 0),';
}
$query_groups.=
'('.(int) $data['id'].', 1),
('.(int) $data['id'].', 2),
('.(int) $data['id'].', 3),'
;
}
$query = rtrim($query,',');
$query_lang = rtrim($query_lang,',');
$query_shop = rtrim($query_shop,',');
$query_groups = rtrim($query_groups,',');
Db::getInstance()->execute('DELETE FROM ps_category WHERE id_category > 2');
Db::getInstance()->execute('DELETE FROM ps_category_lang WHERE id_category > 2');
Db::getInstance()->execute('DELETE FROM ps_category_group WHERE id_category > 2');
Db::getInstance()->execute('DELETE FROM ps_category_shop WHERE id_category > 2');
Db::getInstance()->execute($query);
Db::getInstance()->execute($query_lang);
Db::getInstance()->execute($query_shop);
Db::getInstance()->execute($query_groups);
fwrite(STDOUT, 'FIN IMPORT CATEGORIES'.PHP_EOL);
// Category::regenerateEntireNtree();
fwrite(STDOUT, 'START IMPORTING CATEGORIES'.PHP_EOL);

244
scripts/import_images.php Normal file
View File

@ -0,0 +1,244 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// Old database
$configOld = array(
'dsn' => 'mysql:dbname=versionecologique_old;host=192.168.0.41;charset=UTF8',
'user' => 'root',
'pass' => '',
);
$dbOld = new PDO($configOld['dsn'], $configOld['user'], $configOld['pass']);
// New database
$configNew = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$dbNew = new PDO($configNew['dsn'], $configNew['user'], $configNew['pass']);
// Get products id already imported
$sql = "SELECT id_product AS id_product FROM ps_product";
$stmtNew = $dbNew->query($sql);
if ($stmtNew->rowCount() == 0) {
echo "No products ?\n"; exit;
} else {
while($item = $stmtNew->fetch(PDO::FETCH_OBJ)) {
$products[] = $item->id_product;
}
}
// ps_image_type => type des images
// Truncate
$tables = array(
'ps_image',
'ps_image_lang',
'ps_image_shop',
);
foreach($tables as $table) {
$dbNew->query('TRUNCATE TABLE '.$table);
}
$image_ids = array();
// ps_image
$table = 'ps_image';
$cols = array(
'id_image',
'id_product',
'position',
'cover',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
$image_ids[] = $item->id_image;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// Recreate images
if (count($image_ids) > 0) {
$i = 0;
foreach ($image_ids as $id) {
$image = new Image($id);
$imageFilePath = $image->getPathForCreation().'.'.$image->image_format;
$imageFileOld = realpath(__DIR__).'/../import_images/p/'.$image->getImgFolder().$id.'.'.$image->image_format;
$result = ImageManager::resize($imageFileOld, $imageFilePath);
$imagesTypes = ImageType::getImagesTypes('products');
foreach ($imagesTypes as $imageType) {
$intResult = ImageManager::resize($imageFileOld, $imageFilePath.'-'.stripslashes($imageType['name']).'.'.$image->image_format,
$imageType['width'], $imageType['height'], $image->image_format);
$result = $result & $intResult;
}
if ($result === false) {
echo "Error on image $id - $i/".count($image_ids)."\n";
exit;
}
$i++;
echo $i."/".count($image_ids)."\n";
}
}
// ps_image_shop
$table = 'ps_image_shop';
$cols = array(
'id_product',
'id_image',
'id_shop',
'cover',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_image_lang
$table = 'ps_image_lang';
$cols = array(
'id_image',
'id_lang',
'legend',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_image IN (".join(',', $image_ids).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
$image_ids[] = $item->id_image;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";

426
scripts/import_products.php Normal file
View File

@ -0,0 +1,426 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// Old database
$configOld = array(
'dsn' => 'mysql:dbname=versionecologique_old;host=192.168.0.41;charset=UTF8',
'user' => 'root',
'pass' => '',
);
$dbOld = new PDO($configOld['dsn'], $configOld['user'], $configOld['pass']);
// New database
$configNew = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$dbNew = new PDO($configNew['dsn'], $configNew['user'], $configNew['pass']);
// Get all categories import in new DB - start import_categories before
$categories = array();
$sql = "SELECT id_category FROM ps_category";
$stmtNew = $dbNew->query($sql);
if ($stmtNew->rowCount() > 0) {
while ($item = $stmtNew->fetch(PDO::FETCH_OBJ)) {
$categories[] = $item->id_category;
}
}
// Get products in category (old db)
$sql = "SELECT DISTINCT(id_product) AS id_product FROM ps_category_product WHERE id_category IN (".join(',', $categories).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No products ?\n"; exit;
} else {
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$products[] = $item->id_product;
}
}
// Truncate
$tables = array(
'ps_category_product',
'ps_product',
'ps_product_lang',
'ps_product_shop',
'ps_stock_available',
);
foreach($tables as $table) {
$dbNew->query('TRUNCATE TABLE '.$table);
}
// ps_category_product
$table = 'ps_category_product';
$cols = array(
'id_category',
'id_product',
'position',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_product
$table = 'ps_product';
$cols = array(
'id_product',
'id_supplier',
'id_manufacturer',
'id_category_default',
'id_shop_default',
'id_tax_rules_group',
'on_sale',
'online_only',
'ean13',
'upc',
'ecotax',
'quantity',
'minimal_quantity',
'price',
'wholesale_price',
'unity',
'unit_price_ratio',
'additional_shipping_cost',
'reference',
'supplier_reference',
'location',
'width',
'height',
'depth',
'weight',
'out_of_stock',
'quantity_discount',
'customizable',
'uploadable_files',
'text_fields',
'active',
'redirect_type',
'id_product_redirected',
'available_for_order',
'available_date',
'condition',
'show_price',
/*'favorites_product',
'new_product',*/
'indexed',
'visibility',
'cache_is_pack',
'cache_has_attachments',
'is_virtual',
'cache_default_attribute',
'date_add',
'date_upd',
'advanced_stock_management',
'pack_stock_type',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_product_lang => from id_product
$table = 'ps_product_lang';
$cols = array(
'id_product',
'id_shop',
'id_lang',
'description',
'description_short',
'link_rewrite',
'meta_description',
'meta_keywords',
'meta_title',
'name',
'available_now',
'available_later',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_product_shop
$table = 'ps_product_shop';
$cols = array(
'id_product' => null,
'id_shop' => null,
'id_category_default' => null,
'id_tax_rules_group' => null,
'on_sale' => null,
'online_only' => null,
'ecotax' => null,
'minimal_quantity' => null,
'price' => null,
'wholesale_price' => null,
'unity' => null,
'unit_price_ratio' => null,
'additional_shipping_cost' => null,
'customizable' => null,
'uploadable_files' => null,
'text_fields' => null,
'active' => null,
'redirect_type' => null,
'id_product_redirected' => null,
'available_for_order' => array( 'value' => 1 ),
//'favorites_product' => null,
//'new_product' => null,
'available_date' => null,
'condition' => null,
'show_price' => array( 'value' => 1 ),
'indexed' => null,
'visibility' => null,
'cache_default_attribute' => null,
'advanced_stock_management' => null,
'date_add' => null,
'date_upd' => null,
'pack_stock_type' => null,
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c => $v) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c => $v) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c => $v) {
if (is_array($v)) {
$stmtImport->bindValue($c, $v['value']);
} else {
$stmtImport->bindValue($c, $item->{$c});
}
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_stock_available => from id_product
$table = 'ps_stock_available';
$cols = array(
'id_stock_available',
'id_product',
'id_product_attribute',
'id_shop',
'id_shop_group',
'quantity',
'depends_on_stock',
'out_of_stock',
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c) {
$sql.= '`'.$c.'`, ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c) {
$sql.= ':'.$c.', ';
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c) {
$stmtImport->bindValue($c, $item->{$c});
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";

374
scripts/missing_product.php Normal file
View File

@ -0,0 +1,374 @@
<?php
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
require_once dirname(__FILE__).'/../www/config/config.inc.php';
// Old database
$configOld = array(
'dsn' => 'mysql:dbname=versionecologique_old;host=192.168.0.41;charset=UTF8',
'user' => 'root',
'pass' => '',
);
$dbOld = new PDO($configOld['dsn'], $configOld['user'], $configOld['pass']);
// New database
$configNew = array(
'dsn' => 'mysql:dbname='._DB_NAME_.';host='._DB_SERVER_.';charset=UTF8',
'user' => _DB_USER_,
'pass' => _DB_PASSWD_,
);
$dbNew = new PDO($configNew['dsn'], $configNew['user'], $configNew['pass']);
// Get all categories import in new DB - start import_categories before
function recurseCategory($category, PDO $db) {
$sql = "SELECT id_category FROM ps_category WHERE id_parent=:category";
$stmt = $db->prepare($sql);
$stmt->bindValue('category', $category);
$stmt->execute();
$categories = array();
if ($stmt->rowCount() > 0) {
while ($item = $stmt->fetch(PDO::FETCH_OBJ)) {
$categories[] = $item->id_category;
$subcategories = recurseCategory($item->id_category, $db);
$categories = array_merge($categories, $subcategories);
}
}
return $categories;
}
$categories = recurseCategory(351, $dbOld);
// Get products in category (old db)
$sql = "SELECT DISTINCT(id_product) AS id_product FROM ps_category_product WHERE id_category IN (".join(',', $categories).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No products ?\n"; exit;
} else {
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$products[] = $item->id_product;
}
}
$productMatching = array();
// ps_product
$table = 'ps_product';
$cols = array(
'id_product' => null,
'id_supplier' => null,
'id_manufacturer' => null,
'id_category_default' => array('value' => 351),
'id_shop_default' => null,
'id_tax_rules_group' => null,
'on_sale' => null,
'online_only' => null,
'ean13' => null,
'upc' => null,
'ecotax' => null,
'quantity' => null,
'minimal_quantity' => null,
'price' => null,
'wholesale_price' => null,
'unity' => null,
'unit_price_ratio' => null,
'additional_shipping_cost' => null,
'reference' => null,
'supplier_reference' => null,
'location' => null,
'width' => null,
'height' => null,
'depth' => null,
'weight' => null,
'out_of_stock' => null,
'quantity_discount' => null,
'customizable' => null,
'uploadable_files' => null,
'text_fields' => null,
'active' => null,
'redirect_type' => null,
'id_product_redirected' => null,
'available_for_order' => null,
'available_date' => null,
'condition' => null,
'show_price' => null,
/*'favorites_product' => null,
'new_product' => null,*/
'indexed' => null,
'visibility' => null,
'cache_is_pack' => null,
'cache_has_attachments' => null,
'is_virtual' => null,
'cache_default_attribute' => null,
'date_add' => null,
'date_upd' => null,
'advanced_stock_management' => null,
'pack_stock_type' => null,
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c => $v) {
switch($c) {
case 'id_product':
break;
default:
$sql.= '`'.$c.'`, ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c => $v) {
switch($c) {
case 'id_product':
break;
default:
$sql.= ':'.$c.', ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c => $v) {
switch($c) {
case 'id_product':
// Do nothing
$oldProductId = $item->{$c};
break;
default:
if (is_array($v)) {
$stmtImport->bindValue($c, $v['value']);
} else {
$stmtImport->bindValue($c, $item->{$c});
}
break;
}
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
// Create matching
$productMatching[$oldProductId] = $dbNew->lastInsertId();
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
print_r($productMatching);
// ps_product_lang => from id_product
$table = 'ps_product_lang';
$cols = array(
'id_product' => null,
'id_shop' => null,
'id_lang' => null,
'description' => null,
'description_short' => null,
'link_rewrite' => null,
'meta_description' => null,
'meta_keywords' => null,
'meta_title' => null,
'name' => null,
'available_now' => null,
'available_later' => null,
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c => $v) {
switch($c) {
default:
$sql.= '`'.$c.'`, ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c => $v) {
switch($c) {
default:
$sql.= ':'.$c.', ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c => $v) {
switch($c) {
case 'id_product':
$stmtImport->bindValue($c, $productMatching[$item->{$c}]);
break;
default:
if (is_array($v)) {
$stmtImport->bindValue($c, $v['value']);
} else {
$stmtImport->bindValue($c, $item->{$c});
}
break;
}
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";
// ps_product_shop
$table = 'ps_product_shop';
$cols = array(
'id_product' => null,
'id_shop' => null,
'id_category_default' => array('value' => 351),
'id_tax_rules_group' => null,
'on_sale' => null,
'online_only' => null,
'ecotax' => null,
'minimal_quantity' => null,
'price' => null,
'wholesale_price' => null,
'unity' => null,
'unit_price_ratio' => null,
'additional_shipping_cost' => null,
'customizable' => null,
'uploadable_files' => null,
'text_fields' => null,
'active' => null,
'redirect_type' => null,
'id_product_redirected' => null,
'available_for_order' => array( 'value' => 1 ),
//'favorites_product' => null,
//'new_product' => null,
'available_date' => null,
'condition' => null,
'show_price' => array( 'value' => 1 ),
'indexed' => null,
'visibility' => null,
'cache_default_attribute' => null,
'advanced_stock_management' => null,
'date_add' => null,
'date_upd' => null,
'pack_stock_type' => null,
);
echo "Importing $table...\n";
$sql = "SELECT * FROM ".$table." WHERE id_product IN (".join(',', $products).")";
$stmtOld = $dbOld->query($sql);
if ($stmtOld->rowCount() == 0) {
echo "No Results ?\n";
} else {
try {
// Construct SQL
$sql = 'INSERT INTO '.$table.' (';
foreach ($cols as $c => $v) {
switch($c) {
default:
$sql.= '`'.$c.'`, ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ') VALUES (';
foreach ($cols as $c => $v) {
switch($c) {
default:
$sql.= ':'.$c.', ';
break;
}
}
$sql = trim($sql);
$sql = trim($sql, ',');
$sql.= ')';
// Start transaction
$dbNew->beginTransaction();
$i = 0;
while($item = $stmtOld->fetch(PDO::FETCH_OBJ)) {
$stmtImport = $dbNew->prepare($sql);
foreach ($cols as $c => $v) {
switch($c) {
case 'id_product':
$stmtImport->bindValue($c, $productMatching[$item->{$c}]);
break;
default:
if (is_array($v)) {
$stmtImport->bindValue($c, $v['value']);
} else {
$stmtImport->bindValue($c, $item->{$c});
}
break;
}
}
if ($stmtImport->execute() === false) {
echo "Error on $table - $i\n";
exit;
}
$i++;
}
if ($dbNew->commit() === false) {
echo "Error on $table\n";
exit;
}
} catch(Exception $e) {
$dbNew->rollBack();
echo "Error on $table\n";
exit;
}
echo $stmtOld->rowCount(). " / " . $i . "\n";
}
echo "End of importing $table\n";

41
synchro.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
clear
ONLYPULL=1
echo "Start sync\n";
if [ $ONLYPULL -eq 0 ]; then
#Dump local database
echo "Exporting the local Database"
mysqldump -h 192.168.0.41 -u root versionecologique > versionecologique.sql
printf "Export complete => file versionecologique.sql has been created\n"
printf "Replacing shop names\n"
sed -i -e 's/versionecologique.local/versionecologique.preprod.antadis.fr/g' versionecologique.sql
printf "Sending the Database dump to the preprod server"
PORT="4096"
rsync -e "ssh -p$PORT" -az ./versionecologique.sql root@versionecologique.preprod.antadis.fr:/home/www/versionecologique.preprod.antadis.fr
printf "Sending complete\n"
#printf "importing the Database on the preprod server\n"
ssh root@versionecologique.preprod.antadis.fr -p4096 "cd /home/www/versionecologique.preprod.antadis.fr \\
&& git pull origin master \\
&& mysql -u versionecologique -pShoh5Re5 versionecologique < versionecologique.sql \\
&& if [ -f /home/www/versionecologique.preprod.antadis.fr/www/cache/class_index.php ] ; then rm /home/www/versionecologique.preprod.antadis.fr/www/cache/class_index.php ; fi \\
&& mkdir -p /home/www/versionecologique.preprod.antadis.fr/www/{log,upload} \\
&& chown -R www-data:www-data www/* \\
"
else
#printf "importing the Database on the preprod server\n"
ssh root@versionecologique.preprod.antadis.fr -p4096 "cd /home/www/versionecologique.preprod.antadis.fr \\
&& git pull origin master \\
&& if [ -f /home/www/versionecologique.preprod.antadis.fr/www/cache/class_index.php ] ; then rm /home/www/versionecologique.preprod.antadis.fr/www/cache/class_index.php ; fi \\
&& mkdir -p /home/www/versionecologique.preprod.antadis.fr/www/{log,upload} \\
&& chown -R www-data:www-data www/* \\
"
fi
printf "Sync complete !! \n"

View File

@ -43,7 +43,8 @@ class Adapter_ProductPriceCalculator
$with_ecotax = true,
$use_group_reduction = true,
Context $context = null,
$use_customer_price = true
$use_customer_price = true,
$id_configurator = null
) {
return Product::getPriceStatic(
$id_product,
@ -62,7 +63,8 @@ class Adapter_ProductPriceCalculator
$with_ecotax,
$use_group_reduction,
$context,
$use_customer_price
$use_customer_price,
$id_configurator
);
}
}

View File

@ -128,3 +128,8 @@ if (Tools::isSubmit('getEmailHTML') && $email = Tools::getValue('email')) {
$email_html = AdminTranslationsController::getEmailHTML($email);
die($email_html);
}
if (Tools::getValue('generateMatrice')) {
$matrice = AdminCmsController::generateMatrice(Tools::getValue('idx'));
die($matrice);
}

View File

@ -39,6 +39,7 @@
{if $product.product_reference}{l s='Reference number:'} {$product.product_reference}<br />{/if}
{if $product.product_supplier_reference}{l s='Supplier reference:'} {$product.product_supplier_reference}{/if}
</a>
{hook h='displayAdminOrderProductConfigurator' product=$product mod='antadisconfigurator'}
<div class="row-editing-warning" style="display:none;">
<div class="alert alert-warning">
<strong>{l s='Editing this product line will remove the reduction and base price.'}</strong>

View File

@ -0,0 +1 @@
google-site-verification: google101961860538784e.html

BIN
www/img/123logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 230 KiB

BIN
www/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
www/img/logo_old.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -698,9 +698,13 @@ $.Autocompleter.Select = function (options, input, select, config) {
},
show: function() {
var offset = $(input).offset();
var inputHeight = $("#search_query_block").outerHeight();
var headerHeight = $("#header").outerHeight();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : ($(input).width() + parseInt($(input).css('padding-left')) + parseInt($(input).css('padding-right')) + parseInt($(input).css('margin-left')) + parseInt($(input).css('margin-right'))),
top: offset.top + input.offsetHeight,
// top: offset.top + input.offsetHeight,
top: inputHeight + headerHeight,
height: $(window).innerHeight() - (inputHeight + headerHeight),
left: offset.left
}).show();
if(options.scroll) {

View File

@ -0,0 +1,111 @@
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
include_once(dirname(__FILE__) . '/classes/AdvLink.php');
class AdvBlockLink extends Module
{
public function __construct()
{
$this->name = 'advblocklink';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Antadis';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Bloc liens avancé');
$this->description = $this->l('Gestion des blocs de liens du footer');
}
public function install()
{
$sql = array();
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advblocklink` (
`id_link` int(10) unsigned NOT NULL auto_increment,
`id_parent` varchar(255) NOT NULL,
`position` INT(11) UNSIGNED NOT NULL default 0,
`external` INT(3) NOT NULL,
`active` INT(3) NOT NULL,
PRIMARY KEY (`id_link`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advblocklink_shop` (
`id_link` int(10) unsigned NOT NULL auto_increment,
`id_shop` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_link`, `id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advblocklink_lang` (
`id_link` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`url` varchar(255),
PRIMARY KEY (`id_link`,`id_lang`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
foreach ($sql as $_sql) {
Db::getInstance()->Execute($_sql);
}
AdvLink::refreshPositionsAll();
$new_tab = new Tab();
$new_tab->class_name = 'AdminAdvBlockLink';
$new_tab->id_parent = Tab::getCurrentParentId();
$new_tab->module = $this->name;
$languages = Language::getLanguages();
foreach ($languages as $language) {
$new_tab->name[$language['id_lang']] = 'Liens du footer';
}
$new_tab->add();
return parent::install() && $this->registerHook('displayFooter') && $this->registerHook('actionRefreshBLocklink');
}
public function uninstall()
{
$sql = 'DROP TABLE IF EXISTS
`' . _DB_PREFIX_ . 'advblocklink_lang`,
`' . _DB_PREFIX_ . 'advblocklink_shop`,
`' . _DB_PREFIX_ . 'advblocklink`
';
Db::getInstance()->Execute($sql);
$idTab = Tab::getIdFromClassName('AdminAdvBlockLink');
if ($idTab) {
$tab = new Tab($idTab);
$tab->delete();
}
return parent::uninstall();
}
public function hookDisplayFooter($params)
{
if (!$this->isCached('advblocklink.tpl', $this->getCacheId())) {
$blockLinks = AdvLink::getBlockLinks();
if (!$blockLinks) {
return false;
}
$this->smarty->assign('blockLinks', $blockLinks);
}
return $this->display(__FILE__, 'advblocklink.tpl', $this->getCacheId());
}
public function hookActionRefreshBLocklink()
{
$this->_clearCache('advblocklink.tpl');
}
}

View File

@ -0,0 +1,294 @@
<?php
class AdvLink extends ObjectModel {
public $id_link;
public $id_parent;
public $title;
public $url;
public $external;
public $active;
public $position;
public $has_error = FALSE;
public static $definition = array(
'table' => 'advblocklink',
'primary' => 'id_link',
'multilang' => TRUE,
'fields' => array(
'id_link' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'id_parent' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'external' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'active' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'position' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
// Lang fields
'url' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isUrl', 'required' => FALSE, 'size' => 255),
'title' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isGenericName', 'required' => TRUE, 'size' => 255)
)
);
public function __construct($id = NULL, $id_lang = NULL, $id_shop = NULL) {
parent::__construct($id, $id_lang, $id_shop);
}
public function add($null_values = false, $autodate = true)
{
$this->position = $this->getHigherPosition($this->id_parent)+1;
$result = parent::add($null_values, $autodate);
//Add and remove shop association
if($result && Shop::isFeatureActive()) {
//Delete record if shop has been removed from the list
$result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'` ='.(int)$this->id.' AND id_shop NOT IN ('.implode(', ', $this->id_shop_list).')');
// Insert new record if shop has been added in the list
$insert='';
foreach ($this->id_shop_list as $id_shop) {
if($insert != '')
$insert .= ', ';
$insert .= '('.(int)$this->id.' , '.$id_shop.') ';
}
$result &= Db::getInstance()->execute('
INSERT IGNORE INTO `'._DB_PREFIX_.$this->def['table'].'_shop` (`'.$this->def['primary'].'`, `id_shop`)
VALUES '.$insert
);
}
Hook::exec('actionRefreshBLocklink');
return $result;
}
public function update($null_values = FALSE) {
// check if the object has a different parent
$old_id_parent = -1;
$old_object = new AdvLink((int)$this->id);
if (Validate::isLoadedObject($old_object)) {
$old_id_parent = $old_object->id_parent;
if ($old_id_parent != $this->id_parent) {
$this->position = $this->getHigherPosition($this->id_parent)+1;
}
}
// update the object
$result = parent::update($null_values);
//Add and remove shop association
if($result && Shop::isFeatureActive()) {
//Delete record if shop has been removed from the list
$result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'` ='.(int)$this->id.' AND id_shop NOT IN ('.implode(', ', $this->id_shop_list).')');
// Insert new record if shop has been added in the list
$insert='';
foreach ($this->id_shop_list as $id_shop) {
if($insert != '')
$insert .= ', ';
$insert .= '('.(int)$this->id.' , '.$id_shop.') ';
}
$result &= Db::getInstance()->execute('
INSERT IGNORE INTO `'._DB_PREFIX_.$this->def['table'].'_shop` (`'.$this->def['primary'].'`, `id_shop`)
VALUES '.$insert
);
}
// update links position of previous parent and the new one
if ($result && $old_id_parent != -1) {
$this->refreshPositions($old_id_parent);
$this->refreshPositions();
}
Hook::exec('actionRefreshBLocklink');
return $result;
}
public function delete() {
$this->has_error = FALSE;
$nb_sublinks = $this->getNbSubLinks($this->id);
if ($nb_sublinks>0) {
$this->has_error = TRUE;
return FALSE;
}
if (parent::delete()) {
$this->refreshPositions();
return true;
}
return false;
}
public function getNbSubLinks($id_link) {
return Db::getInstance()->getValue(
'SELECT COUNT(*) FROM `'._DB_PREFIX_.'advblocklink` WHERE `id_parent` = '.(int)$id_link
);
}
public function hasError() {
return $this->has_error;
}
public static function getPath($id_parent, $id_lang)
{
$links = [];
while ($id_parent) {
$obj = new AdvLink((int)$id_parent, (int)$id_lang);
$links[] = ['id_link' => $obj->id, 'title' => $obj->title ];
$id_parent = $obj->id_parent;
}
return array_reverse($links);
}
public static function getBlockLinks()
{
$context = Context::getContext();
$menuLinks = self::getLinks(0, $context);
foreach($menuLinks as $i => $link)
{
$menuLinks[$i]['children'] = self::getLinks($link['id_link'], $context);
$menuLinks[$i]['nbChildren'] = count($menuLinks[$i]['children']);
foreach($menuLinks[$i]['children'] as $y => $children)
{
$menuLinks[$i]['children'][$y]['children'] = self::getLinks($children['id_link'], $context);
}
}
return $menuLinks;
}
public static function getLinks($id_parent, $context)
{
$query = '
SELECT *
FROM `'._DB_PREFIX_.'advblocklink` adv
JOIN `'._DB_PREFIX_.'advblocklink_lang` advl ON adv.`id_link` = advl.`id_link` AND id_lang = '. (int)$context->language->id;
if (Shop::isFeatureActive()) {
$query .= 'JOIN `'._DB_PREFIX_.'advblocklink_shop` advs ON adv.`id_link` = advs.`id_link` AND id_shop = '. (int)$context->shop->id;
}
$query .= '
WHERE `id_parent` = ' . (int)$id_parent . '
ORDER BY `position` ASC
';
$links = Db::getInstance()->executeS($query);
return $links;
}
public static function getLinksTree(&$links, $id_parent, $id_lang, $id_link_to_exclude=-1, $level=-1)
{
$level++;
$sql = '
SELECT adv.`id_link`, `title`, `id_parent`
FROM `'._DB_PREFIX_.'advblocklink` adv
JOIN `'._DB_PREFIX_.'advblocklink_lang` advl ON adv.`id_link` = advl.`id_link` AND id_lang = '. (int)($id_lang) . '
WHERE `id_parent` = ' . (int)$id_parent;
if ($id_link_to_exclude!=-1) {
$sql .= ' AND adv.`id_link` <> '.(int)$id_link_to_exclude;
}
$sql .= ' ORDER BY `position` ASC';
$rows = Db::getInstance()->executeS($sql);
foreach($rows as &$row) {
$row['level'] = $level;
$links[] = $row;
if ($row['id_link']!=$id_link_to_exclude) {
self::getLinksTree($links, $row['id_link'], $id_lang, $id_link_to_exclude, $level);
}
}
}
public function cleanPositions(){
return Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'advblocklink`
SET `position`= `position` - 1
WHERE `id_link` = '.(int)$this->id_link.'
AND `position` > '.(int)$this->position);
}
public function updatePosition($way, $position)
{
$sql = 'SELECT `position`, `id_link`
FROM `'._DB_PREFIX_.'advblocklink`
WHERE `id_parent` = '.(int)$this->id_parent.'
ORDER BY `position` ASC';
if (!$res = Db::getInstance()->executeS($sql))
return false;
foreach ($res as $row)
if ((int)$row['id_link'] == (int)$this->id_link)
$moved_row = $row;
if (!isset($moved_row) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
$res = Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advblocklink`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `id_parent` = '.(int)$this->id_parent.'
AND `position`
'.($way
? '> '.(int)$moved_row['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_row['position'].' AND `position` >= '.(int)$position)
)
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advblocklink`
SET `position` = '.(int)$position.'
WHERE `id_link`='.(int)$moved_row['id_link']
);
$this->refreshPositions();
Hook::exec('actionRefreshBLocklink');
return $res;
}
public function refreshPositions($id_parent=-1){
$sql = 'SELECT `id_link`
FROM `'._DB_PREFIX_.'advblocklink`
WHERE `id_parent` = '.($id_parent>-1 ? $id_parent : (int)$this->id_parent).'
ORDER BY `position` ASC';
if (!$blocks = Db::getInstance()->executeS($sql))
return false;
$pos=0;
foreach ($blocks as $block) {
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advblocklink`
SET `position` = '.(int)$pos.'
WHERE `id_link`='.(int)$block['id_link']);
$pos++;
}
}
public function getHigherPosition($id_parent)
{
$sql = 'SELECT MAX(`position`)
FROM `'._DB_PREFIX_.'advblocklink`
WHERE `id_parent` = '.(int)$id_parent;
$position = DB::getInstance()->getValue($sql);
return (is_numeric($position)) ? $position : -1;
}
public static function refreshPositionsAll(){
$obj = new AdvLink(null);
$sql = 'SELECT DISTINCT id_parent FROM `'._DB_PREFIX_.'advblocklink`';
$rows = Db::getInstance()->executeS($sql);
foreach ($rows as $row) {
$obj->refreshPositions($row['id_parent']);
}
}
}

View File

@ -0,0 +1,266 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvLink.php';
class AdminAdvBlockLinkController extends ModuleAdminController {
private $current_link;
public function __construct() {
$this->table = 'advblocklink';
$this->className = 'AdvLink';
$this->identifier = 'id_link';
$this->lang = TRUE;
$this->deleted = FALSE;
$this->bootstrap = TRUE;
$this->position_identifier = 'id_link';
$this->_defaultOrderBy = 'position';
parent::__construct();
$this->actions = Tools::getValue('id_link', 0) ? array('edit', 'delete') : array('view', 'edit', 'delete');
$this->fields_list = array(
'id_link' => array(
'title' => 'ID',
'width' => 25
),
'title' => array(
'title' => $this->module->l('Titre'),
'width' => 45,
),
'url' => array(
'title' => $this->module->l('Url'),
'width' => 45,
),
'position' => array(
'title' => $this->l('Position'),
'align' => 'center',
'position' => 'position',
'filter_key' => 'a!position'
)
);
$this->current_link = isset($_GET['deleteadvblocklink']) ? new AdvLink((int)(Tools::getValue('id_link', 0))) : new AdvLink((int)(Tools::getValue('id_link', Tools::getValue('id_parent', 0))));
$this->_where = ' AND a.`id_parent` =' . (int)$this->current_link->id;
if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_ALL){
$this->_join .= 'JOIN `'._DB_PREFIX_.'advblocklink_shop` as ashop ON a.`id_link` = ashop.`id_link` AND ashop.`id_shop` IN ('.implode(', ', Shop::getContextListShopID()).') ';
$this->_group .= 'GROUP BY ashop.`id_link`';
}
}
public function initPageHeaderToolbar() {
parent::initPageHeaderToolbar();
if ($this->display != 'edit' && $this->display != 'add') {
$this->page_header_toolbar_btn['new_link'] = array(
'href' => self::$currentIndex.'&id_parent='.$this->current_link->id.'&addadvblocklink&token='.$this->token,
'desc' => $this->l('Ajouter un nouveau lien', NULL, NULL, FALSE),
'icon' => 'process-icon-new'
);
}
}
public function renderList() {
return parent::renderList();
}
public function initContent() {
if ($this->display == 'view') {
$this->display = 'list';
}
parent::initContent();
}
public function renderForm() {
$dbLinks = array();
$id = Tools::getValue('id_link');
AdvLink::getLinksTree($dbLinks, 0, Context::getContext()->cookie->id_lang, $id?$id:-1);
$links[] = array(
'id'=>'0',
'name' => $this->l('Aucun parent')
);
foreach ($dbLinks as $link) {
$links[] = array(
"id" => $link['id_link'],
"name" => str_repeat('--', $link['level']) . ' ' . $link['title']
);
}
$this->fields_form = array(
'tinymce' => TRUE,
'legend' => array(
'title' => $this->className,
),
'submit' => array(
'name' => 'submitadvblocklink',
'title' => $this->l('Save'),
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_link_parent'
),
array(
'type' => 'select',
'label' => $this->l('Lien parent'),
'name' => 'id_parent',
'required' => FALSE,
'options' => array(
'query' => $links,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'text',
'label' => $this->l('Nom'),
'name' => 'title',
'required' => TRUE,
'lang' => TRUE,
'size' => 114
),
array(
'type' => 'text',
'label' => $this->l('Lien'),
'name' => 'url',
'lang' => TRUE,
'required' => FALSE,
'size' => 114
),
array(
'type' => 'switch',
'label' => $this->l('Activé'),
'name' => 'active',
'required' => FALSE,
'is_bool' => TRUE,
'default' => 1,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
)
),
array(
'type' => 'switch',
'label' => $this->l('Lien externe ?'),
'name' => 'external',
'required' => FALSE,
'is_bool' => TRUE,
'default' => 1,
'values' => array(
array(
'id' => 'external_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'external_off',
'value' => 0,
'label' => $this->l('No')
)
)
),
array(
'type' => 'shop',
'label' => $this->l('Shop'),
'form_group_class' => 'fieldhide input_association',
'name' => 'checkBoxShopAsso_advblocklink'
)
)
);
$this->fields_value = array(
'id_link_parent' => (int)Tools::getValue('id_link_parent')
);
self::$currentIndex .= '&id_link_parent='.Tools::getValue('id_parent', Tools::getValue('id_link_parent'));
return parent::renderForm();
}
public function processAdd() {
$result = parent::processAdd();
$this->redirect_after = self::$currentIndex.'&conf=3&token='.$this->token.'&id_link='.Tools::getValue('id_parent');
return $result;
}
public function processUpdate() {
$result = parent::processUpdate();
$this->redirect_after = self::$currentIndex.'&conf=4&token='.$this->token.'&id_link='.Tools::getValue('id_parent');
return $result;
}
public function processDelete() {
$id_parent = $this->current_link->id_parent;
$object = parent::processDelete();
if ($object->hasError()) {
$this->errors = [Tools::displayError($this->l('This link can\'t be deleted : it contains at least one sub link.'))];
}
else {
$this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token.'&id_link='.$id_parent;
}
return $object;
}
protected function copyFromPost(&$object, $table) {
parent::copyFromPost($object, $table);
if(Shop::isFeatureActive())
{
$object->id_shop_list = array();
foreach (Tools::getValue('checkBoxShopAsso_advblocklink') as $id_shop => $value)
$object->id_shop_list[] = $id_shop;
}
}
public function ajaxProcessUpdatePositions()
{
$way = (int)(Tools::getValue('way'));
$id = (int)(Tools::getValue('id'));
$positions = Tools::getValue('link');
$obj = 'advblocklink';
if (is_array($positions)){
foreach ($positions as $position => $value)
{
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id)
{
$menu_obj = new AdvLink((int)$pos[2]);
if (Validate::isLoadedObject($menu_obj))
if (isset($position) && $menu_obj->updatePosition($way, $position))
{
echo 'ok position '.(int)$position.' for '.$obj.' '.(int)$pos[2]."\r\n";
}
else
echo '{"hasError" : true, "errors" : "Can not update '.$obj.' '.(int)$id.' to position '.(int)$position.' "}';
else
echo '{"hasError" : true, "errors" : "This '.$obj.' ('.(int)$id.') cannot be loaded"}';
break;
}
}
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,12 @@
{foreach from=$blockLinks item=blockLink}
<div class="block-links md3 sm3 xs4 xxs12 block ">
<span class="title">{if $blockLink.url}<a href="{$blockLink.url}">{$blockLink.title}</a>{else}{$blockLink.title}{/if}</span>
{if !empty($blockLink.children)}
<ul>
{foreach from=$blockLink.children item=link}
<li><a href="{$link.url|escape}"{if $link.external} onclick="window.open(this.href);return false;"{/if}>{$link.title}</a></li>
{/foreach}
</ul>
{/if}
</div>
{/foreach}

1
www/modules/advconstructor/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea/

View File

@ -0,0 +1 @@
#TODO:

View File

@ -0,0 +1,334 @@
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
include_once dirname(__FILE__).'/classes/AdvConstructorBlock.php';
include_once dirname(__FILE__).'/classes/AdvConstructorHook.php';
class AdvConstructor extends Module
{
public function __construct()
{
$this->name = 'advconstructor';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Antadis';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Générateur de bloc');
$this->description = $this->l('Générer n\'importe quel type de bloc');
}
/***********************/
/******* Install *******/
/***********************/
public function install()
{
$this->installDb();
$this->createTab();
$this->createFolder();
if ( !parent::install() ) {
$this->uninstallDb();
$this->deleteTab();
$this->uninstall();
return false;
}
Configuration::updateValue('ADVCONSTRUCTOR_HOOKS', '');
Configuration::updateValue('ADVCONSTRUCTOR_TYPE', 'alert,edito,footer,nav,seo');
Configuration::updateValue('ADVCONSTRUCTOR_ICON', 'loupe,message,rouage');
return true;
}
public function uninstall()
{
if ( !parent::uninstall() ) {
return false;
}
Configuration::deleteByName('ADVCONSTRUCTOR_HOOKS');
Configuration::deleteByName('ADVCONSTRUCTOR_TYPE');
Configuration::deleteByName('ADVCONSTRUCTOR_ICON');
$this->uninstallDb();
$this->deleteTab();
return true;
}
public function installDb()
{
$sql = array();
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor` (
`id_advconstructor` int(10) unsigned NOT NULL auto_increment,
`skin` varchar(255) NOT NULL,
`active` int(11),
`icon` varchar(255) NOT NULL,
`external` int(10) unsigned NOT NULL,
`date_from` datetime NOT NULL,
`date_to` datetime NOT NULL,
`date_add` datetime NOT NULL DEFAULT "0000-00-00 00:00:00",
`date_upd` datetime NOT NULL DEFAULT "0000-00-00 00:00:00",
PRIMARY KEY (`id_advconstructor`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor_lang` (
`id_advconstructor` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`subtitle` varchar(255) NOT NULL,
`link` varchar(255),
`content` text,
PRIMARY KEY (`id_advconstructor`,`id_lang`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor_shop` (
`id_advconstructor` int(10) unsigned NOT NULL,
`id_shop` int(10) unsigned NOT NULL,
`type` varchar(255) NOT NULL,
PRIMARY KEY (`id_advconstructor`,`id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor_category` (
`id_advconstructor` int(10) unsigned NOT NULL,
`id_category` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advconstructor`,`id_category`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor_product` (
`id_advconstructor` int(10) unsigned NOT NULL,
`id_product` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advconstructor`,`id_product`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advconstructor_hook` (
`id_advconstructor_hook` int(10) unsigned NOT NULL auto_increment,
`id_advconstructor` int(10) unsigned NOT NULL,
`id_hook` int(10) unsigned NOT NULL,
`id_category` int(10) unsigned,
`position` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advconstructor_hook`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
return $this->uninstallDb() && $this->updateDb($sql);
}
public function uninstallDb()
{
$sql = array();
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor_lang` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor_shop` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor_category` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor_product` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advconstructor_hook` ;';
return $this->updateDb($sql);
}
public function updateDb( $sqls )
{
foreach ( $sqls as $sql ) {
if ( !Db::getInstance()->execute($sql) ) {
return false;
}
}
return true;
}
public function createFolder()
{
$img_dir = _PS_IMG_DIR_ . 'constructor';
$folder = is_dir($img_dir);
if (!$folder)
{
$folder = mkdir($img_dir, 0755, true);
}
return $folder;
}
public function createTab()
{
$languages = Language::getLanguages();
$new_tab = new Tab();
$new_tab->class_name = 'AdminAdvConstructor';
$new_tab->id_parent = Tab::getCurrentParentId();
$new_tab->module = $this->name;
foreach ( $languages as $language ) {
$new_tab->name[$language['id_lang']] = 'Générateur de bloc';
}
$new_tab->add();
$id_tab_parent = $new_tab->id;
$new_tab = new Tab();
$new_tab->class_name = 'AdminAdvConstructorPosition';
$new_tab->id_parent = $id_tab_parent;
$new_tab->module = $this->name;
foreach ( $languages as $language ) {
$new_tab->name[$language['id_lang']] = 'Positions des blocs';
}
$new_tab->add();
}
public function deleteTab()
{
$idTab = Tab::getIdFromClassName('AdminAdvConstructor');
if ( $idTab ) {
$tab = new Tab($idTab);
$tab->delete();
}
$idTab = Tab::getIdFromClassName('AdminAdvConstructorPosition');
if ( $idTab ) {
$tab = new Tab($idTab);
$tab->delete();
}
}
/************************/
/********* HOOK *********/
/************************/
public function __call( $name, $args = array() )
{
$hookName = str_replace('hook', '', $name);
$id_hook = (int)Hook::getIdByName($hookName);
$hooks_id = explode( ",", Configuration::get('ADVCONSTRUCTOR_HOOKS') );
if (in_array($id_hook, $hooks_id)) {
$html = '';
$id_category = false;
if (Tools::getValue('controller') == 'category') {
$id_category = (int) Tools::getValue('id_category');
}
if ( $blocks = AdvConstructorBlock::getBlocksByHookID($id_hook, $id_category) ) {
foreach ($blocks as $block) {
$this->smarty->assign(
array(
'block' => $block,
'linkimg' =>'modules/advconstructor/img/',
)
);
$html .= $this->display(__FILE__, $block->skin.'.tpl');
}
}
return $html;
}
return NULL;
}
/*********************************/
/********* CONFIGURATION *********/
/*********************************/
public function getContent()
{
$this->_postProcess();
$this->_html = '';
$this->_html .= $this->renderForm();
return $this->_html;
}
protected function _postProcess()
{
if ( Tools::isSubmit('submitConfiguration') )
{
$this->unHook();
$hooks = Tools::getValue('hookBox');
foreach ($hooks as $hook) {
$this->registerHook(Hook::getNameById($hook));
}
$res = Configuration::updateValue('ADVCONSTRUCTOR_TYPE', Tools::getValue('ADVCONSTRUCTOR_TYPE'));
$res &= Configuration::updateValue('ADVCONSTRUCTOR_ICON', Tools::getValue('ADVCONSTRUCTOR_ICON'));
$res &= Configuration::updateValue('ADVCONSTRUCTOR_HOOKS', implode($hooks,','));
if (!$res) {
$errors[] = $this->displayError($this->l('The configuration could not be updated.'));
} else {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true).'&conf=6&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name);
}
}
}
public function renderForm()
{
$hooks = array();
$hooks_configuration = explode( ",", Configuration::get('ADVCONSTRUCTOR_HOOKS') );
foreach ( Hook::getHooks() as $hook ) {
$hook['selected'] = (bool) in_array($hook['id_hook'], $hooks_configuration);
$hooks[] = $hook;
}
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Configuration'),
'icon' => 'icon-plus-sign-alt'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Types de blocs'),
'name' => 'ADVCONSTRUCTOR_TYPE',
'value' => Configuration::get('ADVCONSTRUCTOR_TYPE')
),
array(
'type' => 'text',
'label' => $this->l('Icones de blocs'),
'name' => 'ADVCONSTRUCTOR_ICON',
'value' => Configuration::get('ADVCONSTRUCTOR_ICON')
),
array(
'type' => 'hook',
'label' => $this->l('Hooks à afficher'),
'name' => 'hookBox',
'values' => $hooks,
'col' => '9'
)
),
'submit' => array(
'title' => $this->l('Sauvegarder'),
)
),
);
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$this->fields_form = array();
$helper->module = $this;
$helper->identifier = $this->identifier;
$helper->submit_action = 'submitConfiguration';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => $this->getConfigFieldsValues()
);
$helper->override_folder = '/';
return $helper->generateForm(array($fields_form));
}
public function getConfigFieldsValues()
{
$id_shop_group = Shop::getContextShopGroupID();
$id_shop = Shop::getContextShopID();
return array(
'ADVCONSTRUCTOR_TYPE' => Configuration::get('ADVCONSTRUCTOR_TYPE'),
'ADVCONSTRUCTOR_ICON' => Configuration::get('ADVCONSTRUCTOR_ICON')
);
}
protected function unHook()
{
$sql = 'SELECT `id_hook` FROM `'._DB_PREFIX_.'hook_module` WHERE `id_module` = '.(int)$this->id;
$result = Db::getInstance()->executeS($sql);
foreach ($result as $row) {
$this->unregisterHook((int)$row['id_hook']);
$this->unregisterExceptions((int)$row['id_hook']);
}
}
}

View File

@ -0,0 +1,251 @@
<?php
class AdvConstructorBlock extends ObjectModel
{
public $id_advconstructor;
public $title;
public $subtitle;
public $icon;
public $link;
public $external;
public $content;
public $skin;
public $date_from = "0000-00-00 00:00:00";
public $date_to = "0000-00-00 00:00:00";
public $active = true;
public $date_add;
public $date_upd;
public $hooks;
public $categories;
public static $definition = array(
'table' => 'advconstructor',
'primary' => 'id_advconstructor',
'multilang' => true,
'fields' => array(
'title' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString',
'required' => TRUE
),
'subtitle' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString'
),
'icon' => array(
'type' => ObjectModel :: TYPE_STRING,
'validate' => 'isString'
),
'content' => array(
'type' => ObjectModel :: TYPE_HTML,
'lang' => true,
'validate' => 'isString'
),
'link' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString'
),
'external' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isBool'
),
'skin' => array(
'type' => ObjectModel :: TYPE_STRING,
'validate' => 'isString'
),
'active' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isBool'
),
'date_from' => array(
'type' => ObjectModel :: TYPE_DATE
),
'date_to' => array(
'type' => ObjectModel :: TYPE_DATE
),
'date_add' => array(
'type' => ObjectModel :: TYPE_DATE
),
'date_upd' => array(
'type' => ObjectModel :: TYPE_DATE
)
)
);
public function getHooks()
{
if (!isset($this->hooks)) {
$this->hooks = array();
foreach (Db::getInstance()->executeS('
SELECT `id_hook`
FROM `' . _DB_PREFIX_ . 'advconstructor_hook`
WHERE `id_advconstructor` = ' . $this->id . '
') as $hook) {
$this->hooks[] = $hook['id_hook'];
}
}
return $this->hooks;
}
public function getCategory()
{
if (!isset($this->categories)) {
$this->categories = array();
foreach (Db::getInstance()->executeS('
SELECT `id_category`
FROM `' . _DB_PREFIX_ . 'advconstructor_category`
WHERE `id_advconstructor` = ' . $this->id . '
') as $category) {
$this->categories[] = $category['id_category'];
}
}
return $this->categories;
}
public function addHooksAssociation( $hooks )
{
$sql = 'DELETE FROM `'._DB_PREFIX_.'advconstructor_hook` WHERE `id_advconstructor` = '.(int) $this->id;
if (!empty($hooks)) {
$sql .= ' AND id_hook NOT IN ('.implode(',',$hooks).')';
}
Db::getInstance()->execute($sql);
foreach ( $hooks as $hook ) {
if ( !AdvConstructorHook::associationHookExist( $this->id, $hook ) ) {
$advconstructor_hook = new AdvConstructorHook();
$advconstructor_hook->id_advconstructor = (int) $this->id;
$advconstructor_hook->id_hook = (int) $hook;
$advconstructor_hook->add();
$advconstructor_hook->refreshPositions();
}
}
}
public function addCategoryAssociation( $categories )
{
$sql = 'DELETE FROM `'._DB_PREFIX_.'advconstructor_category` WHERE `id_advconstructor` = '.(int) $this->id;
if (!empty($categories)) {
$sql .= ' AND id_category NOT IN ('.implode(',',$categories).')';
}
Db::getInstance()->execute($sql);
foreach ( $categories as $category ) {
if ( !$this->associationCategoryExist( $category ) ) {
Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'advconstructor_category`
(`id_advconstructor`,`id_category`)
VALUES ('.(int) $this->id.','.$category.')
');
}
}
}
public static function getBlocksByHookID( $id_hook, $id_category, $active = true)
{
$now = date('Y-m-d H:i:s');
$sql = 'SELECT id_advconstructor, position FROM `' . _DB_PREFIX_ . 'advconstructor_hook` WHERE id_hook ='.(int)$id_hook;
if ( $blocks_id = Db::getInstance()->executeS($sql) ) {
$blocks = array();
foreach ($blocks_id as $block_id) {
$blocks[] = $block_id['id_advconstructor'];
}
$collection = new Collection('AdvConstructorBlock', Context::getContext()->language->id);
$collection->Sqlwhere('a0.date_from <= IF(a0.date_from = "0000-00-00 00:00:00","0000-00-00 00:00:00","' . $now . '")' );
$collection->Sqlwhere('a0.date_to >= IF(a0.date_to = "0000-00-00 00:00:00","0000-00-00 00:00:00","' . $now . '")' );
$collection->Sqlwhere('a0.id_advconstructor IN ('.implode(',',$blocks).')' );
if($active === true) {
$collection->Sqlwhere('a0.active = 1');
}
if (Shop::isFeatureActive()) {
$collection->Sqlwhere('a0.`id_advconstructor` IN (
SELECT sa.`id_advconstructor`
FROM `' . _DB_PREFIX_ . 'advconstructor_shop` sa
WHERE sa.id_shop IN (' . implode(', ', Shop::getContextListShopID()) . ')
)');
}
$res = $collection->getAll();
$temp = array();
foreach ( $res as $row ) {
foreach ($blocks_id as $block_id) {
if ( $block_id['id_advconstructor'] == $row->id ) {
$show = false;
if ( !self::existInOneCategory( $row->id ) ) {
$show = true;
} else {
if ( $id_category && self::testCategoryAssociation( $row->id, $id_category ) ) {
$show = true;
}
}
if ( $show ){
$temp[$block_id['position']] = $row;
}
}
}
}
ksort($temp);
return $temp;
} else {
return false;
}
}
public static function getBlocksByHookIDLite( $id_hook )
{
$sql = 'SELECT id_advconstructor FROM `' . _DB_PREFIX_ . 'advconstructor_hook` WHERE id_hook ='.(int)$id_hook.' ORDER BY position ASC';
if ( $blocks_id = Db::getInstance()->executeS($sql) ) {
$blocks = array();
foreach ($blocks_id as $block_id) {
$blocks[] = $block_id['id_advconstructor'];
}
return $blocks;
} else {
return false;
}
}
public function associationCategoryExist( $id_category )
{
$sql = 'SELECT `id_advconstructor`
FROM `'._DB_PREFIX_.'advconstructor_category`
WHERE `id_category` = '.(int) $id_category.'
AND `id_advconstructor` = '.(int) $this->id;
if (!$id = Db::getInstance()->getRow($sql)) {
return false;
} else {
return true;
}
}
public static function existInOneCategory( $id_advconstructor ){
$sql = 'SELECT `id_advconstructor`
FROM `'._DB_PREFIX_.'advconstructor_category`
WHERE `id_advconstructor` = '.(int) $id_advconstructor;
if (!$id = Db::getInstance()->getRow($sql)) {
return false;
} else {
return true;
}
}
public static function testCategoryAssociation( $id_advconstructor, $id_category ){
$sql = 'SELECT `id_advconstructor`
FROM `'._DB_PREFIX_.'advconstructor_category`
WHERE `id_category` = '.$id_category.' AND
`id_advconstructor` = '.(int) $id_advconstructor;
if (!$id = Db::getInstance()->getRow($sql)) {
return false;
} else {
return true;
}
}
}

View File

@ -0,0 +1,94 @@
<?php
class AdvConstructorHook extends ObjectModel
{
public $id_advconstructor_hook;
public $id_advconstructor;
public $id_hook;
public $position = 0;
public static $definition = array(
'table' => 'advconstructor_hook',
'primary' => 'id_advconstructor_hook',
'fields' => array(
'id_advconstructor' => array(
'type' => ObjectModel :: TYPE_INT
),
'id_hook' => array(
'type' => ObjectModel :: TYPE_INT
),
'position' => array(
'type' => ObjectModel :: TYPE_INT
)
)
);
public function updatePosition($way, $position)
{
$sql = 'SELECT `position`, `id_advconstructor_hook`
FROM `'._DB_PREFIX_.'advconstructor_hook`
WHERE `id_hook` = '.(int)$this->id_hook.'
ORDER BY `position` ASC';
$res = Db::getInstance()->executeS($sql);
if (!$res)
return false;
foreach ($res as $row)
if ((int)$row['id_advconstructor_hook'] == (int)$this->id)
$moved_row = $row;
if (!isset($moved_row) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
$res = Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advconstructor_hook`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `id_hook` = '.(int)$this->id_hook.'
AND `position`
'.($way
? '> '.(int)$moved_row['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_row['position'].' AND `position` >= '.(int)$position)
)
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advconstructor_hook`
SET `position` = '.(int)$position.'
WHERE `id_advconstructor_hook`='.(int)$moved_row['id_advconstructor_hook']
);
$this->refreshPositions();
return $res;
}
public function refreshPositions(){
$sql = 'SELECT `id_advconstructor_hook`
FROM `'._DB_PREFIX_.'advconstructor_hook`
WHERE `id_hook` = '.(int)$this->id_hook.'
ORDER BY `position` ASC';
if (!$blocks = Db::getInstance()->executeS($sql))
return false;
$pos=0;
foreach ($blocks as $block) {
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advconstructor_hook`
SET `position` = '.(int)$pos.'
WHERE `id_advconstructor_hook`='.(int)$block['id_advconstructor_hook']);
$pos++;
}
}
public static function associationHookExist( $id_advconstructor, $id_hook )
{
$sql = 'SELECT `id_advconstructor_hook`
FROM `'._DB_PREFIX_.'advconstructor_hook`
WHERE `id_hook` = '.(int) $id_hook.'
AND `id_advconstructor` = '.(int) $id_advconstructor;
if (!$id = Db::getInstance()->getRow($sql)) {
return false;
} else {
return $id['id_advconstructor_hook'];
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,417 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvConstructorBlock.php';
include_once dirname(__FILE__).'/../../classes/AdvConstructorHook.php';
class AdminAdvConstructorController extends ModuleAdminController
{
public function __construct()
{
$this->table = 'advconstructor';
$this->className = 'AdvConstructorBlock';
$this->identifier = 'id_advconstructor';
$this->lang = true;
$this->deleted = false;
$this->bootstrap = true;
$this->explicitSelect = true;
$this->context = Context::getContext();
$this->_defaultOrderBy = 'id_advconstructor';
if ( Tools::getValue('hookid') ) {
$blocks = AdvConstructorBlock::getBlocksByHookIDLite(Tools::getValue('hookid'));
$blocks_id = "0";
if($blocks){
$blocks_id = implode(',',$blocks);
}
$this->_where = ' AND a.`id_advconstructor` IN ('.$blocks_id.')';
}
parent::__construct();
$this->fields_list = array(
'id_advconstructor' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 25,
'filter_key' => 'a!id_advconstructor'
),
'title' => array(
'title' => $this->l('Nom')
),
'skin' => array(
'title' => $this->l('Apparence')
),
'active' => array(
'title' => $this->l('Activé'),
'active' => 'status',
'filter_key' => 'a!active',
'align' => 'text-center',
'type' => 'bool',
'class' => 'fixed-width-sm',
'orderby' => false
),
);
$this->actions = array('edit','delete');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Supprimer la liste'),
'icon' => 'icon-trash',
'confirm' => $this->l('Supprimer les blocs selectionné?')
)
);
$this->specificConfirmDelete = false;
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if ($this->display == 'edit' || $this->display == 'add') {
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => self::$currentIndex.'&token='.$this->token,
'desc' => $this->l('Retour à la liste', null, null, false),
'icon' => 'process-icon-back'
);
}
$this->page_header_toolbar_btn['new_constructor'] = array(
'href' => self::$currentIndex.'&addadvconstructor&token='.$this->token,
'desc' => $this->l('Ajouter un nouveau bloc', null, null, false),
'icon' => 'process-icon-new'
);
$this->page_header_toolbar_btn['position'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvConstructorPosition'),
'desc' => $this->l('Gérer les positions', null, null, false),
'icon' => 'process-icon-modules-list'
);
}
public function renderForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$context = Context::getContext();
$hooks_id = explode( ",", Configuration::get('ADVCONSTRUCTOR_HOOKS') );
$hooks = array();
foreach ($hooks_id as $hook_id) {
$hook = new Hook($hook_id, $context->language->id);
$hooks[] = array(
'id_hook' => $hook->id,
'name' => $hook->name,
'title' => $hook->title,
);
}
$block_hooks = array();
if (!empty($this->object->id)) {
$block_hooks = $this->object->getHooks();
}
foreach ($hooks as $key => $hook) {
$hook['selected'] = (bool) in_array($hook['id_hook'], $block_hooks);
$hooks[$key] = $hook;
}
$skins = array();
foreach ( explode(',', Configuration::get('ADVCONSTRUCTOR_TYPE')) as $skin ) {
$skins[] = array(
'id' => $skin,
'name' => $skin
);
}
$icons = array();
$icons[] = array('id' => '', 'name' => 'Aucune');
foreach ( explode(',', Configuration::get('ADVCONSTRUCTOR_ICON')) as $icon ) {
$icons[] = array(
'id' => $icon,
'name' => ucfirst($icon)
);
}
if ( Tools::isSubmit('id_advconstructor') ) {
$id_advconstructor = (int)Tools::getValue('id_advconstructor');
$image = __PS_BASE_URI__.'img/constructor/image/'.$id_advconstructor ;
} else {
$image = "noimg" ;
}
$selected_categories = !empty($this->object->id) ? $this->object->getCategory() : array();
$this->fields_form = array(
'multilang' => true,
'tinymce' => true,
'legend' => array(
'title' => $this->l('Bloc'),
),
'submit' => array(
'name' => 'submitBlock',
'title' => $this->l('Enregistrer')
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Titre'),
'name' => 'title',
'lang' => true,
'required' => true,
'form_group_class' => 'fieldhide input_info',
'size' => 255
),
array(
'type' => 'text',
'label' => $this->l('Sous-titre'),
'name' => 'subtitle',
'lang' => true,
'form_group_class' => 'fieldhide input_info',
'size' => 255
),
array(
'type' => 'text',
'label' => $this->l('Lien'),
'name' => 'link',
'lang' => true,
'form_group_class' => 'fieldhide input_info',
'size' => 255
),
array(
'type' => 'switch',
'label' => $this->l('Lien externe'),
'name' => 'external',
'required' => false,
'is_bool' => true,
'form_group_class' => 'fieldhide input_info',
'values' => array(
array(
'id' => 'external_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'external_off',
'value' => 0,
'label' => $this->l('No')
)
)
),
array(
'type' => 'textarea',
'label' => $this->l('Contenu'),
'name' => 'content',
'form_group_class' => 'fieldhide input_info',
'autoload_rte' => true,
'lang' => true,
'cols' => 60,
'rows' => 120
),
array(
'type' => 'datetime',
'label' => $this->l('Date de début'),
'name' => 'date_from',
'form_group_class' => 'fieldhide input_dates',
'size' => 33,
),
array(
'type' => 'datetime',
'label' => $this->l('Date de fin'),
'name' => 'date_to',
'form_group_class' => 'fieldhide input_dates',
'size' => 33,
),
array(
'type' => 'select',
'label' => $this->l('Apparence du bloc'),
'name' => 'skin',
'required' => true,
'form_group_class' => 'fieldhide input_association',
'options' => array(
'query' => $skins,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'hook',
'label' => $this->l('Hook'),
'name' => 'hookBox',
'required' => true,
'form_group_class' => 'fieldhide input_association',
'values' => $hooks,
'col' => '9',
),
array(
'type' => 'categories',
'label' => $this->l('Parent category'),
'name' => 'categoryBox',
'tree' => array(
'id' => 'categories-tree',
'selected_categories' => $selected_categories,
'use_checkbox' => true,
'root_category' => $context->shop->getCategory()
),
'col' => '9',
'form_group_class' => 'fieldhide input_association'
),
array(
'type' => 'select',
'label' => $this->l('Icone'),
'name' => 'icon',
'required' => FALSE,
'form_group_class' => 'fieldhide input_img',
'options' => array(
'query' => $icons,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'file',
'label' => $this->l('Choisisser une image'),
'name' => 'image',
'form_group_class' => 'fieldhide input_img',
'url' => $image
),
array(
'type' => 'switch',
'label' => $this->l('Actif'),
'name' => 'active',
'required' => false,
'class' => 't',
'form_group_class' => 'fieldhide input_info',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1
),
array(
'id' => 'active_off',
'value' => 0
)
),
),
)
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->l('Boutique'),
'name' => 'checkBoxShopAsso',
'form_group_class' => 'fieldhide input_association'
);
}
return parent::renderForm();
}
public function init()
{
parent::init();
if (Shop::getContext() == Shop::CONTEXT_SHOP) {
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_. $this->table .'_shop` sa ON (a.`' . $this->identifier . '` = sa.`' . $this->identifier . '` AND sa.id_shop = '.(int)$this->context->shop->id.') ';
}
if (Shop::getContext() == Shop::CONTEXT_SHOP && Shop::isFeatureActive()) {
$this->_where = ' AND sa.`id_shop` = '.(int)Context::getContext()->shop->id;
}
}
public function postProcess()
{
$result = parent::postProcess();
if ( Validate::isLoadedObject($result) ) {
$this->generatePicture($result);
$result->addHooksAssociation(Tools::getValue('hookBox'));
$result->addCategoryAssociation(Tools::getValue('categoryBox'));
$this->redirect_after = self::$currentIndex.'&id_advconstructor='.(int)$result->id.'&update'.$this->table.'&token='.$this->token;
}
return $result;
}
public function generatePicture($object)
{
$languages = Language::getLanguages(false);
foreach ($languages as $language) {
$tabimgs = array(
"image",
"icon"
);
foreach ( $tabimgs as $tabimg ) {
$namePost = $tabimg.'_'.$language['id_lang'];
if (isset($_FILES[$namePost]) && !empty($_FILES[$namePost]['tmp_name']) ) {
$fileTemp = $_FILES[$namePost]['tmp_name'];
$fileParts = pathinfo($_FILES[$namePost]['name']);
if ( $fileParts['extension'] == 'jpg' || $fileParts['extension'] == 'png' ) {
if(!is_dir(_PS_IMG_DIR_.'constructor/'.$tabimg)) {
mkdir(_PS_IMG_DIR_.'constructor/'.$tabimg, 0775);
}
$res = move_uploaded_file($fileTemp, _PS_IMG_DIR_.'constructor/'.$tabimg.'/'. $object->id . '_'.$language['id_lang'].'.jpg');
if(!$res)
$this->errors[] = sprintf(Tools::displayError('An error occured during upload of file %s'), $object->id . '.jpg');
else
$this->confirmations[] = sprintf($this->l('File %s has been uploaded'), $object->id . '.jpg');
} else
$this->errors[] = sprintf(Tools::displayError('File %s have not good extension, only .jpg or .png'), $object->id . '.jpg');
}
}
}
}
protected function updateAssoShop($id_object)
{
if (!Shop::isFeatureActive()) {
return;
}
$assos_data = $this->getSelectedAssoShop($this->table, $id_object);
$exclude_ids = $assos_data;
foreach (Db::getInstance()->executeS('SELECT id_shop FROM ' . _DB_PREFIX_ . 'shop') as $row) {
if (!$this->context->employee->hasAuthOnShop($row['id_shop'])) {
$exclude_ids[] = $row['id_shop'];
}
}
Db::getInstance()->delete($this->table . '_shop', '`' . $this->identifier . '` = ' . (int) $id_object . ($exclude_ids ? ' AND id_shop NOT IN (' . implode(', ', $exclude_ids) . ')' : ''));
$insert = array();
foreach ($assos_data as $id_shop) {
$insert[] = array(
$this->identifier => $id_object,
'id_shop' => (int) $id_shop,
);
}
return Db::getInstance()->insert($this->table . '_shop', $insert, FALSE, TRUE, Db::INSERT_IGNORE);
}
protected function getSelectedAssoShop($table)
{
if (!Shop::isFeatureActive()) {
return array();
}
$shops = Shop::getShops(TRUE, NULL, TRUE);
if (count($shops) == 1 && isset($shops[0])) {
return array($shops[0], 'shop');
}
$assos = array();
if (Tools::isSubmit('checkBoxShopAsso_' . $table)) {
foreach (Tools::getValue('checkBoxShopAsso_' . $table) as $id_shop => $value) {
$assos[] = (int) $id_shop;
}
} else if (Shop::getTotalShops(FALSE) == 1) {
// if we do not have the checkBox multishop, we can have an admin with only one shop and being in multishop
$assos[] = (int) Shop::getContextShopID();
}
return $assos;
}
}

View File

@ -0,0 +1,159 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvConstructorBlock.php';
include_once dirname(__FILE__).'/../../classes/AdvConstructorHook.php';
class AdminAdvConstructorPositionController extends ModuleAdminController
{
public $_step = 0;
public $_hook = 0;
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvConstructor'),
'desc' => $this->l('Retour à la liste de bloc', null, null, false),
'icon' => 'process-icon-back'
);
if ($this->display != 'edit' && $this->display != 'add') {
$this->page_header_toolbar_btn['back_to_choice'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvConstructorPosition'),
'desc' => $this->l('Retour au choix du hook', null, null, false),
'icon' => 'process-icon-back'
);
}
}
public function renderForm()
{
$context = Context::getContext();
$hooks_id = explode( ",", Configuration::get('ADVCONSTRUCTOR_HOOKS') );
$hooks = array();
foreach ($hooks_id as $hook_id) {
$hook = new Hook($hook_id, $context->language->id);
$hooks[] = array(
'id' => $hook->id,
'name' => $hook->name
);
}
$this->fields_form = array(
'multilang' => true,
'tinymce' => true,
'legend' => array(
'title' => $this->l('Choissisez le hook'),
),
'submit' => array(
'name' => 'submitHook',
'title' => $this->l('Changer les positions')
),
'input' => array(
'icon' => array(
'type' => 'select',
'label' => $this->l('Hook'),
'name' => 'hook',
'required' => FALSE,
'options' => array(
'query' => $hooks,
'id' => 'id',
'name' => 'name'
)
)
)
);
return parent::renderForm();
}
public function renderList()
{
$context = Context::getContext();
$this->table = 'advconstructor_hook';
$this->className = 'AdvConstructorHook';
$this->identifier = 'id_advconstructor_hook';
$this->lang = false;
$this->deleted = false;
$this->bootstrap = true;
$this->explicitSelect = true;
$this->context = Context::getContext();
$this->_defaultOrderBy = 'position';
$this->position_identifier = 'ID';
$this->_select = "a.`id_advconstructor`, c.`title` AS `NAME`";
$this->_where = ' AND a.`id_hook` = '.$this->_hook;
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'advconstructor_lang` c ON (c.`id_advconstructor` = a.`id_advconstructor` AND c.`id_lang` = '.$context->language->id.') ';
$this->fields_list = array(
'id_advconstructor_hook' => array(
'title' => $this->l('ID de la position'),
'align' => 'center',
'width' => 25
),
'id_advconstructor' => array(
'title' => $this->l('ID du bloc'),
'align' => 'center',
'width' => 25
),
'NAME' => array(
'title' => $this->l('Nom du bloc'),
'align' => 'center'
),
'position' => array(
'title' => $this->l('Position'),
'align' => 'center',
'position' => 'position',
'filter_key' => 'a!position'
)
);
return parent::renderList();
}
public function postProcess()
{
if ( Tools::isSubmit("submitHook") ) {
$this->_step = 1;
$this->_hook = Tools::getValue('hook');
$this->display = 'list';
} else {
$this->display = 'add';
}
return parent::postProcess();
}
public function ajaxProcessUpdatePositions()
{
$way = (int)(Tools::getValue('way'));
$id = (int)(Tools::getValue('id'));
$positions = Tools::getValue('advconstructor_hook');
$page = (int)Tools::getValue('page');
$selected_pagination = (int)Tools::getValue('selected_pagination');
$obj = 'position hook';
if ( is_array($positions) ) {
foreach ($positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id) {
$hook_position = new AdvConstructorHook((int)$pos[2]);
if (isset($position) && $hook_position->updatePosition( $way, $position ) ) {
die(true);
} else {
die('{"hasError" : true, errors : "Cannot update blocks position"}');
}
}
}
} else {
die('{"hasError" : true, errors : "Cannot update blocks position"}');
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,48 @@
{extends file="helpers/form/form.tpl"}
{block name="input"}
{if $input.type == 'hook'}
{assign var=hooks value=$input.values}
{if count($hooks) && isset($hooks)}
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered">
<thead>
<tr>
<th class="fixed-width-xs">
<span class="title_box">
<input type="checkbox" name="checkme" id="checkme" onclick="checkDelBoxes(this.form, 'hookBox[]', this.checked)" />
</span>
</th>
<th class="fixed-width-xs"><span class="title_box">{l s='ID' mod='advconstructor'}</span></th>
<th>
<span class="title_box">
{l s='Nom du hook' mod='advconstructor'}
</span>
</th>
</tr>
</thead>
<tbody>
{foreach $hooks as $key => $hook}
<tr>
<td>
{assign var=id_checkbox value=hookBox|cat:'_'|cat:$hook['id_hook']}
<input type="checkbox" name="hookBox[]" class="hookBox" id="{$id_checkbox}" value="{$hook['id_hook']}" {if $hook['selected']}checked="checked"{/if} />
</td>
<td>{$hook['id_hook']}</td>
<td>
<label for="{$id_checkbox}">{$hook['name']} ({$hook['title']})</label>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
{else}
<p>
{l s='Pas de hook' mod='advconstructor'}
</p>
{/if}
{/if}
{$smarty.block.parent}
{/block}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,109 @@
{extends file="helpers/form/form.tpl"}
{block name="fieldset" prepend}
<div class="productTabs pvsaleadm">
<ul class="tab nav nav-tabs">
<li class="tab-row active">
<a class="tab-page" id="cart_rule_link_informations">
<i class="icon-info"></i> {l s='Informations' mod='advconstructor'}
</a>
</li>
<li class="tab-row">
<a class="tab-page" id="cart_rule_link_association">
<i class="icon-random"></i> {l s='Associations' mod='advconstructor'}
</a>
</li>
<li class="tab-row">
<a class="tab-page" id="cart_rule_link_images">
<i class="icon-picture"></i> {l s='Images' mod='advconstructor'}
</a>
</li>
<li class="tab-row">
<a class="tab-page" id="cart_rule_link_dates">
<i class="icon-calendar"></i> {l s='Dates' mod='advconstructor'}
</a>
</li>
</ul>
</div>
<script>
$(document).ready(function(){
$('.fieldhide').hide();
$('.input_info').show();
$('#cart_rule_link_images').click(function(){
$('.fieldhide').hide();
$('.input_img').show();
$('.tab-row').removeClass('active');
$(this).parent().addClass('active');
});
$('#cart_rule_link_informations').click(function(){
$('.fieldhide').hide();
$('.input_info').show();
$('.tab-row').removeClass('active');
$(this).parent().addClass('active');
});
$('#cart_rule_link_dates').click(function(){
$('.fieldhide').hide();
$('.input_dates').show();
$('.tab-row').removeClass('active');
$(this).parent().addClass('active');
});
$('#cart_rule_link_association').click(function(){
$('.fieldhide').hide();
$('.input_association').show();
$('.tab-row').removeClass('active');
$(this).parent().addClass('active');
});
});
</script>
{/block}
{block name="input"}
{if $input.type == 'hook'}
{assign var=hooks value=$input.values}
{if count($hooks) && isset($hooks)}
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered">
<thead>
<tr>
<th class="fixed-width-xs">
<span class="title_box">
<input type="checkbox" name="checkme" id="checkme" onclick="checkDelBoxes(this.form, 'hookBox[]', this.checked)" />
</span>
</th>
<th class="fixed-width-xs"><span class="title_box">{l s='ID' mod='advconstructor'}</span></th>
<th>
<span class="title_box">
{l s='Nom du hook' mod='advconstructor'}
</span>
</th>
</tr>
</thead>
<tbody>
{foreach $hooks as $key => $hook}
<tr>
<td>
{assign var=id_checkbox value=hookBox|cat:'_'|cat:$hook['id_hook']}
<input type="checkbox" name="hookBox[]" class="hookBox" id="{$id_checkbox}" value="{$hook['id_hook']}" {if $hook['selected']}checked="checked"{/if} />
</td>
<td>{$hook['id_hook']}</td>
<td>
<label for="{$id_checkbox}">{$hook['name']} ({$hook['title']})</label>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
{else}
<p>
{l s='Pas de hook' mod='advconstructor'}
</p>
{/if}
{/if}
{$smarty.block.parent}
{/block}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,54 @@
{assign var=languages value=Language::getLanguages(false)}
{if !isset($defaultFormLanguage)}
{assign var=defaultFormLanguage value=$languages[0].id_lang}
{/if}
<div class="row">
{foreach from=$languages item=language}
{if $languages|count > 1}
<div class="translatable-field lang-{$language.id_lang}" {if $language.id_lang != $defaultFormLanguage}style="display:none"{/if}>
{/if}
<div class="col-lg-6">
{if $url != "noimg"}
<img src="{$url}_{$language.id_lang}.jpg" class="img-thumbnail" />
{/if}
<input id="{$name}_{$language.id_lang}" type="file" name="{$name}_{$language.id_lang}" class="hide" />
<div class="dummyfile input-group">
<span class="input-group-addon"><i class="icon-file"></i></span>
<input id="{$name}_{$language.id_lang}-name" type="text" class="disabled" name="filename" readonly />
<span class="input-group-btn">
<button id="{$name}_{$language.id_lang}-selectbutton" type="button" name="submitAddAttachments" class="btn btn-default">
<i class="icon-folder-open"></i> {l s='Choose a file' mod='privatesales'}
</button>
</span>
</div>
</div>
{if $languages|count > 1}
<div class="col-lg-2">
<button type="button" class="btn btn-default dropdown-toggle" tabindex="-1" data-toggle="dropdown">
{$language.iso_code}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{foreach from=$languages item=lang}
<li><a href="javascript:hideOtherLanguage({$lang.id_lang});" tabindex="-1">{$lang.name}</a></li>
{/foreach}
</ul>
</div>
{/if}
{if $languages|count > 1}
</div>
{/if}
<script>
$(document).ready(function(){
$('#{$name}_{$language.id_lang}-selectbutton').click(function(e){
$('#{$name}_{$language.id_lang}').trigger('click');
});
$('#{$name}_{$language.id_lang}').change(function(e){
var val = $(this).val();
var file = val.split(/[\\/]/);
$('#{$name}_{$language.id_lang}-name').val(file[file.length-1]);
});
});
</script>
{/foreach}
</div>

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,10 @@
<div class="md3 sm4 xs4 xxs12 animated-full">
<div class="encart">
<div class="content">
<div class="inner">
<h4 class="title">{$block->title}</h4>
{$block->content}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="md3 sm4 xs4 xxs12 animated-full">
<div class="encart">
<div class="content">
<div class="inner">
<h4 class="title">{$block->title}</h4>
{$block->content}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,3 @@
<div class="col-xs-12">
<img src="{$base_dir}img/constructor/image/{$block->id}_{$cookie->id_lang}.jpg" />
</div>

View File

@ -0,0 +1,5 @@
<div class="col-xs-12">
<h1>{$block->title}</h1>
<h2>{$block->subtitle}</h2>
{$block->content}
</div>

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,154 @@
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
require_once dirname(__FILE__).'/classes/AdvMenuLink.php';
class AdvMenu extends Module
{
public function __construct()
{
$this->name = 'advmenu';
$this->tab = 'front_office_features';
$this->version = '2.0';
$this->author = 'Antadis';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Menu avancé');
$this->description = $this->l('Gestion des blocs de liens du menu du site');
}
public function install()
{
if (!parent::install()
|| !$this->installDb()
|| !$this->installTab()
|| !$this->registerHook('displayMenu')
|| !$this->registerHook('actionSaveMenu')
) {
$this->uninstall();
return false;
}
AdvMenuLink::refreshPositionsAll();
return true;
}
public function uninstall()
{
if (!parent::uninstall()
|| !$this->uninstallTab()
|| !$this->uninstallDb()
|| !$this->unregsiterHook('displayMenu')
|| !$this->unregsiterHook('actionSaveMenu')
) {
return false;
}
return true;
}
public function installDb()
{
$return = true;
$sqlQueries = array();
$sqlQueries[] = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'advmenu` (
`id_link` INT(10) UNSIGNED NOT NULL auto_increment,
`id_parent` VARCHAR(255) NOT NULL,
`classbloc` VARCHAR(255),
`position` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`external` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id_link`)
) ENGINE='._MYSQL_ENGINE_.'DEFAULT CHARSET=utf8';
$sqlQueries[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advmenu_shop` (
`id_link` INT(10) UNSIGNED NOT NULL auto_increment,
`id_shop` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id_link`, `id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sqlQueries[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advmenu_lang` (
`id_link` INT(10) UNSIGNED NOT NULL,
`id_lang` INT(10) UNSIGNED NOT NULL,
`title` VARCHAR(255) NOT NULL,
`url` VARCHAR(255),
`cta` text,
PRIMARY KEY (`id_link`,`id_lang`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
foreach ($sqlQueries as $sql) {
$return = Db::getInstance()->Execute($sql);
}
return $return;
}
public function uninstallDb()
{
return Db::getInstance()->execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'advmenu`, `'._DB_PREFIX_.'advmenu_lang`, `'._DB_PREFIX_.'advmenu_shop`');
}
public function installTab()
{
$langs = Language::getLanguages();
$id_lang = (int)Configuration::get('PS_LANG_DEFAULT');
$tab_i18n = array(
'fr' => array('Menu du site'),
'en' => array('Website menu')
);
$tab = new Tab();
$tab->class_name = 'AdminAdvMenu';
$tab->module = $this->name;
$tab->id_parent = Tab::getCurrentParentId();
$tab->position = 10;
foreach($langs as $lang){
if(isset($tab_i18n[$lang['iso_code']])) {
$tab->name[$lang['id_lang']] = $tab_i18n[$lang['iso_code']][0];
} else {
$tab->name[$lang['id_lang']] = $tab_i18n['en'][0];
}
}
return $tab->save();
}
public function uninstallTab()
{
if ($id_tab = Tab::getIdFromClassName('AdminAdvMenu')) {
$tab = new Tab((int)$id_tab);
return $tab->delete();
}
return true;
}
/*
* Display top menu
*/
public function hookDisplayMenu($params)
{
if (!$this->isCached('advmenu.tpl', $this->getCacheId())) {
$id_lang = Context::getContext()->language->id;
$menuLinks = AdvMenuLink::getMenu();
if (!$menuLinks) {
return false;
}
foreach($menuLinks as $key => $links) {
if ($links['id_category']) {
$category = new Category($links['id_category'], $id_lang);
$menuLinks[$key]['category'] = $category;
$menuLinks[$key]['subcategories'] = $category->getSubCategories($id_lang);
}
}
$this->smarty->assign('menuLinks', $menuLinks);
}
return $this->display(__FILE__, 'advmenu.tpl', $this->getCacheId());
}
public function hookActionSaveMenu()
{
$this->_clearCache('advmenu.tpl');
}
}

View File

@ -0,0 +1,281 @@
<?php
class AdvMenuLink extends ObjectModel {
public $id_link;
public $id_parent;
public $id_category;
public $cta;
public $title;
public $url;
public $classbloc;
public $external;
public $position;
public $has_error = FALSE;
public static $definition = array(
'table' => 'advmenu',
'primary' => 'id_link',
'multilang' => TRUE,
'fields' => array(
'id_link' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'id_parent' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'id_category' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'external' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'position' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'classbloc' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'),
// Lang fields
'url' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isUrl', 'required' => FALSE, 'size' => 255),
'title' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isGenericName', 'required' => TRUE, 'size' => 255),
'cta' => array('type' => self::TYPE_HTML, 'lang' => TRUE, 'validate' => 'isCleanHtml')
)
);
public function add($null_values = false, $autodate = true)
{
$this->position = $this->getHigherPosition($this->id_parent)+1;
$result = parent::add($null_values, $autodate);
//Add and remove shop association
if($result && Shop::isFeatureActive()) {
//Delete record if shop has been removed from the list
$result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'` ='.(int)$this->id.' AND id_shop NOT IN ('.implode(', ', $this->id_shop_list).')');
// Insert new record if shop has been added in the list
$insert='';
foreach ($this->id_shop_list as $id_shop) {
if($insert != '')
$insert .= ', ';
$insert .= '('.(int)$this->id.' , '.$id_shop.') ';
}
$result &= Db::getInstance()->execute('
INSERT IGNORE INTO `'._DB_PREFIX_.$this->def['table'].'_shop` (`'.$this->def['primary'].'`, `id_shop`)
VALUES '.$insert
);
}
Hook::exec('actionSaveMenu');
return $result;
}
public function update($null_values = FALSE)
{
// check if the object has a different parent
$old_id_parent = -1;
$old_object = new AdvMenuLink((int)$this->id);
if (Validate::isLoadedObject($old_object)) {
$old_id_parent = $old_object->id_parent;
if ($old_id_parent != $this->id_parent) {
$this->position = $this->getHigherPosition($this->id_parent)+1;
}
}
// update the object
$result = parent::update($null_values);
//Add and remove shop association
if($result && Shop::isFeatureActive()) {
//Delete record if shop has been removed from the list
$result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'` ='.(int)$this->id.' AND id_shop NOT IN ('.implode(', ', $this->id_shop_list).')');
// Insert new record if shop has been added in the list
$insert='';
foreach ($this->id_shop_list as $id_shop) {
if($insert != '')
$insert .= ', ';
$insert .= '('.(int)$this->id.' , '.$id_shop.') ';
}
$result &= Db::getInstance()->execute('INSERT IGNORE INTO `'._DB_PREFIX_.$this->def['table'].'_shop` (`'.$this->def['primary'].'`, `id_shop`) VALUES '.$insert);
}
// update links position of previous parent and the new one
if ($result && $old_id_parent != -1) {
$this->refreshPositions($old_id_parent);
$this->refreshPositions();
}
Hook::exec('actionSaveMenu');
return $result;
}
public function delete()
{
$this->has_error = FALSE;
$nb_sublinks = $this->getNbSubLinks($this->id);
if ($nb_sublinks>0) {
$this->has_error = TRUE;
return FALSE;
}
if (parent::delete()) {
$this->refreshPositions();
return true;
}
return false;
}
public function getNbSubLinks($id_link)
{
return Db::getInstance()->getValue(
'SELECT COUNT(*) FROM `'._DB_PREFIX_.'advmenu` WHERE `id_parent` = '.(int)$id_link
);
}
public function hasError()
{
return $this->has_error;
}
public static function getPath($id_parent, $id_lang)
{
$links = [];
while ($id_parent) {
$obj = new AdvMenuLink((int)$id_parent, (int)$id_lang);
$links[] = ['id_link' => $obj->id, 'title' => $obj->title ];
$id_parent = $obj->id_parent;
}
return array_reverse($links);
}
public static function getMenu()
{
$context = Context::getContext();
$menuLinks = self::getLinks(0, $context);
return $menuLinks;
}
public static function getLinks($id_parent, $context)
{
$query = '
SELECT adv.`id_link`, `title`, `url`, `classbloc`, `cta`, `external`, `id_category`
FROM `'._DB_PREFIX_.'advmenu` adv
JOIN `'._DB_PREFIX_.'advmenu_lang` advl ON adv.`id_link` = advl.`id_link` AND id_lang = '. (int)$context->language->id;
if (Shop::isFeatureActive()) {
$query .= 'JOIN `'._DB_PREFIX_.'advmenu_shop` advs ON adv.`id_link` = advs.`id_link` AND id_shop = '. (int)$context->shop->id;
}
$query .= '
WHERE `id_parent` = ' . (int)$id_parent . '
ORDER BY `position` ASC
';
$links = Db::getInstance()->executeS($query);
return $links;
}
public static function getLinksTree(&$links, $id_parent, $id_lang, $id_link_to_exclude=-1, $level=-1)
{
$level++;
$sql = '
SELECT adv.`id_link`, `title`, `id_parent`
FROM `'._DB_PREFIX_.'advmenu` adv
JOIN `'._DB_PREFIX_.'advmenu_lang` advl ON adv.`id_link` = advl.`id_link` AND id_lang = '. (int)($id_lang) . '
WHERE `id_parent` = ' . (int)$id_parent;
if ($id_link_to_exclude!=-1) {
$sql .= ' AND adv.`id_link` <> '.(int)$id_link_to_exclude;
}
$sql .= ' ORDER BY `position` ASC';
$rows = Db::getInstance()->executeS($sql);
foreach($rows as &$row) {
$row['level'] = $level;
$links[] = $row;
if ($row['id_link']!=$id_link_to_exclude) {
self::getLinksTree($links, $row['id_link'], $id_lang, $id_link_to_exclude, $level);
}
}
}
public function cleanPositions()
{
return Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'advmenu`
SET `position`= `position` - 1
WHERE `id_link` = '.(int)$this->id_link.'
AND `position` > '.(int)$this->position);
}
public function updatePosition($way, $position)
{
$sql = 'SELECT `position`, `id_link`
FROM `'._DB_PREFIX_.'advmenu`
WHERE `id_parent` = '.(int)$this->id_parent.'
ORDER BY `position` ASC';
if (!$res = Db::getInstance()->executeS($sql))
return false;
foreach ($res as $row)
if ((int)$row['id_link'] == (int)$this->id_link)
$moved_row = $row;
if (!isset($moved_row) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
$res = Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advmenu`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `id_parent` = '.(int)$this->id_parent.'
AND `position`
'.($way
? '> '.(int)$moved_row['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_row['position'].' AND `position` >= '.(int)$position)
)
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advmenu`
SET `position` = '.(int)$position.'
WHERE `id_link`='.(int)$moved_row['id_link']
);
$this->refreshPositions();
Hook::exec('actionSaveMenu');
return $res;
}
public function refreshPositions($id_parent=-1)
{
$sql = 'SELECT `id_link`
FROM `'._DB_PREFIX_.'advmenu`
WHERE `id_parent` = '.($id_parent>-1 ? $id_parent : (int)$this->id_parent).'
ORDER BY `position` ASC';
if (!$blocks = Db::getInstance()->executeS($sql))
return false;
$pos=0;
foreach ($blocks as $block) {
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advmenu`
SET `position` = '.(int)$pos.'
WHERE `id_link`='.(int)$block['id_link']);
$pos++;
}
}
public function getHigherPosition($id_parent)
{
$sql = 'SELECT MAX(`position`)
FROM `'._DB_PREFIX_.'advmenu`
WHERE `id_parent` = '.(int)$id_parent;
$position = DB::getInstance()->getValue($sql);
return (is_numeric($position)) ? $position : -1;
}
public static function refreshPositionsAll()
{
$obj = new AdvMenuLink(null);
$sql = 'SELECT DISTINCT id_parent FROM `'._DB_PREFIX_.'advmenu`';
$rows = Db::getInstance()->executeS($sql);
foreach ($rows as $row) {
$obj->refreshPositions($row['id_parent']);
}
}
}

View File

@ -0,0 +1,298 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvMenuLink.php';
class AdminAdvMenuController extends ModuleAdminController {
private $current_link;
public function __construct() {
$this->table = 'advmenu';
$this->className = 'AdvMenuLink';
$this->identifier = 'id_link';
$this->lang = TRUE;
$this->deleted = FALSE;
$this->bootstrap = TRUE;
$this->position_identifier = 'id_link';
$this->_defaultOrderBy = 'position';
parent::__construct();
$this->actions = array('view', 'edit', 'delete');
$this->fields_list = array(
'id_link' => array(
'title' => 'ID',
'width' => 25
),
'title' => array(
'title' => $this->module->l('Titre'),
'width' => 45,
),
'url' => array(
'title' => $this->module->l('Url'),
'width' => 45,
),
'position' => array(
'title' => $this->l('Position'),
'align' => 'center',
'position' => 'position',
'filter_key' => 'a!position'
)
);
if (isset($_GET['deleteadvmenu'])) {
$this->current_link = new AdvMenuLink(
(int)(
Tools::getValue('id_link_parent', 0)
)
);
} else {
$this->current_link = new AdvMenuLink(
(int)(
Tools::getValue('id_link',
Tools::getValue('id_link_parent', 0))
)
);
}
$this->_where = ' AND a.`id_parent` =' . (int)$this->current_link->id;
if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_ALL){
$this->_join .= 'JOIN `'._DB_PREFIX_.'advmenu_shop` as ashop ON a.`id_link` = ashop.`id_link` AND ashop.`id_shop` IN ('.implode(', ', Shop::getContextListShopID()).') ';
$this->_group .= 'GROUP BY ashop.`id_link`';
}
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if ($this->display != 'edit' && $this->display != 'add') {
$this->page_header_toolbar_btn['new_link'] = array(
'href' => self::$currentIndex.'&id_parent='.$this->current_link->id.'&addadvmenu&token='.$this->token,
'desc' => $this->l('Ajouter un nouveau lien', NULL, NULL, FALSE),
'icon' => 'process-icon-new'
);
}
}
public function renderList()
{
$menu_links = '<li><a href="'.self::$currentIndex.'&token='.$this->token.'"><i class="icon-home"></i></a></li>';
$links = AdvMenuLink::getPath($this->current_link->id, Context::getContext()->cookie->id_lang);
foreach($links as $link) {
$menu_links .= '<li><a href="'.self::$currentIndex.'&id_link='.$link['id_link'].'&viewadvmenu&token='.$this->token.'">'.$link['title'].'</a></li>';
}
$this->context->smarty->assign('menu_links', $menu_links);
self::$currentIndex .= "&id_link_parent=".$this->current_link->id;
return parent::renderList();
}
public function initContent()
{
if ($this->display == 'view') {
$this->display = 'list';
}
parent::initContent();
}
public function renderForm()
{
$dbLinks = array();
$id = Tools::getValue('id_link');
AdvMenuLink::getLinksTree($dbLinks, 0, Context::getContext()->cookie->id_lang, $id?$id:-1);
$links[] = array(
'id'=>'0',
'name' => $this->l('Aucun parent')
);
foreach ($dbLinks as $link) {
$links[] = array(
"id" => $link['id_link'],
"name" => str_repeat('--', $link['level']) . ' ' . $link['title']
);
}
$selected_categories = !empty($this->object->id) ? array($this->object->id_category) : array();
$this->fields_form = array(
'tinymce' => TRUE,
'legend' => array(
'title' => $this->className,
),
'submit' => array(
'name' => 'submitAdvMenu',
'title' => $this->l('Save'),
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_link_parent'
),
array(
'type' => 'select',
'label' => $this->l('Lien parent'),
'name' => 'id_parent',
'required' => FALSE,
'options' => array(
'query' => $links,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'text',
'label' => $this->l('Nom'),
'name' => 'title',
'required' => TRUE,
'lang' => TRUE,
'size' => 114
),
array(
'type' => 'text',
'label' => $this->l('Lien'),
'name' => 'url',
'lang' => TRUE,
'required' => FALSE,
'size' => 114
),
array(
'type' => 'switch',
'label' => $this->l('External link'),
'name' => 'external',
'is_bool' => true,
'required' => false,
'values' => array(
array('id' => 'expo_on', 'value' => 1, 'label' => $this->l('Yes')),
array('id' => 'expo_off', 'value' => 0, 'label' => $this->l('No'))
)
),
array(
'type' => 'textarea',
'label' => $this->l('Call to action'),
'name' => 'cta',
'autoload_rte' => TRUE,
'cols' => 100,
'rows' => 6,
'lang' => TRUE,
),
array(
'type' => 'select',
'label' => $this->l('Type d\'affichage'),
'name' => 'classbloc',
'required' => FALSE,
'options' => array(
'query' => array(
array('id' => '', 'name' => 'Aucune'),
array('id' => 'arrow', 'name' => 'Flèche'),
array('id' => 'menu-subtitle', 'name' => 'Titre'),
),
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'categories',
'label' => $this->l('Catégorie associée'),
'name' => 'id_category',
'tree' => array(
'id' => 'categories-tree',
'selected_categories' => $selected_categories,
'use_checkbox' => false,
'root_category' => $this->context->shop->getCategory()
),
'col' => '9'
),
array(
'type' => 'shop',
'label' => $this->l('Shop'),
'form_group_class' => 'fieldhide input_association',
'name' => 'checkBoxShopAsso_advmenu'
)
)
);
$this->fields_value = array(
'id_link_parent' => (int)Tools::getValue('id_link_parent')
);
self::$currentIndex .= '&id_link_parent='.Tools::getValue('id_parent', Tools::getValue('id_link_parent'));
return parent::renderForm();
}
public function processAdd()
{
$result = parent::processAdd();
$this->redirect_after = self::$currentIndex.'&conf=3&token='.$this->token.'&id_link='.Tools::getValue('id_parent');
return $result;
}
public function processUpdate()
{
$result = parent::processUpdate();
$this->redirect_after = self::$currentIndex.'&conf=4&token='.$this->token.'&id_link='.Tools::getValue('id_link_parent');
return $result;
}
public function processDelete()
{
// "current link" is already parent in this particular case (see constructor)
$id_parent = $this->current_link->id;
$object = parent::processDelete();
if ($object->hasError()) {
$this->errors = [Tools::displayError($this->l('This link can\'t be deleted : it contains at least one sub link.'))];
}
else {
$this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token.'&id_link='.$id_parent;
}
return $object;
}
protected function copyFromPost(&$object, $table)
{
parent::copyFromPost($object, $table);
if(Shop::isFeatureActive()) {
$object->id_shop_list = array();
foreach (Tools::getValue('checkBoxShopAsso_advmenu') as $id_shop => $value)
$object->id_shop_list[] = $id_shop;
}
}
public function ajaxProcessUpdatePositions()
{
$way = (int)(Tools::getValue('way'));
$id = (int)(Tools::getValue('id'));
$positions = Tools::getValue('link');
$obj = 'advmenu';
if (is_array($positions)) {
foreach ($positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id) {
$menu_obj = new AdvMenuLink((int)$pos[2]);
if (Validate::isLoadedObject($menu_obj)) {
if (isset($position) && $menu_obj->updatePosition($way, $position)) {
echo 'ok position '.(int)$position.' for '.$obj.' '.(int)$pos[2]."\r\n";
} else {
echo '{"hasError" : true, "errors" : "Can not update '.$obj.' '.(int)$id.' to position '.(int)$position.' "}';
}
} else {
echo '{"hasError" : true, "errors" : "This '.$obj.' ('.(int)$id.') cannot be loaded"}';
}
break;
}
}
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

View File

@ -0,0 +1,43 @@
{*
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{if isset($menu_links)}
<ul class="breadcrumb cat_bar">
{$menu_links}
</ul>
{/if}
{*
{if isset($url_prev)}
<script type="text/javascript">
$(document).ready(function () {
var re = /url_preview=(.*)/;
var url = re.exec(window.location.href);
if (typeof url !== 'undefined' && url !== null && typeof url[1] !== 'undefined' && url[1] === "1")
window.open("{$url_prev}", "_blank");
});
</script>
{/if}
*}
{$content}

View File

@ -0,0 +1,3 @@
<!-- Block Advmenu module -->
<!-- /Block Advmenu module -->

View File

@ -0,0 +1 @@
#TODO:

View File

@ -0,0 +1,183 @@
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
include_once dirname(__FILE__).'/classes/AdvPictoClass.php';
class AdvPicto extends Module
{
public function __construct()
{
$this->name = 'advpicto';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Antadis';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Gestionnaire de pictos');
$this->description = $this->l('Gérez vos pictos');
}
public function install()
{
return parent::install() && $this->registerHook('displayPictogrammesCategory') && $this->registerHook('displayPictogrammesProduct') && $this->createFolder() && $this->installDb() && $this->createTab();
}
public function uninstall()
{
if ( !parent::uninstall() ) {
return false;
}
$this->uninstallDb();
$this->deleteTab();
return true;
}
public function installDb()
{
$sql = array();
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto` (
`id_advpicto` int(10) unsigned NOT NULL auto_increment,
`active` int(11),
`external` int(10) unsigned NOT NULL,
`selfcategory_display` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advpicto`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto_lang` (
`id_advpicto` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`alt` varchar(255) NOT NULL,
`link` varchar(255),
`content` text,
PRIMARY KEY (`id_advpicto`,`id_lang`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto_shop` (
`id_advpicto` int(10) unsigned NOT NULL,
`id_shop` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advpicto`,`id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto_category` (
`id_advpicto` int(10) unsigned NOT NULL,
`id_category` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advpicto`,`id_category`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto_product` (
`id_advpicto_product` int(11) NOT NULL AUTO_INCREMENT,
`id_advpicto` int(10) unsigned NOT NULL,
`id_product` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_advpicto`,`id_product`),
UNIQUE KEY `id_advpicto_product` (`id_advpicto_product`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advpicto_product_shop` (
`id_advpicto_product` int(11) NOT NULL,
`id_shop` int(11) NOT NULL,
PRIMARY KEY (`id_advpicto_product`,`id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
return $this->uninstallDb() && $this->updateDb($sql);
}
public function uninstallDb()
{
$sql = array();
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto_lang` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto_shop` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto_category` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto_product` ;';
$sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'advpicto_product_shop` ;';
return $this->updateDb($sql);
}
public function updateDb( $sqls )
{
foreach ( $sqls as $sql ) {
if ( !Db::getInstance()->execute($sql) ) {
return false;
}
}
return true;
}
public function createFolder()
{
$img_dir = _PS_IMG_DIR_ . 'picto';
$folder = is_dir($img_dir);
if (!$folder)
{
$folder = mkdir($img_dir, 0755, true);
}
return $folder;
}
public function createTab()
{
$languages = Language::getLanguages();
$new_tab = new Tab();
$new_tab->class_name = 'AdminAdvPicto';
$new_tab->id_parent = Tab::getCurrentParentId();
$new_tab->module = $this->name;
foreach ( $languages as $language ) {
$new_tab->name[$language['id_lang']] = 'Pictos';
}
$new_tab->add();
$under_tab = new Tab();
$under_tab->class_name = 'AdminAdvPictoProduct';
$under_tab->id_parent = $new_tab->id;
$under_tab->module = $this->name;
foreach ( $languages as $language ) {
$under_tab->name[$language['id_lang']] = 'Pictos';
}
$under_tab->add();
return true;
}
public function deleteTab()
{
$idTab = Tab::getIdFromClassName('AdminAdvPicto');
if ( $idTab ) {
$tab = new Tab($idTab);
$tab->delete();
}
}
public function hookDisplayPictogrammesProduct($params)
{
$id_product = $params['id_product'];
$id_category = Tools::getValue('id_category', null);
$is_listing = isset($params['is_listing']) && $params['is_listing'];
$tpl = $is_listing ? 'product-list' : 'product';
$pictos_category = AdvPictoClass::getPictosForCategory($id_product, $id_category);
$pictos_product = AdvPictoClass::getPictosForProduct($id_product);
$pictos = array_merge($pictos_category, $pictos_product);
foreach($pictos as $key => $picto) {
$pictos[$key]['hasImg'] = file_exists(_PS_IMG_DIR_ .'picto/'. $picto['id_advpicto'] . '.jpg');
}
$this->smarty->assign('pictos', $pictos);
return $this->display(__FILE__, $tpl.'.tpl');
}
}

View File

@ -0,0 +1,212 @@
<?php
class AdvPictoClass extends ObjectModel
{
public $id_advpicto;
public $title;
public $alt;
public $link;
public $external;
public $selfcategory_display;
public $content;
public $active = true;
public $categories;
public static $definition = array(
'table' => 'advpicto',
'primary' => 'id_advpicto',
'multilang' => true,
'fields' => array(
'title' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString',
'required' => TRUE
),
'alt' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString'
),
'content' => array(
'type' => ObjectModel :: TYPE_HTML,
'lang' => true,
'validate' => 'isString'
),
'link' => array(
'type' => ObjectModel :: TYPE_STRING,
'lang' => true,
'validate' => 'isString'
),
'external' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isBool'
),
'selfcategory_display' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isBool'
),
'active' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isBool'
)
)
);
public function __construct($id = NULL, $id_lang = NULL, $id_shop = NULL) {
parent::__construct($id, $id_lang, $id_shop);
$this->image_dir = _PS_IMG_DIR_ . 'picto/';
}
public static function getAllPictos()
{
$query = '
SELECT adv.`id_advpicto` as id, advpl.`title`
FROM `' . _DB_PREFIX_ . 'advpicto` adv
LEFT JOIN `' . _DB_PREFIX_ . 'advpicto_lang` advpl ON adv.`id_advpicto` = advpl.`id_advpicto` AND advpl.`id_lang` = ' . Context::getContext()->language->id . '
';
if(Shop::isFeatureActive())
{
$query .= ' INNER JOIN `'._DB_PREFIX_.'advpicto_shop` advs ON adv.`id_advpicto` = advs.`id_advpicto` AND id_shop = '. Context::getContext()->shop->id;
}
return Db::getInstance()->executeS($query);
}
public function getCategories()
{
if(!$this->id)
{
return array();
}
if (!isset($this->categories)) {
$this->categories = array();
foreach (Db::getInstance()->executeS('
SELECT `id_category`
FROM `' . _DB_PREFIX_ . 'advpicto_category`
WHERE `id_advpicto` = ' . $this->id . '
') as $category) {
$this->categories[] = $category['id_category'];
}
}
return $this->categories;
}
public function addCategoryAssociation( $categories )
{
if(!empty($categories)) {
Db::getInstance()->execute('
DELETE FROM `'._DB_PREFIX_.'advpicto_category`
WHERE `id_advpicto` = '.(int) $this->id.'
');
if ($categories)
{
foreach ( $categories as $category )
{
Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'advpicto_category`
(`id_advpicto`,`id_category`)
VALUES ('.(int) $this->id.','.$category.')
');
}
}
}
}
public static function getPictoName($id_picto, $id_lang)
{
return Db::getInstance()->getValue('
SELECT `title`
FROM `' . _DB_PREFIX_ . 'advpicto_lang`
WHERE `id_advpicto` = ' . $id_picto . '
AND id_lang = ' . $id_lang . '
');
}
public static function getPictosForCategory($id_product, $current_category = null)
{
$context = Context::getContext();
$categories = Product::getProductCategories($id_product);
if(!empty($categories)) {
$query = '
SELECT *
FROM `'._DB_PREFIX_.'advpicto` adv
INNER JOIN `'._DB_PREFIX_.'advpicto_lang` advl ON adv.`id_advpicto` = advl.`id_advpicto` AND id_lang = '. $context->language->id
;
if(Shop::isFeatureActive()) {
$query .= ' INNER JOIN `'._DB_PREFIX_.'advpicto_shop` advs ON adv.`id_advpicto` = advs.`id_advpicto` AND id_shop = '. $context->shop->id;
}
$query .= '
INNER JOIN `'._DB_PREFIX_.'advpicto_category` advc ON adv.`id_advpicto` = advc.`id_advpicto` AND advc.`id_category` IN ('. implode(',', $categories) . ')
WHERE adv.`active` = 1
GROUP BY adv.`id_advpicto`
ORDER BY adv.`id_advpicto` ASC
';
$pictos = Db::getInstance()->executeS($query);
if (empty($pictos)) {
return array();
}
if ($current_category) {
foreach($pictos as $key => $picto) {
if(!$picto['selfcategory_display']) {
$pictoCategories = Db::getInstance()->executeS('
SELECT `id_category`
FROM `' . _DB_PREFIX_ . 'advpicto_category`
WHERE `id_advpicto` = ' . $picto['id_advpicto']
);
$pictoCategories = array_map(function($elem) { return $elem['id_category']; }, $pictoCategories);
if(in_array($current_category, $pictoCategories)) {
unset($pictos[$key]);
}
}
}
}
return $pictos;
}
}
public static function getPictosForProduct($id_product = null)
{
$context = Context::getContext();
if(!empty($id_product) ) {
$query = '
SELECT DISTINCT(advp.`id_advpicto`), `title`
FROM `'._DB_PREFIX_.'advpicto_product` advp
INNER JOIN `'._DB_PREFIX_.'advpicto_lang` advl ON advp.`id_advpicto` = advl.`id_advpicto` AND id_lang = '. $context->language->id
;
if(Shop::isFeatureActive())
{
$query .= ' INNER JOIN `'._DB_PREFIX_.'advpicto_shop` advs ON advp.`id_advpicto` = advs.`id_advpicto` AND id_shop = '. $context->shop->id;
}
$query .= ' AND advp.id_product = '. (int) $id_product;
$pictos = Db::getInstance()->executeS($query);
if (empty($pictos)) {
return array();
}
return $pictos;
}
}
}

View File

@ -0,0 +1,49 @@
<?php
class AdvPictoProductClass extends ObjectModel
{
public $id_advpicto_product;
public $id_advpicto;
public $id_product;
public static $definition = array(
'table' => 'advpicto_product',
'primary' => 'id_advpicto_product',
'multilang' => false,
'fields' => array(
'id_advpicto' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isInt'
),
'id_product' => array(
'type' => ObjectModel :: TYPE_INT,
'validate' => 'isInt'
)
)
);
public function __construct($id = NULL, $id_lang = NULL, $id_shop = NULL) {
parent::__construct($id, $id_lang, $id_shop);
$this->image_dir = _PS_IMG_DIR_ . 'picto/';
}
public function add($auto_date = true, $null_values = false) {
if(AdvPictoProductClass::exist($this->id_product, $this->id_advpicto, $this->id)) {
throw new PrestaShopException('Existe déjà');
}
return parent::add($auto_date, $null_values);
}
public function update($null_values = false) {
if(AdvPictoProductClass::exist($this->id_product, $this->id_advpicto, $this->id)) {
throw new PrestaShopException('Existe déjà');
}
return parent::update($null_values);
}
public static function exist($id_product, $id_advpicto, $id_advpicto_product = null)
{
return Db::getInstance()->getValue('SELECT id_advpicto_product FROM '._DB_PREFIX_.'advpicto_product WHERE id_product = '.(int)$id_product.' AND id_advpicto = '.(int)$id_advpicto.(!is_null($id_advpicto_product) ? ' AND id_advpicto_product != '.(int)$id_advpicto_product : ''));
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,348 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvPictoClass.php';
class AdminAdvPictoController extends ModuleAdminController
{
public function __construct()
{
$this->table = 'advpicto';
$this->className = 'AdvPictoClass';
$this->identifier = 'id_advpicto';
$this->lang = true;
$this->deleted = false;
$this->bootstrap = true;
$this->explicitSelect = true;
$this->context = Context::getContext();
$this->_defaultOrderBy = 'id_advpicto';
$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'picto'
);
$this->_group = 'GROUP BY a.`id_advpicto`';
parent::__construct();
$this->fields_list = array(
'id_advpicto' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 25,
'filter_key' => 'a!id_advpicto'
),
'title' => array(
'title' => $this->l('Nom')
),
'active' => array(
'title' => $this->l('Activé'),
'active' => 'status',
'filter_key' => 'a!active',
'align' => 'text-center',
'type' => 'bool',
'class' => 'fixed-width-sm',
'orderby' => false
),
);
$this->actions = array('edit','delete');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Supprimer la liste'),
'icon' => 'icon-trash',
'confirm' => $this->l('Supprimer les blocs selectionné?')
)
);
$this->specificConfirmDelete = false;
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if ($this->display == 'edit' || $this->display == 'add') {
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => self::$currentIndex.'&token='.$this->token,
'desc' => $this->l('Retour à la liste', null, null, false),
'icon' => 'process-icon-back'
);
}
$this->page_header_toolbar_btn['new'] = array(
'href' => self::$currentIndex.'&addadvpicto&token='.$this->token,
'desc' => $this->l('Ajouter un nouveau picto', null, null, false),
'icon' => 'process-icon-new'
);
$this->page_header_toolbar_btn['new_product'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvPictoProduct'),
'desc' => $this->l('Association produit', null, null, false),
'icon' => 'process-icon-compress'
);
}
public function renderForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$context = Context::getContext();
if ( Tools::isSubmit('id_advpicto') ) {
$id_advpicto = (int)Tools::getValue('id_advpicto');
$image = __PS_BASE_URI__.'img/picto/'.$id_advpicto.'.jpg' ;
} else {
$image = "noimg" ;
}
$selected_categories = $obj->getCategories();
$image = _PS_IMG_DIR_ . 'picto/' . $obj->id.'.jpg';
$image_url = ImageManager::thumbnail($image, $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, TRUE, TRUE);
$image_size = file_exists($image) ? filesize($image) / 1000 : FALSE;
$this->fields_form = array(
'multilang' => true,
'tinymce' => true,
'legend' => array(
'title' => $this->l('Picto'),
),
'submit' => array(
'name' => 'submitBlock',
'title' => $this->l('Enregistrer')
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Titre'),
'name' => 'title',
'lang' => true,
'required' => true,
'size' => 255
),
array(
'type' => 'text',
'label' => $this->l('Alt'),
'name' => 'alt',
'lang' => true,
'size' => 255
),
array(
'type' => 'file',
'label' => $this->l('Choisir une image'),
'name' => 'image',
'display_image' => TRUE,
'image' => $image_url,
'size' => $image_size,
'delete_url' => self::$currentIndex.'&'.$this->identifier.'='.$this->object->id.'&token='.$this->token.'&deleteImage=1'
),
array(
'type' => 'text',
'label' => $this->l('Lien'),
'name' => 'link',
'lang' => true,
'size' => 255
),
array(
'type' => 'switch',
'label' => $this->l('Lien externe'),
'name' => 'external',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'external_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'external_off',
'value' => 0,
'label' => $this->l('No')
)
)
),
array(
'type' => 'textarea',
'label' => $this->l('Contenu'),
'name' => 'content',
'autoload_rte' => true,
'lang' => true,
'cols' => 60,
'rows' => 120
),
array(
'type' => 'categories',
'label' => $this->l('Parent category'),
'name' => 'categoryBox',
'tree' => array(
'id' => 'categories-tree',
'selected_categories' => $selected_categories,
'use_checkbox' => true,
'root_category' => $context->shop->getCategory()
),
'col' => '9',
),
array(
'type' => 'switch',
'label' => $this->l('Actif'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1
),
array(
'id' => 'active_off',
'value' => 0
)
),
),
array(
'type' => 'switch',
'label' => $this->l('Affiché dans sa propre catégorie'),
'name' => 'selfcategory_display',
'required' => false,
'class' => 't',
'is_bool' => true,
'hint' => $this->l('Permet de ne pas affiché le pictogramme dans sa propre catégorie (mais dans les autres catégories associées à un produit par exemple)'),
'values' => array(
array(
'id' => 'selfcategory_display_on',
'value' => 1
),
array(
'id' => 'selfcategory_display_off',
'value' => 0
)
),
)
)
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->l('Boutique'),
'name' => 'checkBoxShopAsso',
'form_group_class' => 'fieldhide input_association'
);
}
return parent::renderForm();
}
public function init()
{
parent::init();
if (Shop::getContext() == Shop::CONTEXT_SHOP) {
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_. $this->table .'_shop` sa ON (a.`' . $this->identifier . '` = sa.`' . $this->identifier . '` AND sa.id_shop = '.(int)$this->context->shop->id.') ';
}
if (Shop::getContext() == Shop::CONTEXT_SHOP && Shop::isFeatureActive()) {
$this->_where = ' AND sa.`id_shop` = '.(int)Context::getContext()->shop->id;
}
}
public function postProcess()
{
if (Tools::getValue('deleteImage')) {
$this->processForceDeleteImage();
}
$result = parent::postProcess();
if ( Validate::isLoadedObject($result) ) {
$this->generatePicture($result);
$result->addCategoryAssociation(Tools::getValue('categoryBox'));
}
return $result;
}
public function processForceDeleteImage()
{
$picto = $this->loadObject(TRUE);
if (Validate::isLoadedObject($picto))
{
$picto->deleteImage(TRUE);
}
}
public function generatePicture($object)
{
$namePost = 'image';
if (isset($_FILES[$namePost]) && !empty($_FILES[$namePost]['tmp_name']) ) {
$fileTemp = $_FILES[$namePost]['tmp_name'];
$fileParts = pathinfo($_FILES[$namePost]['name']);
if ( $fileParts['extension'] == 'jpg' || $fileParts['extension'] == 'png' ) {
if(!is_dir(_PS_IMG_DIR_.'picto')) {
mkdir(_PS_IMG_DIR_.'picto', 0775);
}
$res = move_uploaded_file($fileTemp, _PS_IMG_DIR_.'picto/' . $object->id . '.jpg');
if(!$res)
$this->errors[] = sprintf(Tools::displayError('An error occured during upload of file %s'), $object->id . '.jpg');
else
$this->confirmations[] = sprintf($this->l('File %s has been uploaded'), $object->id . '.jpg');
} else
$this->errors[] = sprintf(Tools::displayError('File %s have not good extension, only .jpg or .png'), $object->id . '.jpg');
}
}
protected function updateAssoShop($id_object)
{
if (!Shop::isFeatureActive()) {
return;
}
$assos_data = $this->getSelectedAssoShop($this->table, $id_object);
$exclude_ids = $assos_data;
foreach (Db::getInstance()->executeS('SELECT id_shop FROM ' . _DB_PREFIX_ . 'shop') as $row) {
if (!$this->context->employee->hasAuthOnShop($row['id_shop'])) {
$exclude_ids[] = $row['id_shop'];
}
}
Db::getInstance()->delete($this->table . '_shop', '`' . $this->identifier . '` = ' . (int) $id_object . ($exclude_ids ? ' AND id_shop NOT IN (' . implode(', ', $exclude_ids) . ')' : ''));
$insert = array();
foreach ($assos_data as $id_shop) {
$insert[] = array(
$this->identifier => $id_object,
'id_shop' => (int) $id_shop,
);
}
return Db::getInstance()->insert($this->table . '_shop', $insert, FALSE, TRUE, Db::INSERT_IGNORE);
}
protected function getSelectedAssoShop($table)
{
if (!Shop::isFeatureActive()) {
return array();
}
$shops = Shop::getShops(TRUE, NULL, TRUE);
if (count($shops) == 1 && isset($shops[0])) {
return array($shops[0], 'shop');
}
$assos = array();
if (Tools::isSubmit('checkBoxShopAsso_' . $table)) {
foreach (Tools::getValue('checkBoxShopAsso_' . $table) as $id_shop => $value) {
$assos[] = (int) $id_shop;
}
} else if (Shop::getTotalShops(FALSE) == 1) {
// if we do not have the checkBox multishop, we can have an admin with only one shop and being in multishop
$assos[] = (int) Shop::getContextShopID();
}
return $assos;
}
}

View File

@ -0,0 +1,174 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvPictoClass.php';
include_once dirname(__FILE__).'/../../classes/AdvPictoProductClass.php';
class AdminAdvPictoProductController extends ModuleAdminController
{
public function __construct()
{
$this->table = 'advpicto_product';
$this->className = 'AdvPictoProductClass';
$this->identifier = 'id_advpicto_product';
$this->lang = false;
$this->deleted = false;
$this->bootstrap = true;
$this->explicitSelect = true;
$this->context = Context::getContext();
$this->_defaultOrderBy = 'id_advpicto';
$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'picto'
);
parent::__construct();
$this->fields_list = array(
'id_advpicto_product' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 25,
'filter_key' => 'a!id_advpicto_product'
),
'id_advpicto' => array(
'title' => $this->l('Picto'),
'filter_key' => 'a!id_advpicto',
'callback' => 'getPictoName'
),
'id_product' => array(
'title' => $this->l('Produit'),
'filter_key' => 'a!id_product',
'callback' => 'getProductName',
),
);
$this->actions = array('edit','delete');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Supprimer la liste'),
'icon' => 'icon-trash',
'confirm' => $this->l('Supprimer les blocs selectionné?')
)
);
$this->specificConfirmDelete = false;
}
public function init()
{
parent::init();
if(Tools::getValue('loadProductName') == 1)
{
$this->loadProductData();
}
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvPicto'),
'desc' => $this->l('Liste des pictogrammes', null, null, false),
'icon' => 'process-icon-back'
);
if ($this->display == 'edit' || $this->display == 'add') {
$this->page_header_toolbar_btn['new_product'] = array(
'href' => $this->context->link->getAdminLink('AdminAdvPictoProduct'),
'desc' => $this->l('Liste des associations', null, null, false),
'icon' => 'process-icon-back'
);
}
if ($this->display != 'edit' && $this->display != 'add') {
$this->page_header_toolbar_btn['new_constructor'] = array(
'href' => self::$currentIndex.'&addadvpicto_product&token='.$this->token,
'desc' => $this->l('Ajouter une association produit', null, null, false),
'icon' => 'process-icon-new'
);
}
}
public static function getProductName($id_product, $obj) {
return Product::getProductName($id_product, null, Context::getContext()->language->id);
}
public static function getPictoName($id_advpicto) {
return AdvPictoClass::getPictoName($id_advpicto, Context::getContext()->language->id);
}
public function loadProductData()
{
$id_product = Tools::getValue('id_product');
$identifier = Tools::getValue('identifier');
$data['identifier'] = $identifier;
$data['nameProduct'] = self::getProductName($id_product, null, Context::getContext()->language->id);
die(Tools::jsonEncode($data));
}
public function renderForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$this->addJqueryUI(array('ui.core','ui.widget'));
$this->addJqueryPlugin(array('autocomplete'));
$context = Context::getContext();
$pictos = AdvPictoClass::getAllPictos();
$this->tpl_form_vars['product_id'] = $this->object->id_product;
$this->fields_form = array(
'multilang' => true,
'tinymce' => true,
'legend' => array(
'title' => $this->l('Picto'),
),
'submit' => array(
'name' => 'submitAdd'.$this->table,
'title' => $this->l('Enregistrer')
),
'input' => array(
array(
'type' => 'select',
'label' => $this->l('Pictogramme'),
'name' => 'id_advpicto',
'options' => array(
'query' => $pictos,
'id' => 'id',
'name' => 'title'
),
'required' => true,
),
array(
'type' => 'product',
'label' => $this->l('Produit'),
'name' => 'id_product',
'id' => 'id_product',
'required' => true
)
)
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->l('Boutique'),
'name' => 'checkBoxShopAsso',
'form_group_class' => 'fieldhide input_association'
);
}
return parent::renderForm();
}
public function beforeAdd($object)
{
parent::beforeAdd($object);
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,75 @@
{extends file="helpers/form/form.tpl"}
{block name="field"}
{if $input.type == 'product' }
<div class="col-lg-4">
<input type="hidden" id="id_product" name="id_product" value="{$product_id}" />
<input type="text" size="10" id="id_product_name" name="id_product_name" class="ac_input" autocomplete="off" />
</div>
{/if}
{$smarty.block.parent}
{/block}
{block name="defaultForm"}
<script>
var Choice = function () {
var self = this;
this.init = function() {
this.loadData();
this.initAutocompleteChoice();
}
};
Choice.prototype.loadData = function() {
if($('#id_product').val()) {
var idProduct = $('#id_product').val();
$.ajax({
type: "POST",
url: "{Context::getContext()->link->getAdminLink(AdminAdvPictoProduct)}",
data: 'loadProductName=1&id_product='+idProduct+'&identifier='+idProduct,
dataType: 'json',
success: function (jsonData) {
$('#id_product_name').val(jsonData.nameProduct);
}
});
}
}
Choice.prototype.initAutocompleteChoice = function() {
$('#id_product_name').autocomplete('ajax_products_list.php', {
minChars: 1,
autoFill: false,
max:20,
matchContains: true,
mustMatch:false,
scroll:false,
cacheLength:0,
formatItem: function(item) {
return item[0];
},
}).result( function(event, data, formatted) {
var idProduct = data[1];
var nameProduct = data[0];
$('#id_product').val(idProduct);
$('#id_product_name').val(nameProduct);
});
$('#id_product_name').setOptions({
extraParams: {
excludeIds : ',',
}
});
}
$(document).ready(function() {
var choice = new Choice();
choice.init();
});
</script>
{$smarty.block.parent}
{/block}

View File

@ -0,0 +1,43 @@
{extends file="helpers/form/form.tpl"}
{block name="field"}
{if $input.type == 'product' }
{if $input.type == 'product'}
{assign var="input_action" value="getProducts"}
{/if}
<div class="col-lg-9">
{if !isset($input.id)}
Nécéssite l'identifiant
{/if}
<div class="result" id="content-selected-{$input.id}">
{foreach $input.query as $line}
<input type="hidden" name="input-{$input.id}[]" value="{$line.id}">
<li class="class-{$input.id} input-search-result-selected" data-id="{$line.id}"><button class="removeItem btn btn-default" type="button"><i class="icon-remove"></i></button><span class="content">{$line.content}</span></li>
{/foreach}
</div>
<div class="input-group">
<input type="text"
name="searchAssoc[{$input.id}]"
id="{if isset($input.id)}{$input.id}{/if}"
data-action="{$input_action}"
value=""
size="{if isset($input.size)}{$input.size}{/if}"
class="{if isset($input.class)}{$input.class}{/if} input-search-js"
autocomplete="off" >
<span class="input-group-addon"><i class="icon-search"></i></span>
</div>
<div class="searchResult" id="content-result-list-{$input.id}"></div>
</div>
{/if}
{$smarty.block.parent}
{/block}
{block name="defaultForm"}
<script type="text/javascript">
searchUrl = "{$link->getAdminLink('AdminSearch', true)}";
</script>
{$smarty.block.parent}
{/block}

View File

@ -0,0 +1,17 @@
{if $pictos}
{foreach from=$pictos item=picto name=picto}
<li class="picto valign-middle">
{if $picto.hasImg}
<img src="{$base_dir_ssl}img/picto/{$picto.id_advpicto}.jpg" alt="{$picto.title}" />
{/if}
<div class="picto-title">
<div class="picto-text">
{$picto.title}
</div>
<div class="picto-title-left">
</div>
<div class="picto-title-right"></div>
</div>
</li>
{/foreach}
{/if}

View File

@ -0,0 +1,19 @@
{if $pictos}
<ul class="pictos clearfix">
{foreach from=$pictos item=picto name=picto}
<li class="picto valign-middle">
{if $picto.hasImg}
<img src="{$base_dir_ssl}img/picto/{$picto.id_advpicto}.jpg" alt="{$picto.title}" />
{/if}
<div class="picto-title">
<div class="picto-text">
{$picto.title}
</div>
<div class="picto-title-left">
</div>
<div class="picto-title-right"></div>
</div>
</li>
{/foreach}
</ul>
{/if}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2015 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@ -0,0 +1,130 @@
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
include_once(dirname(__FILE__) . '/classes/AdvRea.php');
class AdvReassurance extends Module
{
public function __construct()
{
$this->name = 'advreassurance';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Antadis';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Reassurance avancé');
$this->description = $this->l('Gestion des blocks reassurance');
}
public function install()
{
$sql = [];
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advreassurance` (
`id_reassurance` int(10) unsigned NOT NULL auto_increment,
`position` INT(11) UNSIGNED NOT NULL default 0,
`active` INT(11) UNSIGNED NOT NULL default 1,
PRIMARY KEY (`id_reassurance`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advreassurance_lang` (
`id_reassurance` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`subtitle` varchar(255) NOT NULL,
`url` varchar(255),
PRIMARY KEY (`id_reassurance`,`id_lang`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
$sql[] =
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'advreassurance_shop` (
`id_reassurance` int(10) unsigned NOT NULL auto_increment,
`id_shop` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_reassurance`, `id_shop`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
foreach ($sql as $_sql)
{
Db::getInstance()->Execute($_sql);
}
$tab = new Tab();
$tab->class_name = 'AdminAdvReassurance';
$tab->id_parent = Tab::getCurrentParentId();
$tab->module = $this->name;
$languages = Language::getLanguages();
foreach ($languages as $language)
{
$tab->name[$language['id_lang']] = 'Reassurance';
}
$img_dir = _PS_IMG_DIR_ . 'reassurance';
$folder = is_dir($img_dir);
if (!$folder)
{
$folder = mkdir($img_dir, 0755, true);
}
return parent::install() && $tab->add() && $this->registerHook('displayReassurance') && $this->registerHook('actionRefreshReassurance')
&& $folder;
}
public function uninstall()
{
$sql = 'DROP TABLE IF EXISTS
`' . _DB_PREFIX_ . 'advreassurance_lang`,
`' . _DB_PREFIX_ . 'advreassurance_shop`,
`' . _DB_PREFIX_ . 'advreassurance`
';
Db::getInstance()->Execute($sql);
$idTab = Tab::getIdFromClassName('AdminAdvReassurance');
if ($idTab)
{
$tab = new Tab($idTab);
$tab->delete();
}
return parent::uninstall();
}
public function assignBlocks($category)
{
$blocks = AdvRea::getBlocks($category);
if (!$blocks) {
return false;
}
$this->smarty->assign('blocks', $blocks);
}
public function hookDisplayReassurance($params)
{
$category = $params['category'];
$templateName = 'advreassurance-'.$category.'.tpl';
if (!$this->isCached($templateName, $this->getCacheId())) {
$this->assignBlocks($category);
return $this->display(__FILE__, $templateName, $this->getCacheId());
}
}
public function hookActionRefreshReassurance()
{
$this->_clearCache('advreassurance-menu');
$this->_clearCache('advreassurance-footer');
$this->_clearCache('advreassurance-tunnel');
}
}

View File

@ -0,0 +1,144 @@
<?php
class AdvRea extends ObjectModel {
public $id_reassurance;
public $position;
public $active;
public $category;
public $title;
public $subtitle;
public $url;
public static $definition = array(
'table' => 'advreassurance',
'primary' => 'id_reassurance',
'multilang' => TRUE,
'fields' => array(
'id_reassurance' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'position' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'active' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'category' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 255),
// Lang fields
'title' => array('type' => self::TYPE_HTML, 'lang' => TRUE, 'validate' => 'isCleanHtml'),
'subtitle' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isGenericName', 'size' => 255),
'url' => array('type' => self::TYPE_STRING, 'lang' => TRUE, 'validate' => 'isUrl', 'size' => 255)
)
);
public function __construct($id = NULL, $id_lang = NULL, $id_shop = NULL) {
parent::__construct($id, $id_lang, $id_shop);
$this->image_dir = _PS_IMG_DIR_ . 'reassurance/';
}
public function add($null_values = false, $autodate = true)
{
$result = parent::add($null_values, $autodate);
Hook::exec('actionRefreshReassurance');
return $result;
}
public function update($null_values = FALSE) {
$result = parent::update($null_values);
Hook::exec('actionRefreshReassurance');
return $result;
}
public function delete($null_values = FALSE) {
$result = parent::delete($null_values);
Hook::exec('actionRefreshReassurance');
return $result;
}
public static function getBlocks($category)
{
$context = Context::getContext();
$query = '
SELECT *
FROM `'._DB_PREFIX_.'advreassurance` adv
JOIN `'._DB_PREFIX_.'advreassurance_lang` advl ON adv.`id_reassurance` = advl.`id_reassurance` AND id_lang = '. (int)$context->language->id;
if (Shop::isFeatureActive()) {
$query .= 'JOIN `'._DB_PREFIX_.'advreassurance_shop` advs ON adv.`id_reassurance` = advs.`id_reassurance` AND id_shop = '. (int)$context->shop->id;
}
$query .= '
WHERE adv.`active` = 1
AND category = \''. $category . '\'
ORDER BY `position` ASC
';
$reassurances = Db::getInstance()->executeS($query);
return $reassurances;
}
public function cleanPositions(){
return Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'advreassurance`
SET `position`= `position` - 1
WHERE `id_reassurance` = '.(int)$this->id_reassurance.'
AND `position` > '.(int)$this->position);
}
public function updatePosition($way, $position)
{
$sql = 'SELECT `position`, `id_reassurance`
FROM `'._DB_PREFIX_.'advreassurance`
ORDER BY `position` ASC';
if (!$res = Db::getInstance()->executeS($sql))
return false;
foreach ($res as $row)
if ((int)$row['id_reassurance'] == (int)$this->id_reassurance)
$moved_row = $row;
if (!isset($moved_row) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
$res = Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advreassurance`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
AND `position`
'.($way
? '> '.(int)$moved_row['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_row['position'].' AND `position` >= '.(int)$position)
)
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advreassurance`
SET `position` = '.(int)$position.'
WHERE `id_reassurance`='.(int)$moved_row['id_reassurance']
);
$this->refreshPositions();
Hook::exec('actionRefreshReassurance');
return $res;
}
public function refreshPositions(){
$sql = 'SELECT `id_reassurance`
FROM `'._DB_PREFIX_.'advreassurance`
ORDER BY `position` ASC';
if (!$blocks = Db::getInstance()->executeS($sql))
return false;
$pos=0;
foreach ($blocks as $block) {
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'advreassurance`
SET `position` = '.(int)$pos.'
WHERE `id_reassurance`='.(int)$block['id_reassurance']);
$pos++;
}
}
}

View File

@ -0,0 +1,260 @@
<?php
include_once dirname(__FILE__).'/../../classes/AdvRea.php';
class AdminAdvReassuranceController extends ModuleAdminController {
public function __construct() {
$this->table = 'advreassurance';
$this->className = 'AdvRea';
$this->identifier = 'id_reassurance';
$this->lang = TRUE;
$this->deleted = FALSE;
$this->bootstrap = TRUE;
$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'reassurance'
);
$this->position_identifier = 'id_reassurance';
$this->_defaultOrderBy = 'position';
parent::__construct();
$this->actions = array('edit', 'delete');
$this->fields_list = array(
'id_reassurance' => array(
'title' => 'ID',
'width' => 25
),
'image' => array(
'title' => $this->module->l('Image'),
'image' => $this->fieldImageSettings['dir'],
'width' => 75
),
'title' => array(
'title' => $this->module->l('Titre'),
),
'subtitle' => array(
'title' => $this->module->l('Sout-titre'),
),
'category' => array(
'title' => $this->module->l('Catégorie')
),
'url' => array(
'title' => $this->module->l('Url'),
'width' => 45,
),
'position' => array(
'title' => $this->l('Position'),
'align' => 'center',
'position' => 'position',
'filter_key' => 'a!position'
)
);
if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_ALL) {
$this->_join .= 'JOIN `'._DB_PREFIX_.'advreassurance_shop` as ashop ON a.`id_reassurance` = ashop.`id_reassurance` AND ashop.`id_shop` IN ('.implode(', ', Shop::getContextListShopID()).') ';
$this->_group .= 'GROUP BY ashop.`id_reassurance`';
}
}
public function initPageHeaderToolbar() {
parent::initPageHeaderToolbar();
if ($this->display != 'edit' && $this->display != 'add') {
$this->page_header_toolbar_btn['new_link'] = array(
'href' => self::$currentIndex.'&id_parent='.(int)Tools::getValue('id_reassurance').'&addadvreassurance&token='.$this->token,
'desc' => $this->l('Ajouter un nouveau block', NULL, NULL, FALSE),
'icon' => 'process-icon-new'
);
}
}
public function renderView() {
return $this->renderList();
}
public function renderForm() {
$this->fields_form = array(
'tinymce' => TRUE,
'legend' => array(
'title' => $this->className,
),
'submit' => array(
'name' => 'submitAdvReassurancer',
'title' => $this->l('Save'),
),
'input' => array(
array(
'type' => 'textarea',
'label' => $this->l('Titre'),
'name' => 'title',
'autoload_rte' => TRUE,
'lang' => TRUE,
),
array(
'type' => 'text',
'label' => $this->l('Sous-titre'),
'name' => 'subtitle',
'lang' => TRUE,
),
array(
'type' => 'text',
'label' => $this->l('Lien'),
'name' => 'url',
'lang' => TRUE
),
array(
'type' => 'select',
'label' => $this->l('Catégorie'),
'name' => 'category',
'options' => array(
'query' => array(
array('id' => 'home', 'name' => 'Comment ca marche ?'),
array('id' => 'footer', 'name' => 'Footer')
),
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'switch',
'label' => $this->l('Activé'),
'name' => 'active',
'required' => FALSE,
'is_bool' => TRUE,
'default' => 1,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
),
),
array(
'type' => 'shop',
'label' => $this->l('Shop'),
'form_group_class' => 'fieldhide input_association',
'name' => 'checkBoxShopAsso_advreassurance'
)
)
);
$obj = $this->loadObject(TRUE);
$image = FALSE;
$image_url = '';
$image_size = '';
if($obj)
{
$image = _PS_IMG_DIR_ . 'reassurance/' . $obj->id.'.jpg';
$image_url = ImageManager::thumbnail($image, $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, TRUE, TRUE);
$image_size = file_exists($image) ? filesize($image) / 1000 : FALSE;
}
$this->fields_form['input'][] = array(
'type' => 'file',
'label' => $this->l('Image'),
'name' => 'image',
'display_image' => TRUE,
'lang' => TRUE,
'image' => $image_url,
'size' => $image_size,
'delete_url' => self::$currentIndex.'&'.$this->identifier.'='.$this->object->id.'&token='.$this->token.'&deleteImage=1'
);
return parent::renderForm();
}
protected function copyFromPost(&$object, $table) {
parent::copyFromPost($object, $table);
if(Shop::isFeatureActive())
{
$object->id_shop_list = array();
foreach (Tools::getValue('checkBoxShopAsso_advreassurance') as $id_shop => $value)
$object->id_shop_list[] = $id_shop;
}
}
public function postProcess() {
if (Tools::getValue('deleteImage')) {
$this->processForceDeleteImage();
$this->refreshPreview();
}
return parent::postProcess();
}
public function processForceDeleteImage() {
$link = $this->loadObject(TRUE);
if (Validate::isLoadedObject($link))
{
$link->deleteImage(TRUE);
}
}
protected function postImage($id) {
$ret = parent::postImage($id);
$this->refreshPreview();
if (isset($_FILES) && count($_FILES) && $_FILES['image']['name'] != NULL && !empty($this->object->id) )
{
return TRUE;
}
return TRUE;
}
public function refreshPreview()
{
$current_preview = _PS_TMP_IMG_DIR_.'advreassurance_mini_'.$this->object->id_reassurance.'_'.$this->context->shop->id.'.jpg';
if (file_exists($current_preview)) {
unlink($current_preview);
}
}
public function ajaxProcessUpdatePositions()
{
$way = (int)(Tools::getValue('way'));
$id = (int)(Tools::getValue('id'));
$positions = Tools::getValue('slide');
$obj = 'advreassurance';
if (is_array($positions)){
foreach ($positions as $position => $value)
{
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id)
{
$menu_obj = new AdvRea((int)$pos[2]);
if (Validate::isLoadedObject($menu_obj))
if (isset($position) && $menu_obj->updatePosition($way, $position))
{
echo 'ok position '.(int)$position.' for '.$obj.' '.(int)$pos[2]."\r\n";
}
else
echo '{"hasError" : true, "errors" : "Can not update '.$obj.' '.(int)$id.' to position '.(int)$position.' "}';
else
echo '{"hasError" : true, "errors" : "This '.$obj.' ('.(int)$id.') cannot be loaded"}';
break;
}
}
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,3 @@
<!-- Block Advmenu module -->
<!-- /Block Advmenu module -->

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