Compare commits

...

20 Commits

Author SHA1 Message Date
Thomas MONCHICOURT eadb2a397f Fix : probleme connexion apres login 2018-08-22 11:34:58 +02:00
Thomas MONCHICOURT 959dd61435 Feat : ajout lien modification menu et title 2018-08-21 14:33:38 +02:00
Thomas MONCHICOURT 6e63c1f2e8 feat : css pour la cookie bar en prod 2018-08-21 14:16:34 +02:00
Thomas MONCHICOURT 8a91476e86 Feat : css suite merge 2018-08-21 12:33:37 +02:00
Thomas MONCHICOURT 714bf6ad8e Feat : cookie bar #7105 @1h
# Conflicts:
#	volume/www/website/www/composer.json
#	volume/www/website/www/composer.lock
#	volume/www/website/www/vendor/composer/installed.json
#	volume/www/website/www/web/css/styles.css
#	volume/www/website/www/web/css/styles.css.map
#	volume/www/website/www/web/sass/modules/_app.scss
2018-08-21 12:33:20 +02:00
Thomas MONCHICOURT 1907aeb647 Feat : Mise en place des titles pour le suivi event #7071 @0h10 2018-08-16 14:43:46 +02:00
Thomas MONCHICOURT 5f1e89b7ea Fix : facebook connexion 2018-08-01 10:43:47 +02:00
root 0f7f85c39e Merge branch 'master' of https://git.e-declic.net/talents-tube/website 2018-07-26 09:31:57 +02:00
root e912a508d3 Conf : git erver side updated files 2018-07-26 09:31:46 +02:00
Maxime Thévenot ea3cdf0553 Fix : set store in noindex nofollow 2018-07-26 09:24:55 +02:00
Maxime Thévenot 4518a8a5e2 Fix: set noindex on spontaneous answer 2018-07-25 16:11:32 +02:00
Thomas MONCHICOURT c6a00a24c7 Merge branch 'develop'
# Conflicts:
#	volume/www/website/www/web/css/styles.css.map
2018-07-23 14:59:36 +02:00
Thomas MONCHICOURT 68ca21136a Fix : merge css 2018-07-23 14:55:29 +02:00
Thomas MONCHICOURT d14bea9c1a Fix : Territoires en homepage #6769 @0h10 2018-07-23 14:47:01 +02:00
Thomas MONCHICOURT b2a6e425aa Fix : modif css suite merge 2018-07-23 14:13:21 +02:00
Thomas MONCHICOURT fd48045549 Merge branch 'feat/new-style-title' into develop
# Conflicts:
#	volume/www/website/www/web/css/styles.css.map
2018-07-23 14:12:46 +02:00
Thomas MONCHICOURT 512d269f53 feat : Modification des titles en home #6769 @0h15 2018-07-23 11:07:07 +02:00
Thomas MONCHICOURT 3743166ac2 Feat: modification recherche #6770 @1h20 2018-07-23 10:45:31 +02:00
Thomas MONCHICOURT 72c72a5986 Feat : modification recherche #6770 @0h30 2018-07-20 17:08:08 +02:00
Thomas MONCHICOURT f3e2cb2cf1 Feat : Nouveau bandeau offre pourvu #6779 @0h30 2018-07-20 16:36:18 +02:00
144 changed files with 7375 additions and 12103 deletions
@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="https://www.prestashop.com/fr/blog/feed.xml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:og="http://ogp.me/ns#" xmlns:article="http://ogp.me/ns/article#" xmlns:book="http://ogp.me/ns/book#" xmlns:profile="http://ogp.me/ns/profile#" xmlns:video="http://ogp.me/ns/video#" xmlns:product="http://ogp.me/ns/product#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<channel>
<title>Blog Feed</title>
<link>https://www.prestashop.com/fr/blog/feed.xml</link>
<description></description>
<language>fr</language>
<atom:link href="https://www.prestashop.com/fr/blog/feed.xml" rel="self" type="application/rss+xml" />
<item>
<title>4 moyens daugmenter votre taux de conversion grâce à votre page de paiement</title>
<link>https://www.prestashop.com/fr/4-moyens-daugmenter-votre-taux-de-conversion-grace-a-votre-page-de-paiement-6</link>
<description>Par 
Dernier contact entre un marchand et son client, nous savons que le check-out est un passage délicat dans le tunnel de conversion.
</description>
<pubDate>Thu, 20 Jul 2017 16:30:04 +0200</pubDate>
<dc:creator>Anonymous</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/4-moyens-daugmenter-votre-taux-de-conversion-grace-a-votre-page-de-paiement-6</guid>
</item>
<item>
<title>Comment une agence de développement web peut-elle vous être utile ?</title>
<link>https://www.prestashop.com/fr/comment-une-agence-de-developpement-web-peut-elle-vous-etre-utile</link>
<description>Par 
Lorsquun marchand nous contacte pour la première fois, lune des questions récurrentes est : &quot;Pourquoi confier ses développements à une agence ?&quot;. Puis, à propos de PrestaShop: &quot;Puisque le logiciel est gratuit, ai-je vraiment besoin d&#039;un prestataire technique ?&quot;.
</description>
<pubDate>Thu, 20 Jul 2017 14:46:24 +0200</pubDate>
<dc:creator>Anonymous</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/comment-une-agence-de-developpement-web-peut-elle-vous-etre-utile</guid>
</item>
<item>
<title>Rencontrez Nicolas, Ambassadeur du mois | Juillet 2017</title>
<link>https://www.prestashop.com/fr/blog/prestashop-ambassadors/rencontrez-nicolas-ambassadeur-du-mois-juillet-2017-2</link>
<description>CreaNico est notre Ambassadeur à Montpellier, France, et est très actif dans la région.</description>
<pubDate>Tue, 18 Jul 2017 17:27:38 +0200</pubDate>
<dc:creator>Manon Plommet</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/prestashop-ambassadors/rencontrez-nicolas-ambassadeur-du-mois-juillet-2017-2</guid>
</item>
<item>
<title>Zoom sur l&amp;#039;e-commerce italien</title>
<link>https://www.prestashop.com/fr/blog/tendances-e-commerce/zoom-sur-le-commerce-italien</link>
<description>Avec un taux de croissance des ventes de 18% en 2016, une base dacheteurs en ligne de 18 millions de personnes et un panier moyen en augmentation, le e-commerce italie</description>
<pubDate>Mon, 17 Jul 2017 18:34:12 +0200</pubDate>
<dc:creator>vMartelli</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/tendances-e-commerce/zoom-sur-le-commerce-italien</guid>
</item>
<item>
<title>Rentrée, Black Friday, Noël : Téléchargez votre guide e-commerce de fin d&amp;#039;année</title>
<link>https://www.prestashop.com/fr/blog/actualites-prestashop/rentree-black-friday-noel-telechargez-votre-guide-e-commerce-de-fin-dannee-1</link>
<description>La rentrée, Black Friday, Noël : en quelques mois seulement se joue la majeure partie du chiffre daffaires de lactivité e-commerce.</description>
<pubDate>Mon, 17 Jul 2017 14:28:47 +0200</pubDate>
<dc:creator>Cécile Dubouis</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/actualites-prestashop/rentree-black-friday-noel-telechargez-votre-guide-e-commerce-de-fin-dannee-1</guid>
</item>
<item>
<title>Lutte contre la fraude à la TVA, allègement de la loi</title>
<link>https://www.prestashop.com/fr/blog/actualites-prestashop/lutte-fraude-tva-allegement-loi</link>
<description>Suite à notre article Conformité à larticl</description>
<pubDate>Mon, 26 Jun 2017 10:10:00 +0200</pubDate>
<dc:creator>Mohammed Bellamine</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/actualites-prestashop/lutte-fraude-tva-allegement-loi</guid>
</item>
<item>
<title>Planning et astuces pour créer des promotions efficaces sur PrestaShop</title>
<link>https://www.prestashop.com/fr/blog/conseils-e-commerce/planning-et-astuces-pour-creer-des-promotions-efficaces-sur-prestashop</link>
<description>Été, rentrée, Black Friday, Noël… Les promotions de fin dannée sont primordiales en e-commerce, mais leur préparation peut être chronophage.</description>
<pubDate>Mon, 19 Jun 2017 11:24:19 +0200</pubDate>
<dc:creator>Cécile Dubouis</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/conseils-e-commerce/planning-et-astuces-pour-creer-des-promotions-efficaces-sur-prestashop</guid>
</item>
<item>
<title>10 ans 10 interviews « portrait » : Keiko ITO, développeuse web au Japon </title>
<link>https://www.prestashop.com/fr/blog/actualites-prestashop/10-ans-10-interviews-portrait-keiko-ito-developpeuse-web-au-japon</link>
<description>Le pitch / Originaire de Kobe, au Japon, Keiko est passionnée par le web et la France.</description>
<pubDate>Fri, 16 Jun 2017 16:17:35 +0200</pubDate>
<dc:creator>Mpierrot</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/actualites-prestashop/10-ans-10-interviews-portrait-keiko-ito-developpeuse-web-au-japon</guid>
</item>
<item>
<title>Rencontrez Claudia, Ambassadrice du mois | Juin 2017</title>
<link>https://www.prestashop.com/fr/blog/prestashop-ambassadors/clone-of-meet-claudia-ambassador-of-the-month-june-2017</link>
<description>Claudia est notre Ambassadrice à Monterrey, Mexique, et y organise des meetups très régulièrement. Elle est toujours partante pour parler de PrestaShop !</description>
<pubDate>Fri, 16 Jun 2017 11:38:21 +0200</pubDate>
<dc:creator>Manon Plommet</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/prestashop-ambassadors/clone-of-meet-claudia-ambassador-of-the-month-june-2017</guid>
</item>
<item>
<title>10 ans 10 interviews « portrait » : Corinne Lejbowicz, CEO de PrestaShop</title>
<link>https://www.prestashop.com/fr/blog/actualites-prestashop/10-ans-10-interviews-portrait-corinne-lejbowicz-ceo-de-prestashop</link>
<description>Le pitch / En 2007, Corinne Lejbowicz est CEO de LeGuide.com, où elle rencontre le jeune Bruno Lévêque.</description>
<pubDate>Wed, 14 Jun 2017 15:06:02 +0200</pubDate>
<dc:creator>Mpierrot</dc:creator>
<guid isPermaLink="false">https://www.prestashop.com/fr/blog/actualites-prestashop/10-ans-10-interviews-portrait-corinne-lejbowicz-ceo-de-prestashop</guid>
</item>
</channel>
</rss>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -261,7 +261,7 @@
</tab>
<tab class_name="AdminPayment" display_type="default_list">
<module name="secureframe" position="1"/>
<module name="paypalmx" position="2"/>
<module name="paypal" position="13"/>
<module name="mercadopagobr" position="3"/>
<module name="payulatam" position="4"/>
<module name="dotpay" position="5"/>
@@ -272,14 +272,14 @@
<module name="simplifycommerce" position="10"/>
<module name="klarnaofficial" position="11"/>
<module name="spsrsmartsepa" position="12"/>
<module name="oyst" position="13"/>
<module name="ewayrapid" position="14"/>
<module name="fcpayone" position="15"/>
<module name="pagseguro" position="16"/>
<module name="ewayrapid" position="17"/>
<module name="hipay" position="18"/>
<module name="ogone" position="19"/>
<module name="payplug" position="20"/>
<module name="payplug" position="2"/>
<module name="oyst" position="14"/>
<module name="ewayrapid" position="15"/>
<module name="fcpayone" position="16"/>
<module name="pagseguro" position="17"/>
<module name="ewayrapid" position="18"/>
<module name="hipay" position="19"/>
<module name="ogone" position="20"/>
<module name="realexredirect" position="21"/>
<module name="stripe_official" position="22"/>
<module name="skrill" position="23"/>
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
<?xml version="1.0"?>
<modules_list><modules type="untrusted"><module name="blockreinsurance"/><module name="etransactions"/><module name="trackingfront"/></modules></modules_list>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
@charset "UTF-8";
@media only print{#header .nav,#header .banner,#header .row > div{display:none}#header .row div#header_logo{display:block}#center_column{width:100% !important}#left_column,#right_column{display:none}.no-print,#quantity_wanted_p > a,a.quick-view{display:none !important}div.selector,div.selector span,div.selector select{background:none}#thumbs_list li a:hover,#thumbs_list li a.shown{border-color:#fff}.product_attributes,.box-cart-bottom{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.pb-left-column #views_block{margin-top:10px;width:278px !important}#thumbs_list_frame,#thumbs_list{width:100% !important;height:100% !important}#thumbs_list li,#thumbs_list li:first-child{margin:4px;width:82px;height:82px}#view_scroll_left,#view_scroll_right,.view_scroll_spacer{display:none !important}.bx-wrapper{width:100% !important;max-width:100% !important}.bx-viewport{height:auto !important}#bxslider,#bxslider1,#crossselling_list_car{width:100% !important;height:auto !important;overflow:visible !important}#bxslider1 .product-box{min-height:200px}.bx-controls-direction{display:none}#footer .row > div,#footer .row > section{display:none}#footer .row > div#block_contact_infos,#footer .row > section#block_contact_infos{display:block;width:100%;border-left:none;border-top:1px solid #515151;padding-top:20px}.footer-container #footer h4:after{display:none}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -51,7 +51,8 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
<meta name="keywords" content="{$meta_keywords|escape:'html':'UTF-8'}" />
{/if}
<meta name="generator" content="PrestaShop" />
<meta name="robots" content="{if isset($nobots)}no{/if}index,{if isset($nofollow) && $nofollow}no{/if}follow" />
<!-- <meta name="robots" content="{if isset($nobots)}no{/if}index,{if isset($nofollow) && $nofollow}no{/if}follow" /> -->
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, minimum-scale=0.25, maximum-scale=1.6, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="icon" type="image/vnd.microsoft.icon" href="{$favicon_url}?{$img_update_time}" />
+3
View File
@@ -48,6 +48,9 @@ class AppKernel extends Kernel
//oAuth
new Http\HttplugBundle\HttplugBundle(),
new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),
//CookieBar
new Fairlane\CookieConsentBundle\FairlaneCookieConsentBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
@@ -0,0 +1,39 @@
{% if fairlane_cookie_consent.active == true and app.request.cookies.get('fairlane-cookie-consent') != 'ok'%}
{% if fairlane_cookie_consent.translate == true %}
{% set text_info = fairlane_cookie_consent.twig.text_info | trans %}
{% set text_additional_info_link = fairlane_cookie_consent.twig.text_additional_info_link | trans %}
{% set text_accept_button = fairlane_cookie_consent.twig.text_accept_button | trans %}
{% else %}
{% set text_info = fairlane_cookie_consent.twig.text_info %}
{% set text_additional_info_link = fairlane_cookie_consent.twig.text_additional_info_link %}
{% set text_accept_button = fairlane_cookie_consent.twig.text_accept_button %}
{% endif %}
<div id="fairlane-cookie-consent" {% if fairlane_cookie_consent.useBootstrap == true %}class="navbar navbar-fixed-top"{% endif %}>
<p>
{{ text_info }}
{% if fairlane_cookie_consent.twig.url_additional_info| length > 1 and text_additional_info_link | length > 1 %}
<a href="{{ fairlane_cookie_consent.twig.url_additional_info }}" target="_blank">{{ text_additional_info_link }}</a>
{% endif %}
</p>
<button class="btn btn-default">{{ text_accept_button }}</button>
</div>
{% if fairlane_cookie_consent.useJquery %}
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#fairlane-cookie-consent button").click(function(){
jQuery.ajax({
async: true,
type: 'POST',
url: '{{ url('fairlane_cookie_consent_accept') }}',
data: JSON.stringify({'cookie-consent': 'ok'}),
success: function(data) {
jQuery("#fairlane-cookie-consent").fadeOut("fast");
},
contentType: "application/json",
dataType: 'json'
});
})
});
</script>
{% endif %}
{% endif %}
@@ -52,7 +52,7 @@
</div>
<div class="row m-t-40">
<div class="col s10 offset-s1 center-align">
<button id="submit" class=" btn btn-large btn-default disabled" type="submit">
<button title="import-candidature" id="submit" class=" btn btn-large btn-default disabled" type="submit">
Envoyer ma candidature
</button><br /><br />
<a class="color-grey5" href="{{ path(routeObject,{'alias': object.alias }) }}">Annuler</a>
@@ -1,4 +1,7 @@
{% extends 'base.html.twig' %}
{% block metarobot %}<meta name="robots" content="noindex,follow">{% endblock %}
{% block content %}
{% if typeObject == 'Ad' %}
{% set subtitle = 'Candidature à l\'offre d\'emploi:' %}
@@ -88,7 +88,7 @@
</div>
<div class="row m-t-40">
<div class="col s10 offset-s1 center-align">
<button id="submit" class=" btn btn-large btn-default disabled" type="submit">
<button title="webcam-candidature" id="submit" class=" btn btn-large btn-default disabled" type="submit">
Envoyer ma candidature
</button><br /><br />
<a class="color-grey5" href="{{ path(routeObject,{'alias': object.alias }) }}">Annuler</a>
@@ -21,7 +21,7 @@
<script type="text/javascript" defer="defer" src="https://extend.vimeocdn.com/ga/64189815.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>{% block title %}Talents Tube : Le 1er job board 100% vidéo{% endblock %}</title>
<title>{% block title %}Talents Tube : La 1ère plateforme pour lemploi 100% vidéo{% endblock %}</title>
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}"/>
{% block metarobot %}<meta name="robots" content="index,follow">{% endblock %}
@@ -83,5 +83,6 @@
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
{{ include('FairlaneCookieConsentBundle::cookie-info.html.twig') }}
</body>
</html>
@@ -27,9 +27,11 @@
<h3>Profil du talent : </h3>
<div class="profil">
<p class="profil-picture">
{% if answer.user.getWebPath() %}
<img src="{{ answer.user.getWebPath() | imagine_filter('profile_square') }}"
alt="{{ answer.user.firstname }} {{ answer.user.lastname }}"
class="circle responsive-img"/>
{% endif %}
</p>
<i class="fa fa-user-circle"
aria-hidden="true"></i> {{ answer.user.firstname }} {{ answer.user.lastname }}
@@ -12,10 +12,12 @@
<span class="playerbtn"></span>
{% endif %}
</a>
{% if a.isPromoted %}
<div class="isPromoted">
OFFRE POURVUE
</div>
{% endif %}
</div>
{% if a.isPromoted %}
<div class="isPromoted"><img src="{{asset('/img/offre-pourvue-gauche.png')}}" alt="promoted"></div>
{% endif %}
<div class="col s12 m8 col-noPadding">
<div class="row row-infos row-noMargin">
<div class="col s4 m4 l5 company-infos col-noPadding">
@@ -47,7 +47,9 @@
</div>
{#{% endif %}#}
{% if ad.isPromoted %}
<div class="isPromoted"><img src="{{asset('/img/offre-pourvue-gauche.png')}}" alt="promoted"></div>
<div class="isPromoted">
OFFRE POURVUE
</div>
{% endif %}
</div>
{% endif %}
@@ -33,6 +33,9 @@
<li>
<a class="white-text" href="{{ path('service_cgu') }}">Conditions générales d'utilisation</a>
</li>
<li>
<a class="white-text" href="{{ path('page_Confidentialite') }}">Politique de confidentialité et protection des données</a>
</li>
</ul>
</div>
<div class="col xl3 l3 m6 s12 left-align">
@@ -9,7 +9,7 @@
<li><a href="{{ path('page_accompagnementTalent') }}" title="Accompagnement talent">Accompagnement</a></li>
</ul>
<ul id='dropdown_company' class='dropdown-content'>
<li><a href="{{ path('company_list') }}" title="Listes entreprises">Listes entreprises</a></li>
<li><a href="{{ path('company_list') }}" title="Les entreprises qui recrutent">Les entreprises qui recrutent</a></li>
<li><a href="{{ path('page_OffreEmploi') }}" title="L'offre d'emploi en vidéo">L'offre d'emploi en vidéo</a></li>
<li><a href="{{ path('page_reussirOffrevideo') }}" title="Comment faire une offre en vidéo">Comment faire une offre en vidéo</a></li>
<li><a href="{{ path('page_MarqueEmployeur') }}" title="Vidéo Marque Employeur">Vidéo Marque Employeur</a></li>
@@ -33,7 +33,10 @@
<div id="liste-jobs" class="fuild-container bg-grey-3 button-plus">
<div class="container">
<div class="row center-align">
<div class="col s12"><h2 class="blue-text no-margin-top">Les offres <span>d'emploi</span></h2></div>
<div class="col s12">
<h2 class="blue-text no-margin-top">Les offres d'emploi</h2>
<h3 class="subtitles-homepage">Postulez en CV vidéo ou vidéo de motivation</h3>
</div>
</div>
<div class="row">
<div class="col s12 col-noPadding">
@@ -47,7 +50,7 @@
<div class="row center-align">
<div class="col s12">
<a href="{{ path('ad_search_result') }}" title="Découvrir toutes les offres d'emploi"
class="btn btn-default btn-round btn-all-jobs">Découvrir toutes les offres d'emploi
class="btn btn-default btn-round btn-all-jobs">Voir les offres
</a>
</div>
</div>
@@ -60,9 +63,8 @@
<div class="container">
<div class="row center-align">
<div class="col s12">
<h2 class="blue-text no-margin-top">
La marque employeur des <span>entreprises de talents</span>
</h2>
<h2 class="blue-text no-margin-top">Ils recrutent</h2>
<h3 class="subtitles-homepage">Ils méritent votre candidature spontanée, découvrez leur réalité, leur marque employeur.</h3>
</div>
</div>
<div class="row">
@@ -76,7 +78,7 @@
</div>
<div class="row center-align">
<div class="col s12">
<a href="{{ path('company_list') }}" title="Toutes les entreprise" class="btn btn-default btn-round btn-all-talents">Découvrir toutes les entreprises</a>
<a href="{{ path('company_list') }}" title="Toutes les entreprise" class="btn btn-default btn-round btn-all-talents">Voir les entreprises</a>
</div>
</div>
</div>
@@ -90,8 +92,8 @@
<div id="liste-talents" class="bg-dark2 button-plus">
<div class="container">
<div class="row center-align">
<div class="col s12"><h2 class="blue-text no-margin-top">Les CV vidéo
<span>à la une</span></h2></div>
<div class="col s12"><h2 class="blue-text no-margin-top">Les talents</h2></div>
<h3 class="subtitles-homepage">Découvrez leurs CV vidéo et vidéo de motivation.</h3>
</div>
<div class="row">
<div class="owl-carousel owl-carousel-home home-talent-carousel">
@@ -107,7 +109,8 @@
<div class="container">
<div class="row center-align">
<div class="col s12">
<h2 class="blue-text no-margin-top">Les territoires <span>pour vivre et travailler</span></h2>
<h2 class="blue-text no-margin-top">Les territoires</h2>
<h3 class="subtitles-homepage">Venez vivre et travailler chez nous.</h3>
{% if territories %}
<div class="owl-carousel owl-carousel-home territory-carousel">
{% for territory in territories if territory.presentationVideo and territory.isPrivate != true %}
@@ -120,8 +123,8 @@
</div>
</div>
<div class="m-t-30">
<a title="territoire de {{ territory.brandname }}" class="btn btn-default" href="{{ path('territory_show',{'alias': territory.alias }) }}">
Voir le territoire de <span>{{ territory.brandname }}</span>
<a title="Voir les territoires" class="btn btn-default" href="{{ path('territory_list') }}">
Voir les territoires</span>
</a>
</div>
</div>
@@ -59,10 +59,26 @@ doctrine:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
AppBundle: ~
fairlane_cookie_consent:
active: true
use_bootstrap: true
use_jquery: true
translate: false
cookie_lifetime: 90 # days
twig:
text_info: 'Notre site utilise des cookies et recueille des informations vous concernant à des fins fonctionnelles et / ou publicitaires. Nous vous invitons à accepter la collecte ou configurer vos choix. Vous pouvez modifier vos paramètres à tout moment.'
text_accept_button: 'Accepter'
text_additional_info_link: 'En savoir plus'
url_additional_info: 'https://www.talentstube.com/confidentialite'
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
fairlane_cookie_consent: '@fairlane_cookie_consent.twig'
# Swiftmailer Configuration
swiftmailer:
@@ -19,4 +19,7 @@ hwi_oauth_connect:
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /login
prefix: /login
fairlane_cookie_consent:
resource: "@FairlaneCookieConsentBundle/Resources/config/routing.yml"
@@ -3,8 +3,8 @@ security:
in_memory:
memory: ~
fos_userbundle:
id: fos_user.user_provider.username_email
#id: app.user_provider
#id: fos_user.user_provider.username_email
id: app.user_provider
firewalls:
dev:
+3 -1
View File
@@ -50,7 +50,9 @@
"php-http/httplug-bundle": "^1.8",
"symfony/assetic-bundle": "^2.8",
"friendsofsymfony/elastica-bundle": "4.1.*",
"liip/imagine-bundle": "^1.9"
"liip/imagine-bundle": "^1.9",
"twig/extensions": "^1.5",
"fairlane/cookie-consent-bundle": "^1.0"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
+98 -2
View File
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1ee242a3c7f90797f49f553ffc4a342d",
"content-hash": "4f2ac88cf6d46bc55a35e28d9e2a66f5",
"packages": [
{
"name": "alcaeus/mongo-php-adapter",
@@ -1498,6 +1498,46 @@
],
"time": "2017-07-17T17:04:59+00:00"
},
{
"name": "fairlane/cookie-consent-bundle",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/fairlane/cookie-consent-bundle.git",
"reference": "db2ca1c40a44e13c090406da6704b428d00dfd84"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fairlane/cookie-consent-bundle/zipball/db2ca1c40a44e13c090406da6704b428d00dfd84",
"reference": "db2ca1c40a44e13c090406da6704b428d00dfd84",
"shasum": ""
},
"require": {
"php": ">=7.0",
"symfony/framework-bundle": ">=2.7",
"symfony/twig-bundle": ">=2.7",
"twig/twig": ">=1.28"
},
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Fairlane\\CookieConsentBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"WTFPL"
],
"description": "EU Cookie Consent Bundle for Symfony",
"keywords": [
"cookie",
"cookie consent"
],
"time": "2017-11-12T00:24:21+00:00"
},
{
"name": "friendsofsymfony/elastica-bundle",
"version": "v4.1.1",
@@ -4107,6 +4147,7 @@
"compression",
"minification"
],
"abandoned": "symfony/webpack-encore-pack",
"time": "2017-07-14T07:26:46+00:00"
},
{
@@ -4715,6 +4756,61 @@
],
"time": "2017-11-16T18:00:05+00:00"
},
{
"name": "twig/extensions",
"version": "v1.5.2",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig-extensions.git",
"reference": "2c1a86526d0044065220d1b51ac08348bea5ca82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/2c1a86526d0044065220d1b51ac08348bea5ca82",
"reference": "2c1a86526d0044065220d1b51ac08348bea5ca82",
"shasum": ""
},
"require": {
"twig/twig": "^1.27|^2.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.4",
"symfony/translation": "^2.7|^3.4"
},
"suggest": {
"symfony/translation": "Allow the time_diff output to be translated"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-0": {
"Twig_Extensions_": "lib/"
},
"psr-4": {
"Twig\\Extensions\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Common additional features for Twig that do not directly belong in core",
"keywords": [
"i18n",
"text"
],
"time": "2018-05-22T13:26:07+00:00"
},
{
"name": "twig/twig",
"version": "v2.4.4",
@@ -298,11 +298,17 @@ class AdController extends Controller
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
if (is_null($data['job'])) {
return $this->redirectToRoute('homepage');
//return $this->redirectToRoute('homepage');
$session->remove('jobSearch');
unset($data['job']);
} else {
$session->set('jobSearch', $data['job']);
}
$session->set('jobSearch', $data['job']);
if (!is_null($data['contrat'])) {
$session->set('contratSearch', $data['contrat']);
} else {
$session->remove('contratSearch');
}
$adSearcher = $this->get('app.ad_searcher');
$ads = $adSearcher->process($data);
@@ -319,7 +325,8 @@ class AdController extends Controller
return $this->render('default/ad_search_result.html.twig', [
'ads' => $ads,
'noResults' => $noResults
'noResults' => $noResults,
'isPromotedAds' => $promoted
]);
} else {
@@ -357,6 +364,7 @@ class AdController extends Controller
$ads[] = $ad;
}
}
return $ads;
}
@@ -233,4 +233,17 @@ class PageController extends Controller
]);
}
/**
* @Route("/confidentialite", name="page_Confidentialite")
*/
public function ConfidentialiteAction()
{
$em = $this->getDoctrine()->getManager();
$page = $em->getRepository('AppBundle:Page')->findOneByRef('CONFIDENTIALITE');
return $this->render('default/page.html.twig', [
'page' => $page
]);
}
}
@@ -95,6 +95,7 @@ class Page
$pages[] = 'MARQUEEMPLOYEUR';
$pages[] = 'VIDEOTERRITTORY';
$pages[] = 'ACCTERRITTORY';
$pages[] = 'CONFIDENTIALITE';
// $pages[] = '';
return $pages;
@@ -16,7 +16,7 @@ class AdSearchType extends AbstractType
$builder
->add('job', TextType::class, array(
'label' => false,
'required' => true,
'required' => false,
'attr' => array(
'placeholder' => 'Rechercher une offre d\'emploi vidéo par mots clés',
)
@@ -2,19 +2,11 @@
namespace AppBundle\Security\Core\User;
use FOS\UserBundle\Model\UserInterface as FOSUserInterface;
use AppBundle\Entity\Company;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseFOSUBProvider;
use AppBundle\Entity\Company;
use AppBundle\Entity\Answer;
use AppBundle\Entity\Media;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Core\User\UserInterface;
class FOSUBUserProvider extends BaseFOSUBProvider
{
@@ -22,20 +14,19 @@ class FOSUBUserProvider extends BaseFOSUBProvider
public function __construct($userManager, $em, $slug, $container, array $properties)
{
parent::__construct($userManager,$properties);
parent::__construct($userManager, $properties);
$this->em = $em;
$this->slugService = $slug;
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$isTmpUser = false;
if($this->container->get('security.token_storage')->getToken()){
if ($this->container->get('security.token_storage')->getToken()) {
$userConnected = $this->container->get('security.token_storage')->getToken()->getUser();
if ($userConnected->hasRole('ROLE_TALENT_TMP')) {
$isTmpUser = true;
@@ -46,7 +37,7 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$property = $this->getProperty($response);
$username = $response->getUsername(); // get the unique user identifier
$serviceName = $response->getResourceOwner()->getName();
$propertyQuery = str_replace('_', '', lcfirst(ucwords($property, '_')));
$propertyQuery = str_replace('_', '', lcfirst(ucwords($property, '_')));
$setter = 'set' . ucfirst($serviceName) . 'Id';
$setterToken = 'set' . ucfirst($serviceName) . 'AccessToken';
$existingUser = $this->userManager->findUserBy(array($propertyQuery => $username));
@@ -56,7 +47,7 @@ class FOSUBUserProvider extends BaseFOSUBProvider
}
if (null !== $existingUser) {
$this->disconnect($existingUser, $response);
if($isTmpUser){
if ($isTmpUser) {
$this->assignToRealAccount($userConnected, $existingUser);
$user = $existingUser;
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
@@ -66,7 +57,7 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$existingUser->$setterToken($response->getAccessToken());
$this->userManager->updateUser($existingUser);
} else {
if($isTmpUser){
if ($isTmpUser) {
$existingUser = $this->loadUserByOAuthUserResponse($response);
$this->assignToRealAccount($userConnected, $existingUser);
$existingUser->$setter($username);
@@ -81,9 +72,17 @@ class FOSUBUserProvider extends BaseFOSUBProvider
}
}
public function assignToRealAccount($userConnected, $existingUser) {
/**
* This function is meant to reassign data from a temporary account to a real account
*
* @param $userConnected
* @param $existingUser
* @return void
*/
public function assignToRealAccount($userConnected, $existingUser)
{
$answers = $this->em->getRepository('AppBundle:Answer')->findBy(array('user' => $userConnected));
$medias = $this->em->getRepository('AppBundle:Media')->findBy(array('creator'=> $userConnected));
$medias = $this->em->getRepository('AppBundle:Media')->findBy(array('creator' => $userConnected));
foreach ($medias as $key => $media) {
$media->setCreator($existingUser);
}
@@ -95,56 +94,77 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$this->userManager->deleteUser($userConnected);
}
/**
* Load a user by username.
*
* @param string $username
*
* @return UserInterface|null
*/
public function loadUserByUsername($username)
{
$existingUser = $this->userManager->findUserByEmail($username);
if($this->container->get('security.token_storage')->getToken()){
$existingUser = $this->userManager->findUserByUsername($username);
if($existingUser == null){
$existingUser = $this->userManager->findUserByEmail($username);
}
//Used to assign data from temporry account to real account
if ($this->container->get('security.token_storage')->getToken()) {
$userConnected = $this->container->get('security.token_storage')->getToken()->getUser();
if ($userConnected->hasRole('ROLE_TALENT_TMP')) {
$this->assignToRealAccount($userConnected, $existingUser);
}
}
return $existingUser;
}
/**
* {@inheritDoc}
*/
* Used to create or load user when linkedin or Facebook Oauth is used
*
* @param UserResponseInterface $response
* @return $user
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
{
$serviceName = $response->getResourceOwner()->getName();
$data = $response->getData();
$userConnected = null;
if($this->container->get('security.token_storage')->getToken()){
if ($this->container->get('security.token_storage')->getToken()) {
$userConnected = $this->container->get('security.token_storage')->getToken()->getUser();
}
$userEmail = $response->getEmail();
$user = $this->userManager->findUserByEmail($userEmail);
if($serviceName == "linkedin"){
if ($serviceName == "linkedin") {
$id = $data['id'];
$birthday = null;
$gender = null;
$userPhoto = $data['pictureUrls']['values'][0];
$username = $data['firstName']."-".$data['lastName'];
$username = $data['firstName'] . "-" . $data['lastName'];
$firstname = $data['firstName'];
$lastname = $data['lastName'];
} else {
$userPhoto = 'http://graph.facebook.com/'.$data['id'].'/picture?height=200';
$birthday = \DateTime::createFromFormat ('m/d/Y', $data['birthday']);
$gender = $data['gender'];
if(isset($data['birthday'])){
$birthday = \DateTime::createFromFormat ('m/d/Y', $data['birthday']);
} else {
$birthday = null;
}
if (isset($data['gender'])) {
$gender = $data['gender'];
} else {
$gender = null;
}
$id = $data['id'];
$firstname = $data['first_name'];
$lastname = $data['last_name'];
}
if (null === $user) {
if (null === $user) {
$user = $this->userManager->createUser();
$user->setUsername($firstname."-".$lastname);
$user->setUsername($firstname . "-" . $lastname);
$user->setFirstname($firstname);
$user->setLastname($lastname);
$user->setEmail($userEmail);
@@ -154,10 +174,10 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$user->setRoles(array('ROLE_TALENT'));
$user->setBirthday($birthday);
$user->setGender($gender);
if($serviceName == "linkedin"){
if ($serviceName == "linkedin") {
$user->setLinkedinId($id);
}
if($serviceName == "facebook"){
if ($serviceName == "facebook") {
$user->setFacebookId($id);
}
$this->userManager->updateUser($user);
@@ -176,10 +196,10 @@ class FOSUBUserProvider extends BaseFOSUBProvider
return $user;
} else {
if($userConnected) {
if ($userConnected) {
$userConnected->hasRole('ROLE_TALENT_TMP');
if ($userConnected->hasRole('ROLE_TALENT_TMP')) {
$user->setUsername($firstname."-".$lastname);
$user->setUsername($firstname . "-" . $lastname);
$user->setFirstname($firstname);
$user->setLastname($lastname);
$user->setEmail($userEmail);
@@ -189,10 +209,10 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$user->setRoles(array('ROLE_TALENT'));
$user->setBirthday($birthday);
$user->setGender($gender);
if($serviceName == "linkedin"){
if ($serviceName == "linkedin") {
$user->setLinkedinId($id);
}
if($serviceName == "facebook"){
if ($serviceName == "facebook") {
$user->setFacebookId($id);
}
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
@@ -205,7 +225,6 @@ class FOSUBUserProvider extends BaseFOSUBProvider
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
$user->$setter($response->getAccessToken());
return $user;
return $user;
}
}
@@ -52,11 +52,12 @@ class AdSearcher
}
$boolQuery = new \Elastica\Query\BoolQuery();
$fieldQuery = new \Elastica\Query\MultiMatch();
$fieldQuery->setQuery($data['job']);
$fieldQuery->setFields(['title', 'publicTag', 'company.brandname']);
$boolQuery->addMust($fieldQuery);
if(isset($data['job'])){
$fieldQuery->setQuery($data['job']);
$fieldQuery->setFields(['title', 'publicTag', 'company.brandname']);
$boolQuery->addMust($fieldQuery);
}
if($data['contrat']){
$fieldQueryContract = new \Elastica\Query\Match();
$fieldQueryContract->setFieldQuery('contract_type', $data['contrat']);
+3 -3
View File
@@ -377,11 +377,11 @@ class ClassLoader
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
$length = $this->prefixLengthsPsr4[$first][$search];
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
+4 -4
View File
@@ -17,9 +17,9 @@ return array(
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
'6a47392539ca2329373e0d33e1dba053' => $vendorDir . '/symfony/polyfill-intl-icu/bootstrap.php',
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
'ce89ac35a6c330c55f4710717db9ff78' => $vendorDir . '/kriswallsmith/assetic/src/functions.php',
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
'6a47392539ca2329373e0d33e1dba053' => $vendorDir . '/symfony/polyfill-intl-icu/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
);
@@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Twig_Extensions_' => array($vendorDir . '/twig/extensions/lib'),
'Twig_' => array($vendorDir . '/twig/twig/lib'),
'SensioLabs\\Security' => array($vendorDir . '/sensiolabs/security-checker'),
'RequestLab\\VimeoBundle' => array($vendorDir . '/requestlab/vimeo-bundle'),
+4 -2
View File
@@ -9,6 +9,7 @@ return array(
'Zend\\EventManager\\' => array($vendorDir . '/zendframework/zend-eventmanager/src'),
'Zend\\Code\\' => array($vendorDir . '/zendframework/zend-code/src'),
'Vimeo\\' => array($vendorDir . '/vimeo/vimeo-api/src/Vimeo'),
'Twig\\Extensions\\' => array($vendorDir . '/twig/extensions/src'),
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Tests\\' => array($baseDir . '/tests'),
'Symfony\\Polyfill\\Util\\' => array($vendorDir . '/symfony/polyfill-util'),
@@ -40,10 +41,10 @@ return array(
'Jaybizzle\\CrawlerDetect\\' => array($vendorDir . '/jaybizzle/crawler-detect/src'),
'Incenteev\\ParameterHandler\\' => array($vendorDir . '/incenteev/composer-parameter-handler'),
'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'),
'Http\\Message\\' => array($vendorDir . '/php-http/message-factory/src', $vendorDir . '/php-http/message/src'),
'Http\\Message\\' => array($vendorDir . '/php-http/message/src', $vendorDir . '/php-http/message-factory/src'),
'Http\\HttplugBundle\\' => array($vendorDir . '/php-http/httplug-bundle'),
'Http\\Discovery\\' => array($vendorDir . '/php-http/discovery/src'),
'Http\\Client\\Common\\Plugin\\' => array($vendorDir . '/php-http/stopwatch-plugin/src', $vendorDir . '/php-http/logger-plugin/src', $vendorDir . '/php-http/cache-plugin/src'),
'Http\\Client\\Common\\Plugin\\' => array($vendorDir . '/php-http/cache-plugin/src', $vendorDir . '/php-http/logger-plugin/src', $vendorDir . '/php-http/stopwatch-plugin/src'),
'Http\\Client\\Common\\' => array($vendorDir . '/php-http/client-common/src'),
'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'),
'Http\\Adapter\\Guzzle6\\' => array($vendorDir . '/php-http/guzzle6-adapter/src'),
@@ -51,6 +52,7 @@ return array(
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Fairlane\\CookieConsentBundle\\' => array($vendorDir . '/fairlane/cookie-consent-bundle'),
'FOS\\UserBundle\\' => array($vendorDir . '/friendsofsymfony/user-bundle'),
'FOS\\ElasticaBundle\\' => array($vendorDir . '/friendsofsymfony/elastica-bundle'),
'Elastica\\' => array($vendorDir . '/ruflin/elastica/lib/Elastica'),
+22 -8
View File
@@ -18,11 +18,11 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
'6a47392539ca2329373e0d33e1dba053' => __DIR__ . '/..' . '/symfony/polyfill-intl-icu/bootstrap.php',
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
'ce89ac35a6c330c55f4710717db9ff78' => __DIR__ . '/..' . '/kriswallsmith/assetic/src/functions.php',
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
'6a47392539ca2329373e0d33e1dba053' => __DIR__ . '/..' . '/symfony/polyfill-intl-icu/bootstrap.php',
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
);
public static $prefixLengthsPsr4 = array (
@@ -37,6 +37,7 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
),
'T' =>
array (
'Twig\\Extensions\\' => 16,
'Twig\\' => 5,
'Tests\\' => 6,
),
@@ -109,6 +110,7 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
),
'F' =>
array (
'Fairlane\\CookieConsentBundle\\' => 29,
'FOS\\UserBundle\\' => 15,
'FOS\\ElasticaBundle\\' => 19,
),
@@ -156,6 +158,10 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
array (
0 => __DIR__ . '/..' . '/vimeo/vimeo-api/src/Vimeo',
),
'Twig\\Extensions\\' =>
array (
0 => __DIR__ . '/..' . '/twig/extensions/src',
),
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
@@ -282,8 +288,8 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
),
'Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/php-http/message-factory/src',
1 => __DIR__ . '/..' . '/php-http/message/src',
0 => __DIR__ . '/..' . '/php-http/message/src',
1 => __DIR__ . '/..' . '/php-http/message-factory/src',
),
'Http\\HttplugBundle\\' =>
array (
@@ -295,9 +301,9 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
),
'Http\\Client\\Common\\Plugin\\' =>
array (
0 => __DIR__ . '/..' . '/php-http/stopwatch-plugin/src',
0 => __DIR__ . '/..' . '/php-http/cache-plugin/src',
1 => __DIR__ . '/..' . '/php-http/logger-plugin/src',
2 => __DIR__ . '/..' . '/php-http/cache-plugin/src',
2 => __DIR__ . '/..' . '/php-http/stopwatch-plugin/src',
),
'Http\\Client\\Common\\' =>
array (
@@ -327,6 +333,10 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Fairlane\\CookieConsentBundle\\' =>
array (
0 => __DIR__ . '/..' . '/fairlane/cookie-consent-bundle',
),
'FOS\\UserBundle\\' =>
array (
0 => __DIR__ . '/..' . '/friendsofsymfony/user-bundle',
@@ -412,6 +422,10 @@ class ComposerStaticInit1b32d02bd8fea2d524bf79b36ada5830
public static $prefixesPsr0 = array (
'T' =>
array (
'Twig_Extensions_' =>
array (
0 => __DIR__ . '/..' . '/twig/extensions/lib',
),
'Twig_' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/lib',
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
Changelog
=========
### 1.0.2
* Fix hiding the cookie info div
* Update instructions
### 1.0.1
* Fix the composer dependencies
### 1.0.0
* Initial release
@@ -0,0 +1,46 @@
<?php
namespace Fairlane\CookieConsentBundle\Controller;
use Fairlane\CookieConsentBundle\Type\Constant;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class CookieController extends Controller
{
public function acceptAction()
{
$request = Request::createFromGlobals();
$content = json_decode($request->getContent(), true);
if (isset($content['cookie-consent']) && $content['cookie-consent'] == 'ok') {
$expires = new \DateTime("now");
$dateInterval = new \DateInterval(
sprintf(
'P%dD',
$this->getFairlaneParameter(Constant::BUNDLE_CONFIG_COOKIE_LIFETIME)
)
);
$expires->add($dateInterval);
$cookie = new Cookie(Constant::BUNDLE_COOKIE_NAME,'ok', $expires);
$jsonResponse = new JsonResponse(['success' => true]);
$jsonResponse->headers->setCookie($cookie);
return $jsonResponse;
} else {
return new JsonResponse(['success' => false], 400);
}
}
protected function getFairlaneParameter($key)
{
$params = $this->getParameter('fairlane_cookie_consent');
if (!empty($params[$key])) {
return $params[$key];
} else {
return null;
}
}
}
@@ -0,0 +1,46 @@
<?php
namespace Fairlane\CookieConsentBundle\DependencyInjection;
use Fairlane\CookieConsentBundle\Type\Constant;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root(Constant::BUNDLE_CONFIG_ROOT);
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.
$rootNode
->children()
->booleanNode(Constant::BUNDLE_CONFIG_BOOTSTRAP)->end()
->booleanNode(Constant::BUNDLE_CONFIG_ACTIVE)->end()
->booleanNode(Constant::BUNDLE_CONFIG_TRANSLATE)->end()
->booleanNode(Constant::BUNDLE_CONFIG_JQUERY)->end()
->integerNode(Constant::BUNDLE_CONFIG_COOKIE_LIFETIME)->end()
->arrayNode(Constant::BUNDLE_CONFIG_TWIG)
->children()
->scalarNode(Constant::BUNDLE_CONFIG_TEXT_INFO)->end()
->scalarNode(Constant::BUNDLE_CONFIG_TEXT_INFO_LINK)->end()
->scalarNode(Constant::BUNDLE_CONFIG_TEXT_ACCEPT_BUTTON)->end()
->scalarNode(Constant::BUNDLE_CONFIG_URL_ADDITIONAL_INFO)->end()
->end()
->end()
->end();
return $treeBuilder;
}
}
@@ -0,0 +1,29 @@
<?php
namespace Fairlane\CookieConsentBundle\DependencyInjection;
use Fairlane\CookieConsentBundle\Type\Constant;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class FairlaneCookieConsentExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$container->setParameter('fairlane_cookie_consent', $config);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
@@ -0,0 +1,9 @@
<?php
namespace Fairlane\CookieConsentBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class FairlaneCookieConsentBundle extends Bundle
{
}
@@ -0,0 +1,106 @@
Symfony 3 Cookie Consent bundle
Installation
============
Step 1: Install the bundle
--------------------------
The easiest way to install the bundle is by using composer.
```console
$ composer require fairlane/cookie-consent-bundle"
```
This command requires you to have Composer installed globally, as explained
in the [installation chapter](https://getcomposer.org/doc/00-intro.md)
of the Composer documentation.
Step 2: Enable the Bundle
-------------------------
Then, enable the bundle by adding it to the list of registered bundles
in the `app/AppKernel.php` file of your project:
```php
<?php
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
// ...
new Fairlane\CookieConsentBundle\FairlaneCookieConsentBundle(),
);
// ...
}
// ...
}
```
Step 3: Configure bundle
------------------------
This bundle has few simple configurations. To see the list configuration options run following command:
```console
$ bin/console config:dump-reference fairlane_cookie_consent
```
You must expose the `fairlane_cookie_consent.twig` service globally.
```yaml
twig:
// ...
globals:
// ...
fairlane_cookie_consent: '@fairlane_cookie_consent.twig'
```
Your config should look something like this.
```yaml
# Fairlane Cookie Consent configuration
fairlane_cookie_consent:
active: true
use_bootstrap: true
use_jquery: true
translate: false
cookie_lifetime: 365 # days
twig:
text_info: 'This site uses cookies for...'
text_accept_button: 'OK'
text_additional_info_link: 'Read more about our cookie policy from here'
url_additional_info: 'https://yourdomain/your-cookie-policy'
twig:
globals:
fairlane_cookie_consent: '@fairlane_cookie_consent.twig'
```
The routes must be imported as well. Add following route to your `routes.yml`
```yaml
fairlane_cookie_consent:
resource: "@FairlaneCookieConsentBundle/Resources/config/routing.yml"
```
Finally, include the twig template into your layout file.
```twig
{{ include('FairlaneCookieConsentBundle::cookie-info.html.twig') }}
```
Step 4: Style the cookie notification
-------------------------------------
The id of the div `fairlane-cookie-consent`. Feel free to style it as you please. If you set the `use_bootsrap` to true
the extension will add `navbar navbar-fixed-top` classes to the div and `btn btn-primary` classes to the button.
If you set `use_jquery` to `true` acceptance of cookies is sent via ajax call & the div fades out. Otherwise you need to
handle calling the `Cookie:accept` (route id: `fairlane_cookie_consent_accept`) by yourself. This route only accepts
POST requests.
ToDo
====
* Improve & enrich the instructions
@@ -0,0 +1,4 @@
fairlane_cookie_consent_accept:
path: /fairlane/cookie-consent/accept
defaults: { _controller: FairlaneCookieConsentBundle:Cookie:accept}
methods: [POST]
@@ -0,0 +1,4 @@
services:
fairlane_cookie_consent.twig:
class: Fairlane\CookieConsentBundle\Service\TwigService
arguments: ["%fairlane_cookie_consent%"]
@@ -0,0 +1,39 @@
{% if fairlane_cookie_consent.active == true and app.request.cookies.get('fairlane-cookie-consent') != 'ok'%}
{% if fairlane_cookie_consent.translate == true %}
{% set text_info = fairlane_cookie_consent.twig.text_info | trans %}
{% set text_additional_info_link = fairlane_cookie_consent.twig.text_additional_info_link | trans %}
{% set text_accept_button = fairlane_cookie_consent.twig.text_accept_button | trans %}
{% else %}
{% set text_info = fairlane_cookie_consent.twig.text_info %}
{% set text_additional_info_link = fairlane_cookie_consent.twig.text_additional_info_link %}
{% set text_accept_button = fairlane_cookie_consent.twig.text_accept_button %}
{% endif %}
<div id="fairlane-cookie-consent" {% if fairlane_cookie_consent.useBootstrap == true %}class="navbar navbar-fixed-top"{% endif %}>
<p>
{{ text_info }}
{% if fairlane_cookie_consent.twig.url_additional_info| length > 1 and text_additional_info_link | length > 1 %}
<a href="{{ fairlane_cookie_consent.twig.url_additional_info }}" target="_blank">{{ text_additional_info_link }}</a>
{% endif %}
</p>
<button {% if fairlane_cookie_consent.useBootstrap == true %}class="btn btn-primary"{% endif %}>{{ text_accept_button }}</button>
</div>
{% if fairlane_cookie_consent.useJquery %}
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#fairlane-cookie-consent button").click(function(){
jQuery.ajax({
async: true,
type: 'POST',
url: '{{ url('fairlane_cookie_consent_accept') }}',
data: JSON.stringify({'cookie-consent': 'ok'}),
success: function(data) {
jQuery("#fairlane-cookie-consent").fadeOut("fast");
},
contentType: "application/json",
dataType: 'json'
});
})
});
</script>
{% endif %}
{% endif %}
@@ -0,0 +1,69 @@
<?php
namespace Fairlane\CookieConsentBundle\Service;
use Fairlane\CookieConsentBundle\Type\Constant;
/**
* Class TwigService
*
* @package Auxilia\CoreBundle\Service
*/
class TwigService
{
/**
* Contains the injected configuration
*
* @var array
*/
private $config;
/**
* TwigService constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->config = $config;
}
/**
* @return array
*/
public function getTwig()
{
return $this->config['twig'];
}
/**
* @return boolean
*/
public function getUseBootstrap()
{
return $this->config[Constant::BUNDLE_CONFIG_BOOTSTRAP];
}
/**
* @return boolean
*/
public function getActive()
{
return $this->config[Constant::BUNDLE_CONFIG_ACTIVE];
}
/**
* @return boolean
*/
public function getTranslate()
{
return $this->config[Constant::BUNDLE_CONFIG_TRANSLATE];
}
/**
* @return boolean
*/
public function getUseJquery()
{
return $this->config[Constant::BUNDLE_CONFIG_JQUERY];
}
}
@@ -0,0 +1,17 @@
<?php
namespace Fairlane\CookieConsentBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DefaultControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
$crawler = $client->request('GET', '/');
$this->assertContains('Hello World', $client->getResponse()->getContent());
}
}
@@ -0,0 +1,24 @@
<?php
namespace Fairlane\CookieConsentBundle\Type;
/**
* This class has constants used by the bundle
*
*/
class Constant
{
const BUNDLE_CONFIG_ROOT = 'fairlane_cookie_consent';
const BUNDLE_CONFIG_BOOTSTRAP = 'use_bootstrap';
const BUNDLE_CONFIG_JQUERY = 'use_jquery';
const BUNDLE_CONFIG_TRANSLATE = 'translate';
const BUNDLE_CONFIG_COOKIE_LIFETIME = 'cookie_lifetime';
const BUNDLE_CONFIG_URL_ADDITIONAL_INFO = 'url_additional_info';
const BUNDLE_CONFIG_ACTIVE = 'active';
const BUNDLE_CONFIG_TWIG = 'twig';
const BUNDLE_CONFIG_TEXT_INFO = 'text_info';
const BUNDLE_CONFIG_TEXT_ACCEPT_BUTTON = 'text_accept_button';
const BUNDLE_CONFIG_TEXT_INFO_LINK = 'text_additional_info_link';
const BUNDLE_COOKIE_NAME = 'fairlane-cookie-consent';
}
@@ -0,0 +1,21 @@
{
"name": "fairlane/cookie-consent-bundle",
"type": "symfony-bundle",
"description": "EU Cookie Consent Bundle for Symfony",
"keywords": ["cookie", "cookie consent"],
"license": "WTFPL",
"require": {
"php": ">=7.0",
"twig/twig": ">=1.28",
"symfony/framework-bundle": ">=2.7",
"symfony/twig-bundle": ">=2.7"
},
"autoload": {
"psr-4": {
"Fairlane\\CookieConsentBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
}
}
@@ -33,6 +33,7 @@ final class Versions
'doctrine/orm' => 'dev-master@374e7ace49d864dad8cddbc55346447c8a6a2083',
'dunglas/doctrine-json-odm' => 'dev-master@067f38940d6424b272521192a38d69d6af87825a',
'evenement/evenement' => 'v1.1.0@e24176d20f6dab44dd4768b32c897f63b6f2b7c3',
'fairlane/cookie-consent-bundle' => '1.0.2@db2ca1c40a44e13c090406da6704b428d00dfd84',
'friendsofsymfony/elastica-bundle' => 'v4.1.1@b056b39abfe74a56cc79823ab5ddb0121270cec0',
'friendsofsymfony/user-bundle' => 'v2.0.2@2fc8a023d7ab482321cf7ec810ed49eab40eb50f',
'guzzlehttp/guzzle' => '6.3.0@f4db5a78a5ea468d4831de7f0bf9d9415e348699',
@@ -84,6 +85,7 @@ final class Versions
'symfony/polyfill-util' => 'v1.6.0@6e719200c8e540e0c0effeb31f96bdb344b94176',
'symfony/swiftmailer-bundle' => 'v2.6.7@c4808f5169efc05567be983909d00f00521c53ec',
'symfony/symfony' => 'v3.2.14@fc9f9470e81e6fb59bd826d8040b961f7ed30f94',
'twig/extensions' => 'v1.5.2@2c1a86526d0044065220d1b51ac08348bea5ca82',
'twig/twig' => 'v2.4.4@eddb97148ad779f27e670e1e3f19fb323aedafeb',
'vimeo/vimeo-api' => '1.3.0@46820e2d777362849137c1eb14f5cdb657c289ea',
'zendframework/zend-code' => '3.3.0@6b1059db5b368db769e4392c6cb6cc139e56640d',
@@ -0,0 +1,4 @@
phpunit.xml
vendor/
composer.lock
@@ -0,0 +1,34 @@
language: php
sudo: false
cache:
directories:
- vendor
- $HOME/.composer/cache/files
env:
- DEPS=no
before_install:
- phpenv config-rm xdebug.ini
before_script:
- if [ "$DEPS" == "low" ]; then composer --prefer-lowest --prefer-stable update; fi;
- if [ "$DEPS" == "no" ]; then composer install; fi;
script: |
./vendor/bin/simple-phpunit
matrix:
include:
- php: 5.3
dist: precise
- php: 5.4
- php: 5.5
- php: 5.6
env: DEPS=low
- php: 7.0
- php: 7.1
- php: 7.2
fast_finish: true
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2010-2017 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,14 @@
Twig Extensions Repository
==========================
This repository hosts Twig Extensions that do not belong to the core but can
be nonetheless interesting to share with other developers.
Fork this repository, add your extension, and request a pull.
More Information
----------------
Read the `documentation`_ for more information.
.. _documentation: http://twig-extensions.readthedocs.io/
@@ -0,0 +1,32 @@
{
"name": "twig/extensions",
"description": "Common additional features for Twig that do not directly belong in core",
"keywords": ["i18n","text"],
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"require": {
"twig/twig": "^1.27|^2.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3.4",
"symfony/translation": "^2.7|^3.4"
},
"suggest": {
"symfony/translation": "Allow the time_diff output to be translated"
},
"autoload": {
"psr-0": { "Twig_Extensions_": "lib/" },
"psr-4": { "Twig\\Extensions\\": "src/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
}
}
@@ -0,0 +1,14 @@
The Array Extension
===================
The Array extensions provides the following filters:
* ``shuffle``
Installation
------------
First, :ref:`install the Extensions library<extensions-install>`. Next, add
the extension to Twig::
$twig->addExtension(new Twig_Extensions_Extension_Array());
@@ -0,0 +1,41 @@
The Date Extension
===================
The *Date* extension provides the ``time_diff`` filter.
You need to register this extension before using the ``time_diff`` filter::
$twig->addExtension(new Twig_Extensions_Extension_Date());
``time_diff``
-------------
Use the ``time_diff`` filter to render the difference between a date and now.
.. code-block:: jinja
{{ post.published_at|time_diff }}
The example above will output a string like ``4 seconds ago`` or ``in 1 month``,
depending on the filtered date.
.. note::
Internally, Twig uses the PHP ``DateTime::diff()`` method for calculating the
difference between dates, this means that PHP 5.3+ is required.
Arguments
~~~~~~~~~
* ``date``: The date for calculate the difference from now. Can be a string
or a DateTime instance.
* ``now``: The date that should be used as now. Can be a string or
a DateTime instance. Do not set this argument to use current date.
Translation
~~~~~~~~~~~
To get a translatable output, give a ``Symfony\Component\Translation\TranslatorInterface``
as constructor argument. The returned string is formatted as ``diff.ago.XXX``
or ``diff.in.XXX`` where ``XXX`` can be any valid unit: second, minute, hour, day, month, year.
@@ -0,0 +1,191 @@
The i18n Extension
==================
Configuration
-------------
The ``i18n`` extension adds `gettext`_ support to Twig. It defines one tag,
``trans``.
To use it, first, :ref:`install the Extensions library<extensions-install>`.
You need to register this extension before using the ``trans`` block::
$twig->addExtension(new Twig_Extensions_Extension_I18n());
Note that you must configure the ``gettext`` extension before rendering any
internationalized template. Here is a simple configuration example from the
PHP `documentation`_::
// Set language to French
putenv('LC_ALL=fr_FR');
setlocale(LC_ALL, 'fr_FR');
// Specify the location of the translation tables
bindtextdomain('myAppPhp', 'includes/locale');
bind_textdomain_codeset('myAppPhp', 'UTF-8');
// Choose domain
textdomain('myAppPhp');
.. caution::
The ``i18n`` extension only works if the PHP `gettext`_ extension is
enabled.
Usage
-----
Use the ``trans`` block to mark parts in the template as translatable:
.. code-block:: jinja
{% trans "Hello World!" %}
{% trans string_var %}
{% trans %}
Hello World!
{% endtrans %}
In a translatable string, you can embed variables:
.. code-block:: jinja
{% trans %}
Hello {{ name }}!
{% endtrans %}
During the gettext lookup these placeholders are converted. ``{{ name }}`` becomes ``%name%`` so the gettext ``msgid`` for this string would be ``Hello %name%!``.
.. note::
``{% trans "Hello {{ name }}!" %}`` is not a valid statement.
If you need to apply filters to the variables, you first need to assign the
result to a variable:
.. code-block:: jinja
{% set name = name|capitalize %}
{% trans %}
Hello {{ name }}!
{% endtrans %}
To pluralize a translatable string, use the ``plural`` block:
.. code-block:: jinja
{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}
The ``plural`` tag should provide the ``count`` used to select the right
string. Within the translatable string, the special ``count`` variable always
contain the count value (here the value of ``apple_count``).
To add notes for translators, use the ``notes`` block:
.. code-block:: jinja
{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% notes %}
This is shown in the user menu. This string should be shorter than 30 chars
{% endtrans %}
You can use ``notes`` with or without ``plural``. Once you get your templates compiled you should
configure the ``gettext`` parser to get something like this: ``xgettext --add-comments=notes``
Within an expression or in a tag, you can use the ``trans`` filter to translate
simple strings or variables:
.. code-block:: jinja
{{ var|default(default_value|trans) }}
Complex Translations within an Expression or Tag
------------------------------------------------
Translations can be done with both the ``trans`` tag and the ``trans`` filter.
The filter is less powerful as it only works for simple variables or strings.
For more complex scenario, like pluralization, you can use a two-step
strategy:
.. code-block:: jinja
{# assign the translation to a temporary variable #}
{% set default_value %}
{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}
{% endset %}
{# use the temporary variable within an expression #}
{{ var|default(default_value|trans) }}
Extracting Template Strings
---------------------------
If you use the Twig I18n extension, you will probably need to extract the
template strings at some point.
Using Poedit 2
~~~~~~~~~~~~~~
Poedit 2 has native support for extracting from Twig files and no extra
setup is necessary (Pro version).
Using ``xgettext`` or Poedit 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unfortunately, the ``xgettext`` utility does not understand Twig templates
natively and neither do tools based on it such as free versions of Poedit.
But there is a simple workaround: as Twig converts templates to
PHP files, you can use ``xgettext`` on the template cache instead.
Create a script that forces the generation of the cache for all your
templates. Here is a simple example to get you started::
$tplDir = dirname(__FILE__).'/templates';
$tmpDir = '/tmp/cache/';
$loader = new Twig_Loader_Filesystem($tplDir);
// force auto-reload to always have the latest version of the template
$twig = new Twig_Environment($loader, array(
'cache' => $tmpDir,
'auto_reload' => true
));
$twig->addExtension(new Twig_Extensions_Extension_I18n());
// configure Twig the way you want
// iterate over all your templates
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tplDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
{
// force compilation
if ($file->isFile()) {
$twig->loadTemplate(str_replace($tplDir.'/', '', $file));
}
}
Use the standard ``xgettext`` utility as you would have done with plain PHP
code:
.. code-block:: text
xgettext --default-domain=messages -p ./locale --from-code=UTF-8 -n --omit-header -L PHP /tmp/cache/*.php
Another workaround is to use `Twig Gettext Extractor`_ and extract the template
strings right from `Poedit`_.
.. _`gettext`: http://www.php.net/gettext
.. _`documentation`: http://fr.php.net/manual/en/function.gettext.php
.. _`Twig Gettext Extractor`: https://github.com/umpirsky/Twig-Gettext-Extractor
.. _`Poedit`: http://www.poedit.net/
@@ -0,0 +1,39 @@
Twig Extensions
===============
.. toctree::
:hidden:
text
i18n
intl
array
date
The Twig Extensions is a library that provides several useful extensions
for Twig. You can find it's code at `GitHub.com/twigphp/Twig-extensions`_.
.. _extensions-install:
Installation
------------
This library can be installed via Composer running the following from the
command line:
.. code-block:: bash
composer require twig/extensions
* :doc:`Text <text>`: Provides useful filters for text manipulation;
* :doc:`I18n <i18n>`: Adds internationalization support via the ``gettext``
library;
* :doc:`Intl <intl>`: Adds a filter for localization of ``DateTime`` objects, numbers and currency;
* :doc:`Array <array>`: Provides useful filters for array manipulation;
* :doc:`Date <date>`: Adds a filter for rendering the difference between dates.
.. _`GitHub.com/twigphp/Twig-extensions`: https://github.com/twigphp/Twig-extensions
@@ -0,0 +1,160 @@
The Intl Extension
==================
The *Intl* extensions provides the ``localizeddate``, ``localizednumber`` and ``localizedcurrency`` filters.
Installation
------------
First, :ref:`install the Extensions library<extensions-install>`. Next, add
the extension to Twig::
$twig->addExtension(new Twig_Extensions_Extension_Intl());
``localizeddate``
-----------------
Use the ``localizeddate`` filter to format dates into a localized string
representating the date.
.. code-block:: jinja
{{ post.published_at|localizeddate('medium', 'none', locale) }}
The ``localizeddate`` filter accepts strings (it must be in a format supported
by the `strtotime`_ function), `DateTime`_ instances, or `Unix timestamps`_.
.. note::
Internally, Twig uses the PHP `IntlDateFormatter::create()`_ function for
the date.
Arguments
~~~~~~~~~
* ``date_format``: The date format. Choose one of these formats:
* 'none': `IntlDateFormatter::NONE`_
* 'short': `IntlDateFormatter::SHORT`_
* 'medium': `IntlDateFormatter::MEDIUM`_
* 'long': `IntlDateFormatter::LONG`_
* 'full': `IntlDateFormatter::FULL`_
* ``time_format``: The time format. Same formats possible as above.
* ``locale``: The locale used for the format. If ``NULL`` is given, Twig will
use ``Locale::getDefault()``
* ``timezone``: The date timezone
* ``format``: Optional pattern to use when formatting or parsing. Possible
patterns are documented in the `ICU user guide`_.
* ``calendar``: Calendar to use for formatting. The default value is 'gregorian',
which corresponds to IntlDateFormatter::GREGORIAN. Choose one of these formats:
* 'gregorian': `IntlDateFormatter::GREGORIAN`_
* 'traditional': `IntlDateFormatter::TRADITIONAL`_
For the following calendars should use 'traditional':
* Japanese
* Buddhist
* Chinese
* Persian
* Indian
* Islamic
* Hebrew
* Coptic
* Ethiopic
Also for non-Gregorian calendars need to be specified in locale.
Examples might include locale="fa_IR@calendar=PERSIAN".
``localizednumber``
-------------------
Use the ``localizednumber`` filter to format numbers into a localized string
representating the number.
.. code-block:: jinja
{{ product.quantity|localizednumber }}
.. note::
Internally, Twig uses the PHP `NumberFormatter::create()`_ function for
the number.
Arguments
~~~~~~~~~
* ``style``: Optional number format (default: 'decimal'). Choose one of these formats:
* 'decimal': `NumberFormatter::DECIMAL`_
* 'currency': `NumberFormatter::CURRENCY`_
* 'percent': `NumberFormatter::PERCENT`_
* 'scientific': `NumberFormatter::SCIENTIFIC`_
* 'spellout': `NumberFormatter::SPELLOUT`_
* 'ordinal': `NumberFormatter::ORDINAL`_
* 'duration': `NumberFormatter::DURATION`_
* ``type``: Optional formatting type to use (default: 'default'). Choose one of these types:
* 'default': `NumberFormatter::TYPE_DEFAULT`_
* 'int32': `NumberFormatter::TYPE_INT32`_
* 'int64': `NumberFormatter::TYPE_INT64`_
* 'double': `NumberFormatter::TYPE_DOUBLE`_
* 'currency': `NumberFormatter::TYPE_CURRENCY`_
* ``locale``: The locale used for the format. If ``NULL`` is given, Twig will
use ``Locale::getDefault()``
``localizedcurrency``
---------------------
Use the ``localizedcurrency`` filter to format a currency value into a localized string.
.. code-block:: jinja
{{ product.price|localizedcurrency('EUR') }}
.. note::
Internally, Twig uses the PHP `NumberFormatter::create()`_ function for
the number.
Arguments
~~~~~~~~~
* ``currency``: The 3-letter ISO 4217 currency code indicating the currency to use.
* ``locale``: The locale used for the format. If ``NULL`` is given, Twig will
use ``Locale::getDefault()``
.. _`strtotime`: http://php.net/strtotime
.. _`DateTime`: http://php.net/DateTime
.. _`Unix timestamps`: http://en.wikipedia.org/wiki/Unix_time
.. _`IntlDateFormatter::create()`: http://php.net/manual/en/intldateformatter.create.php
.. _`IntlDateFormatter::NONE`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.none
.. _`IntlDateFormatter::SHORT`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.short
.. _`IntlDateFormatter::MEDIUM`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.medium
.. _`IntlDateFormatter::LONG`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.long
.. _`IntlDateFormatter::FULL`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.full
.. _`IntlDateFormatter::GREGORIAN`: http://php.net/IntlDateFormatter#intldateformatter.constants.gregorian
.. _`IntlDateFormatter::TRADITIONAL`: http://php.net/IntlDateFormatter#intldateformatter.constants.traditional
.. _`ICU user guide`: http://userguide.icu-project.org/formatparse/datetime
.. _`NumberFormatter::create()`: http://php.net/manual/en/numberformatter.create.php
.. _`NumberFormatter::DECIMAL`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.decimal
.. _`NumberFormatter::CURRENCY`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.currency
.. _`NumberFormatter::PERCENT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.percent
.. _`NumberFormatter::SCIENTIFIC`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.scientific
.. _`NumberFormatter::SPELLOUT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.spellout
.. _`NumberFormatter::ORDINAL`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.ordinal
.. _`NumberFormatter::DURATION`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.duration
.. _`NumberFormatter::TYPE_DEFAULT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-default
.. _`NumberFormatter::TYPE_INT32`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-int32
.. _`NumberFormatter::TYPE_INT64`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-int64
.. _`NumberFormatter::TYPE_DOUBLE`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-double
.. _`NumberFormatter::TYPE_CURRENCY`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-currency
@@ -0,0 +1,76 @@
The Text Extension
==================
The Text extension provides the following filters:
* ``truncate``
* ``wordwrap``
Installation
------------
First, :ref:`install the Extensions library<extensions-install>`. Next, add
the extension to Twig::
$twig->addExtension(new Twig_Extensions_Extension_Text());
Wrapping Words
--------------
Use the ``wordwrap`` filter to split your text in lines with equal length.
.. code-block:: jinja
{{ "Lorem ipsum dolor sit amet, consectetur adipiscing"|wordwrap(10) }}
This example would print::
Lorem ipsu
m dolor si
t amet, co
nsectetur
adipiscing
The default separator is "\\n", but you can easily change that by providing one:
.. code-block:: jinja
{{ "Lorem ipsum dolor sit amet, consectetur adipiscing"|wordwrap(10, "zz\n") }}
This would result in::
Lorem ipsuzz
m dolor sizz
t amet, cozz
nsectetur zz
adipiscing
Truncating Text
---------------
Use the ``truncate`` filter to cut off a string after limit is reached
.. code-block:: jinja
{{ "Hello World!"|truncate(5) }}
The example would output ``Hello...``, as ``...`` is the default separator.
You can also tell truncate to preserve whole words by setting the second
parameter to ``true``. If the last Word is on the the separator, truncate
will print out the whole Word.
.. code-block:: jinja
{{ "Hello World!"|truncate(7, true) }}
Here ``Hello World!`` would be printed.
If you want to change the separator, just set the third parameter to
your desired separator.
.. code-block:: jinja
{{ "Hello World!"|truncate(7, false, "??") }}
This example would print ``Hello W??``.
@@ -0,0 +1,48 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The "Twig_Extensions_Autoloader" class is deprecated since version 1.5. Use Composer instead.', E_USER_DEPRECATED);
/**
* Autoloads Twig Extensions classes.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*
* @deprecated since version 1.5, use Composer instead.
*/
class Twig_Extensions_Autoloader
{
/**
* Registers Twig_Extensions_Autoloader as an SPL autoloader.
*/
public static function register()
{
spl_autoload_register(array(new self(), 'autoload'));
}
/**
* Handles autoloading of classes.
*
* @param string $class a class name
*
* @return bool Returns true if the class has been loaded
*/
public static function autoload($class)
{
if (0 !== strpos($class, 'Twig_Extensions')) {
return;
}
if (file_exists($file = __DIR__.'/../../'.str_replace('_', '/', $class).'.php')) {
require $file;
}
}
}
@@ -0,0 +1,56 @@
<?php
/**
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @author Ricard Clau <ricard.clau@gmail.com>
*/
class Twig_Extensions_Extension_Array extends Twig_Extension
{
/**
* {@inheritdoc}
*/
public function getFilters()
{
$filters = array(
new Twig_SimpleFilter('shuffle', 'twig_shuffle_filter'),
);
return $filters;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'array';
}
}
/**
* Shuffles an array.
*
* @param array|Traversable $array An array
*
* @return array
*/
function twig_shuffle_filter($array)
{
if ($array instanceof Traversable) {
$array = iterator_to_array($array, false);
}
shuffle($array);
return $array;
}
class_alias('Twig_Extensions_Extension_Array', 'Twig\Extensions\ArrayExtension', false);
@@ -0,0 +1,101 @@
<?php
/**
* This file is part of Twig.
*
* (c) 2014 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Component\Translation\TranslatorInterface;
/**
* @author Robin van der Vleuten <robinvdvleuten@gmail.com>
*/
class Twig_Extensions_Extension_Date extends Twig_Extension
{
public static $units = array(
'y' => 'year',
'm' => 'month',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
/**
* @var TranslatorInterface
*/
private $translator;
public function __construct(TranslatorInterface $translator = null)
{
$this->translator = $translator;
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new Twig_SimpleFilter('time_diff', array($this, 'diff'), array('needs_environment' => true)),
);
}
/**
* Filter for converting dates to a time ago string like Facebook and Twitter has.
*
* @param Twig_Environment $env a Twig_Environment instance
* @param string|DateTime $date a string or DateTime object to convert
* @param string|DateTime $now A string or DateTime object to compare with. If none given, the current time will be used.
*
* @return string the converted time
*/
public function diff(Twig_Environment $env, $date, $now = null)
{
// Convert both dates to DateTime instances.
$date = twig_date_converter($env, $date);
$now = twig_date_converter($env, $now);
// Get the difference between the two DateTime objects.
$diff = $date->diff($now);
// Check for each interval if it appears in the $diff object.
foreach (self::$units as $attribute => $unit) {
$count = $diff->$attribute;
if (0 !== $count) {
return $this->getPluralizedInterval($count, $diff->invert, $unit);
}
}
return '';
}
protected function getPluralizedInterval($count, $invert, $unit)
{
if ($this->translator) {
$id = sprintf('diff.%s.%s', $invert ? 'in' : 'ago', $unit);
return $this->translator->transChoice($id, $count, array('%count%' => $count), 'date');
}
if (1 !== $count) {
$unit .= 's';
}
return $invert ? "in $count $unit" : "$count $unit ago";
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'date';
}
}
class_alias('Twig_Extensions_Extension_Date', 'Twig\Extensions\DateExtension', false);
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Extensions_Extension_I18n extends Twig_Extension
{
/**
* {@inheritdoc}
*/
public function getTokenParsers()
{
return array(new Twig_Extensions_TokenParser_Trans());
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new Twig_SimpleFilter('trans', 'gettext'),
);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'i18n';
}
}
class_alias('Twig_Extensions_Extension_I18n', 'Twig\Extensions\I18nExtension', false);
@@ -0,0 +1,146 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Extensions_Extension_Intl extends Twig_Extension
{
public function __construct()
{
if (!class_exists('IntlDateFormatter')) {
throw new RuntimeException('The native PHP intl extension (http://php.net/manual/en/book.intl.php) is needed to use intl-based filters.');
}
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new Twig_SimpleFilter('localizeddate', 'twig_localized_date_filter', array('needs_environment' => true)),
new Twig_SimpleFilter('localizednumber', 'twig_localized_number_filter'),
new Twig_SimpleFilter('localizedcurrency', 'twig_localized_currency_filter'),
);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'intl';
}
}
function twig_localized_date_filter(Twig_Environment $env, $date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null, $calendar = 'gregorian')
{
$date = twig_date_converter($env, $date, $timezone);
$formatValues = array(
'none' => IntlDateFormatter::NONE,
'short' => IntlDateFormatter::SHORT,
'medium' => IntlDateFormatter::MEDIUM,
'long' => IntlDateFormatter::LONG,
'full' => IntlDateFormatter::FULL,
);
if (PHP_VERSION_ID < 50500) {
$formatter = IntlDateFormatter::create(
$locale,
$formatValues[$dateFormat],
$formatValues[$timeFormat],
$date->getTimezone()->getName(),
'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL,
$format
);
return $formatter->format($date->getTimestamp());
}
$formatter = IntlDateFormatter::create(
$locale,
$formatValues[$dateFormat],
$formatValues[$timeFormat],
IntlTimeZone::createTimeZone($date->getTimezone()->getName()),
'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL,
$format
);
return $formatter->format($date->getTimestamp());
}
function twig_localized_number_filter($number, $style = 'decimal', $type = 'default', $locale = null)
{
static $typeValues = array(
'default' => NumberFormatter::TYPE_DEFAULT,
'int32' => NumberFormatter::TYPE_INT32,
'int64' => NumberFormatter::TYPE_INT64,
'double' => NumberFormatter::TYPE_DOUBLE,
'currency' => NumberFormatter::TYPE_CURRENCY,
);
$formatter = twig_get_number_formatter($locale, $style);
if (!isset($typeValues[$type])) {
throw new Twig_Error_Syntax(sprintf('The type "%s" does not exist. Known types are: "%s"', $type, implode('", "', array_keys($typeValues))));
}
return $formatter->format($number, $typeValues[$type]);
}
function twig_localized_currency_filter($number, $currency = null, $locale = null)
{
$formatter = twig_get_number_formatter($locale, 'currency');
return $formatter->formatCurrency($number, $currency);
}
/**
* Gets a number formatter instance according to given locale and formatter.
*
* @param string $locale Locale in which the number would be formatted
* @param int $style Style of the formatting
*
* @return NumberFormatter A NumberFormatter instance
*/
function twig_get_number_formatter($locale, $style)
{
static $formatter, $currentStyle;
$locale = null !== $locale ? $locale : Locale::getDefault();
if ($formatter && $formatter->getLocale() === $locale && $currentStyle === $style) {
// Return same instance of NumberFormatter if parameters are the same
// to those in previous call
return $formatter;
}
static $styleValues = array(
'decimal' => NumberFormatter::DECIMAL,
'currency' => NumberFormatter::CURRENCY,
'percent' => NumberFormatter::PERCENT,
'scientific' => NumberFormatter::SCIENTIFIC,
'spellout' => NumberFormatter::SPELLOUT,
'ordinal' => NumberFormatter::ORDINAL,
'duration' => NumberFormatter::DURATION,
);
if (!isset($styleValues[$style])) {
throw new Twig_Error_Syntax(sprintf('The style "%s" does not exist. Known styles are: "%s"', $style, implode('", "', array_keys($styleValues))));
}
$currentStyle = $style;
$formatter = NumberFormatter::create($locale, $styleValues[$style]);
return $formatter;
}
class_alias('Twig_Extensions_Extension_Intl', 'Twig\Extensions\IntlExtension', false);
@@ -0,0 +1,99 @@
<?php
/**
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @author Henrik Bjornskov <hb@peytz.dk>
*/
class Twig_Extensions_Extension_Text extends Twig_Extension
{
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new Twig_SimpleFilter('truncate', 'twig_truncate_filter', array('needs_environment' => true)),
new Twig_SimpleFilter('wordwrap', 'twig_wordwrap_filter', array('needs_environment' => true)),
);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'Text';
}
}
if (function_exists('mb_get_info')) {
function twig_truncate_filter(Twig_Environment $env, $value, $length = 30, $preserve = false, $separator = '...')
{
if (mb_strlen($value, $env->getCharset()) > $length) {
if ($preserve) {
// If breakpoint is on the last word, return the value without separator.
if (false === ($breakpoint = mb_strpos($value, ' ', $length, $env->getCharset()))) {
return $value;
}
$length = $breakpoint;
}
return rtrim(mb_substr($value, 0, $length, $env->getCharset())).$separator;
}
return $value;
}
function twig_wordwrap_filter(Twig_Environment $env, $value, $length = 80, $separator = "\n", $preserve = false)
{
$sentences = array();
$previous = mb_regex_encoding();
mb_regex_encoding($env->getCharset());
$pieces = mb_split($separator, $value);
mb_regex_encoding($previous);
foreach ($pieces as $piece) {
while (!$preserve && mb_strlen($piece, $env->getCharset()) > $length) {
$sentences[] = mb_substr($piece, 0, $length, $env->getCharset());
$piece = mb_substr($piece, $length, 2048, $env->getCharset());
}
$sentences[] = $piece;
}
return implode($separator, $sentences);
}
} else {
function twig_truncate_filter(Twig_Environment $env, $value, $length = 30, $preserve = false, $separator = '...')
{
if (strlen($value) > $length) {
if ($preserve) {
if (false !== ($breakpoint = strpos($value, ' ', $length))) {
$length = $breakpoint;
}
}
return rtrim(substr($value, 0, $length)).$separator;
}
return $value;
}
function twig_wordwrap_filter(Twig_Environment $env, $value, $length = 80, $separator = "\n", $preserve = false)
{
return wordwrap($value, $length, $separator, !$preserve);
}
}
class_alias('Twig_Extensions_Extension_Text', 'Twig\Extensions\TextExtension', false);
@@ -0,0 +1,43 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
abstract class Twig_Extensions_Grammar implements Twig_Extensions_GrammarInterface
{
protected $name;
protected $parser;
/**
* @param string $name
*/
public function __construct($name)
{
$this->name = $name;
}
/**
* @param Twig_Parser $parser
*/
public function setParser(Twig_Parser $parser)
{
$this->parser = $parser;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Arguments extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s:arguments>', $this->name);
}
public function parse(Twig_Token $token)
{
return $this->parser->getExpressionParser()->parseArguments();
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Array extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s:array>', $this->name);
}
public function parse(Twig_Token $token)
{
return $this->parser->getExpressionParser()->parseArrayExpression();
}
}
@@ -0,0 +1,43 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Body extends Twig_Extensions_Grammar
{
protected $end;
public function __construct($name, $end = null)
{
parent::__construct($name);
$this->end = null === $end ? 'end'.$name : $end;
}
public function __toString()
{
return sprintf('<%s:body>', $this->name);
}
public function parse(Twig_Token $token)
{
$stream = $this->parser->getStream();
$stream->expect(Twig_Token::BLOCK_END_TYPE);
return $this->parser->subparse(array($this, 'decideBlockEnd'), true);
}
public function decideBlockEnd(Twig_Token $token)
{
return $token->test($this->end);
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Boolean extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s:boolean>', $this->name);
}
public function parse(Twig_Token $token)
{
$this->parser->getStream()->expect(Twig_Token::NAME_TYPE, array('true', 'false'));
return new Twig_Node_Expression_Constant('true' === $token->getValue() ? true : false, $token->getLine());
}
}
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Constant extends Twig_Extensions_Grammar
{
protected $type;
public function __construct($name, $type = null)
{
$this->name = $name;
$this->type = null === $type ? Twig_Token::NAME_TYPE : $type;
}
public function __toString()
{
return $this->name;
}
public function parse(Twig_Token $token)
{
$this->parser->getStream()->expect($this->type, $this->name);
return $this->name;
}
public function getType()
{
return $this->type;
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Expression extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s>', $this->name);
}
public function parse(Twig_Token $token)
{
return $this->parser->getExpressionParser()->parseExpression();
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Hash extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s:hash>', $this->name);
}
public function parse(Twig_Token $token)
{
return $this->parser->getExpressionParser()->parseHashExpression();
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @deprecated since version 1.5
*/
class Twig_Extensions_Grammar_Number extends Twig_Extensions_Grammar
{
public function __toString()
{
return sprintf('<%s:number>', $this->name);
}
public function parse(Twig_Token $token)
{
$this->parser->getStream()->expect(Twig_Token::NUMBER_TYPE);
return new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
}
}

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