Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 703ec9a1bb | |||
| 4a72e4dfe6 | |||
| 607f7706ca | |||
| b0b1179bdc | |||
| 0e2494797e | |||
| 69a7595966 | |||
| e404b4d876 | |||
| fa8b21b93c | |||
| 8e8312c0f9 | |||
| 0297191e07 | |||
| e64ce55b66 | |||
| eda0562edc | |||
| 01f5823885 | |||
| 9ed2745e8d | |||
| 82c4911770 | |||
| 8df9b7af43 | |||
| 71259c40c6 | |||
| 2dd559fa64 | |||
| 90ae12995f | |||
| 7aa4a92cb6 | |||
| 6a9b48d629 | |||
| 032d10bb50 | |||
| 7731dd2c23 | |||
| 8c6e8f14a4 | |||
| f1c795e8cd | |||
| 5dd437d939 | |||
| 59f6854379 | |||
| c2450d3929 | |||
| 2f626dbad5 | |||
| 8bccabbcf6 | |||
| 766335bb19 | |||
| 708e1f1c87 | |||
| 1d0e0e4c48 | |||
| a790f99adb | |||
| e98a2488eb | |||
| 8b7a79ef8d | |||
| 645cf1f05a | |||
| 974629794d | |||
| f23e906168 | |||
| 5a47ac168e | |||
| a35647ca1d | |||
| 231a692369 | |||
| 1ad2d8bf1a | |||
| 2047322161 | |||
| f90c907942 | |||
| a2d0a9539f | |||
| d5f448483c | |||
| 8f12cddd86 | |||
| 0f195907c5 | |||
| 8dabe7ba82 | |||
| 0bfed4b932 | |||
| bf875db942 | |||
| 5c47a00d0e | |||
| 0f8fe7732e | |||
| bed4cbc7b1 | |||
| b09ca38415 | |||
| c0f09f715c | |||
| 77d695f67a | |||
| 4cb07a74b6 | |||
| 43997a3493 | |||
| e6316504f1 | |||
| d8ac0993d6 | |||
| 67575e53e4 | |||
| 182a1b5078 | |||
| 4b9cd98266 | |||
| cf4e5020f5 |
+2
-1
@@ -6,4 +6,5 @@
|
||||
!/volume/www
|
||||
/volume/www/**/conf/nginx.conf
|
||||
/backup
|
||||
/conf/env/*.env
|
||||
/conf/env/*.env
|
||||
volume/www/website/.idea
|
||||
|
||||
@@ -4,7 +4,7 @@ services:
|
||||
|
||||
nginx:
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ../volume/www:/home/www:cached
|
||||
restart: "no"
|
||||
|
||||
@@ -16,7 +16,7 @@ server {
|
||||
|
||||
# DEV
|
||||
location / {
|
||||
try_files $uri /app_dev.php$is_args$args;
|
||||
try_files $uri /app.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ ^/(app_dev|config)\.php(/|$) {
|
||||
|
||||
@@ -36,7 +36,7 @@ server {
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
|
||||
location / {
|
||||
# try to serve file directly, fallback to app.php
|
||||
try_files $uri /app.php$is_args$args;
|
||||
@@ -58,6 +58,7 @@ server {
|
||||
# for more information).
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
fastcgi_param HTTPS on;
|
||||
}
|
||||
|
||||
# PROD
|
||||
@@ -78,6 +79,7 @@ server {
|
||||
# http://domain.tld/app.php/some-path
|
||||
# Remove the internal directive to allow URIs like this
|
||||
internal;
|
||||
fastcgi_param HTTPS on;
|
||||
}
|
||||
|
||||
# ---- PRESTASHOP ----
|
||||
|
||||
@@ -6,6 +6,21 @@ upstream store_php {
|
||||
server tt-website.store-php.prod:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name static.talentstube.com;
|
||||
|
||||
index index.html;
|
||||
root /home/www/website/www/web/uploads/;
|
||||
|
||||
access_log /home/www/website/log/access.log vhosts;
|
||||
error_log /home/www/website/log/error.log;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
|
||||
listen 80;
|
||||
@@ -13,7 +28,7 @@ server {
|
||||
|
||||
client_max_body_size 500M;
|
||||
|
||||
root /home/www/www.talentstube.com/www/web;
|
||||
root /home/www/website/www/web;
|
||||
|
||||
access_log /home/www/website/log/access.log vhosts;
|
||||
error_log /home/www/website/log/error.log;
|
||||
|
||||
@@ -44,6 +44,10 @@ class AppKernel extends Kernel
|
||||
new Edeclic\PrestashopBridgeBundle\EdeclicPrestashopBridgeBundle(),
|
||||
new Edeclic\HistoryBundle\EdeclicHistoryBundle(),
|
||||
new AppBundle\AppBundle(),
|
||||
|
||||
//oAuth
|
||||
new Http\HttplugBundle\HttplugBundle(),
|
||||
new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),
|
||||
];
|
||||
|
||||
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
|
||||
|
||||
+4
-4
@@ -38,20 +38,20 @@
|
||||
{{ form_row(form.plainPassword.second, {'label': 'Répéter le mot de passe'}) }}
|
||||
</div>
|
||||
</div>
|
||||
{% if destination_login is defined %}
|
||||
<input type="hidden" name="_target_path" value="{{ destination_login }}" />
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{% set label = 'user.cgu.label'|trans({'%link_start%' : '<a href="'~path('service_cgu')~'">', '%link_end%' : '</a>'}, 'messages') | raw %}
|
||||
{{ form_errors(form.cgu) }}
|
||||
{{ form_widget(form.cgu) }}
|
||||
{{ form_label(form.cgu) }}
|
||||
<br />
|
||||
{#{{ form_widget(form.cgu) }}
|
||||
{{ form_label(form.cgu) }}#}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<a href="{{ path('service_cgu') }}" title="conditions d'utilisations" style="margin-left:45px;">Lire les conditions générales d'utilisations</a>
|
||||
Lire les conditions générales d'utilisations</a>
|
||||
<br /><br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+71
-9
@@ -1,16 +1,78 @@
|
||||
{% block fos_user_content %}
|
||||
<div class="row">
|
||||
<div class="col s12 m12 l6 col-login-first col-login">
|
||||
<h4>Connexion</h4>
|
||||
<div class="row login_face active_face">
|
||||
<div class="col s12 col-login-first col-login">
|
||||
<h4 class="color-blue1 pull-left">Connexion</h4>
|
||||
<div class="pull-right">
|
||||
ou
|
||||
<a href="#" class="color-blue1 change_to_register">
|
||||
Créer un compte
|
||||
</a>
|
||||
</div>
|
||||
<br class="clearfix"/>
|
||||
{{ include('@FOSUser/Security/login_content.html.twig') }}
|
||||
</div>
|
||||
<div class="col s12 m12 l6 col-login-first col-login-subscribe hide-on-med-and-down">
|
||||
<div class="center-align">
|
||||
<strong>Je ne possède pas de<br />compte Talents Tube</strong>
|
||||
</div>
|
||||
<div class="row register_face">
|
||||
<div class="col s12 col-login-first col-login">
|
||||
<h4 class="color-blue1 pull-left">Créer un compte</h4>
|
||||
<div class="pull-right">
|
||||
ou
|
||||
<a href="#" class="color-blue1 change_to_login">
|
||||
Se connecter
|
||||
</a>
|
||||
</div>
|
||||
<a href="{{ path('fos_user_registration_register') }}" class="btn btn-default btn-round">
|
||||
Créer un compte
|
||||
</a>
|
||||
<br class="clearfix"/>
|
||||
{{ form_start(register_form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
|
||||
{{ form_errors(register_form) }}
|
||||
<div class="row">
|
||||
<div class="input-field col s6">
|
||||
{{ form_row(register_form.firstname, {'label': 'Prénom'}) }}
|
||||
</div>
|
||||
<div class="input-field col s6">
|
||||
{{ form_row(register_form.lastname, {'label': 'Nom'}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_row(register_form.email, {'label': 'E-mail'}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="hide">
|
||||
{{ form_row(register_form.username, {'label': 'Username'}) }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_row(register_form.plainPassword.first, {'label': 'Mot de passe'}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_row(register_form.plainPassword.second, {'label': 'Répéter le mot de passe'}) }}
|
||||
</div>
|
||||
</div>
|
||||
{% if destination_login is defined %}
|
||||
<input type="hidden" name="_target_path" value="{{ destination_login }}" />
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{% set label = 'user.cgu.label'|trans({'%link_start%' : '<a style="margin-bottom:25px;" target="_blank" href="'~path('service_cgu')~'">', '%link_end%' : '</a>'}, 'messages') | raw %}
|
||||
{{ form_errors(register_form.cgu) }}
|
||||
{{ form_widget(register_form.cgu) }}
|
||||
{% block form_label %}
|
||||
{% spaceless %}
|
||||
<label for="fos_user_registration_form_cgu">
|
||||
Je déclare avoir pris connaissance et accepté les termes et les <a target="_blank" href="{{ path("service_cgu") }}">conditions générales d’utilisation</a>
|
||||
</label>
|
||||
{% endspaceless %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-30">
|
||||
<div class="col s12 center-align">
|
||||
<input class="btn btn-default btn-round" type="submit" id="_submit_register" name="_submit_register" value="Créer un compte" />
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(register_form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock fos_user_content %}
|
||||
|
||||
+19
-23
@@ -1,5 +1,6 @@
|
||||
{% trans_default_domain 'FOSUserBundle' %}
|
||||
|
||||
{% include 'default/facebook.html.twig' %}
|
||||
{% if error %}
|
||||
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||
{% endif %}
|
||||
@@ -7,38 +8,33 @@
|
||||
{% if csrf_token %}
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="row field-login">
|
||||
<div class="input-field col s12">
|
||||
<label for="username">{{ 'security.login.username'|trans }}</label>
|
||||
<label for="username">e-mail</label>
|
||||
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row field-login">
|
||||
<div class="input-field col s12">
|
||||
<label for="password">{{ 'security.login.password'|trans }}</label>
|
||||
<input type="password" id="password" name="_password" required="required" />
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
|
||||
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
|
||||
</p>
|
||||
<br />
|
||||
<div class="row hide-on-large-only">
|
||||
<div class="col s6">
|
||||
<input class="btn btn-default btn-round" type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" /><br />
|
||||
<a href="{{path('fos_user_resetting_request')}}"><span class="tiny-text font-black m-l-10">J'ai oublié mon mot de passe</span></a>
|
||||
</div>
|
||||
<div class="col s6">
|
||||
<a href="{{ path('fos_user_registration_register') }}" class="btn btn-default btn-round">
|
||||
Créer un compte
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row hide-on-med-and-down">
|
||||
<div class="row field-login-checkbox">
|
||||
<div class="col s12">
|
||||
<input class="btn btn-default btn-round" type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" /><br />
|
||||
<a href="{{path('fos_user_resetting_request')}}"><span class="tiny-text font-black m-l-10">J'ai oublié mon mot de passe</span></a>
|
||||
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
|
||||
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
|
||||
<br class="clearfix"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<br />
|
||||
{% if destination_login is defined %}
|
||||
<input type="hidden" name="_target_path" value="{{ destination_login }}" />
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col s12 center-align">
|
||||
<input class="btn btn-default btn-round" type="submit" id="_submit" name="_submit" value="Se connecter" /><br />
|
||||
<a href="{{path('fos_user_resetting_request')}}"><span class="tiny-text font-black m-l-10">Mot de passe oublié ?</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
+10
-15
@@ -1,17 +1,12 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block urlCanonical %}
|
||||
#!
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h2 class="center-align">Page introuvable</h2>
|
||||
<p class="center-align">
|
||||
Cette page n'existe plus.<br/><br/>
|
||||
<a class="btn btn-default" href="{{ path('homepage') }}">Retour à l'accueil</a>
|
||||
</p>
|
||||
</div>
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h2 class="center-align m-t-100">Page introuvable</h2>
|
||||
<p class="center-align">
|
||||
Cette page n'existe plus.<br/><br/>
|
||||
<a class="btn btn-default" href="{{ path('homepage') }}">Retour à l'accueil</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -66,6 +66,10 @@
|
||||
title="Modifier">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a href="{{ path('admin_ad_refresh_img',{'id':ad.id}) }}" data-toggle="tooltip"
|
||||
title="Mise à jour image vimeo">
|
||||
<i class="fa fa-picture-o" aria-hidden="true"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<link rel="stylesheet" href="{{ asset('admin/AdminLTE/dist/css/AdminLTE.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ asset('admin/AdminLTE/dist/css/skins/skin-blue.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ asset('admin/AdminLTE/plugins/datatables/dataTables.bootstrap.css') }}">
|
||||
<link rel="stylesheet" href="{{ asset('admin/AdminLTE/plugins/datatables/dataTables.bootstrap.css') }}">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.2/jquery-confirm.min.css">
|
||||
<script type="text/javascript" defer="defer" src="https://extend.vimeocdn.com/ga/64189815.js"></script>
|
||||
|
||||
{% block css %}
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
style="margin-left: 5px;">
|
||||
<i class="fa fa-cart-plus" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a href="{{ path('admin_company_refresh_img',{'id':company.id}) }}" data-toggle="tooltip"
|
||||
title="Mise à jour image vimeo">
|
||||
<i class="fa fa-picture-o" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
|
||||
<a href="{{ path('company_dashboard',{'_switch_user':company.MainUser.username}) }}"
|
||||
data-toggle="tooltip" title="Se connecter avec ce compte"
|
||||
@@ -88,7 +92,7 @@
|
||||
"language": {
|
||||
"url": "https://cdn.datatables.net/plug-ins/1.10.11/i18n/French.json"
|
||||
},
|
||||
"order": [[1, 'desc']],
|
||||
"order": [[0, 'desc']],
|
||||
"columnDefs": [
|
||||
{"targets": 0, "searchable": true, "orderable": true},
|
||||
{"targets": 1, "searchable": true, "orderable": true},
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
{"targets": 4, "searchable": true, "orderable": true, "className": "text-center"},
|
||||
{"targets": 5, "searchable": false, "orderable": false, "className": "text-center"},
|
||||
],
|
||||
"order": [[1, "asc"]]
|
||||
"order": [[0, "desc"]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
{{ form_row(form.emphasisOrder) }}
|
||||
{{ form_row(form.brandName) }}
|
||||
{{ form_row(form.description) }}
|
||||
{{ form_row(form.descriptionAdmin) }}
|
||||
{{ form_row(form.website) }}
|
||||
{{ form_row(form.tagsComma) }}
|
||||
{{ form_row(form.file) }}
|
||||
@@ -60,11 +61,24 @@
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="{{ asset('codemirror/lib/codemirror.css') }}">
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
<script src="{{ asset('codemirror/lib/codemirror.js') }}"></script>
|
||||
<script src="{{ asset('codemirror/mode/xml/xml.js') }}"></script>
|
||||
<script src="{{ asset('codemirror/mode/javascript/javascript.js') }}"></script>
|
||||
<script src="{{ asset('codemirror/mode/css/css.js') }}"></script>
|
||||
<script src="{{ asset('codemirror/mode/vbscript/vbscript.js') }}"></script>
|
||||
<script src="{{ asset('codemirror/mode/htmlmixed/htmlmixed.js') }}"></script>
|
||||
<script>
|
||||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById('territory_admin_descriptionAdmin'), {
|
||||
lineNumbers: true,
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -100,7 +100,7 @@
|
||||
{"targets": 3, "searchable": true, "orderable": true, "className": "text-center"},
|
||||
{"targets": 4, "searchable": false, "orderable": false, "className": "text-center"},
|
||||
],
|
||||
"order": [[1, "asc"]]
|
||||
"order": [[0, "desc"]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
{% extends 'admin/base_admin.html.twig' %}
|
||||
|
||||
{% block contentHeader %}
|
||||
<h1>
|
||||
Utilisateurs
|
||||
<small>Liste</small>
|
||||
</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li>
|
||||
<a href="{{ path('admin_dashboard') }}">
|
||||
<i class="fa fa-dashboard"></i>
|
||||
Dashboard</a>
|
||||
</li>
|
||||
<li>Secret</li>
|
||||
<li class="active">Utilisateurs</li>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="box box-primary">
|
||||
<div class="box-body">
|
||||
<table id="user_list_table" class="table table-hover table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-2">Nom</th>
|
||||
<th class="col-md-2">Prénom</th>
|
||||
<th class="col-md-3">Email</th>
|
||||
<th class="col-md-1">Rôle</th>
|
||||
<th class="col-md-3">Etat</th>
|
||||
<th class="col-md-1">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
<td>{{ u.lastname }}</td>
|
||||
<td>{{ u.firstname }}</td>
|
||||
<td>{{ u.email }}</td>
|
||||
<td>
|
||||
{% for r in u.roles %}
|
||||
{% if r != "ROLE_USER" and r == "ROLE_TALENT" %}
|
||||
<span class="badge bg-blue" style="font-weight: 400;">{{ r }}</span>
|
||||
{% elseif r != "ROLE_USER" and r == "ROLE_COMPANY" %}
|
||||
<span class="badge bg-orange" style="font-weight: 400;">{{ r }}</span>
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if u.enabled %}
|
||||
Activé
|
||||
{% else %}
|
||||
Désactivé
|
||||
<br/>
|
||||
<a href="{{ path('admin_user_resend',{'id':u.id}) }}">Renvoyer le mail de confirmation</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="delete-user" href="{{ path('admin_user_delete',{'id':u.id}) }}" data-toggle="tooltip" title="Supprimer">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#user_list_table').DataTable({
|
||||
"paging": true,
|
||||
"lengthChange": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
"autoWidth": false,
|
||||
"language": {
|
||||
"url": "https://cdn.datatables.net/plug-ins/1.10.11/i18n/French.json"
|
||||
},
|
||||
"columnDefs": [
|
||||
{
|
||||
"targets": 0,
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
}, {
|
||||
"targets": 1,
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
}, {
|
||||
"targets": 2,
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
}, {
|
||||
"targets": 3,
|
||||
"searchable": true,
|
||||
"orderable": true,
|
||||
"className": "text-center"
|
||||
}, {
|
||||
"targets": 4,
|
||||
"searchable": false,
|
||||
"orderable": false,
|
||||
"className": "text-center"
|
||||
}, {
|
||||
"targets": 5,
|
||||
"searchable": false,
|
||||
"orderable": false,
|
||||
"className": "text-center"
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
$(".delete-user").confirm({
|
||||
title: "Êtes vous sûr de supprimer cet utilisateur ?",
|
||||
content: "Supprimer cet utilisateur supprimera, son compte, son entreprise, ses réponses, médias",
|
||||
type: 'red',
|
||||
boxWidth: '30%',
|
||||
useBootstrap: false,
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: 'Confirmer',
|
||||
action: function () {
|
||||
console.log(this.$target);
|
||||
location.href = this.$target.attr('href');
|
||||
return true;
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
text: 'Annuler'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,98 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block content %}
|
||||
{% if typeObject == 'Ad' %}
|
||||
{% set subtitle = 'Candidature à l\'offre d\'emploi:' %}
|
||||
{% set title = object.title %}
|
||||
{% set route = "answer_create_ad_step2" %}
|
||||
{% elseif typeObject == 'Company' %}
|
||||
{% set subtitle = 'Candidature pour l\'entreprise :' %}
|
||||
{% set title = object.brandName %}
|
||||
{% set route = "answer_create_company_step2" %}
|
||||
{% endif %}
|
||||
<div class="fluid-container bg-grey-3">
|
||||
<div class="container contentWrapper contentPage" id="answerPage">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="center-align bg-grey-3 m-t-20">
|
||||
<strong>{{ subtitle }}</strong>
|
||||
<h3 class="color-blue1 m-t-10">{{ title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content bg-arrow z-depth-2 p-20">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">1</span> Importez votre CV Vidéo</h4>
|
||||
</div>
|
||||
<div class="col s10 offset-s1 answer-dropzone">
|
||||
{% include 'media/dropzone.html.twig' with {'deleting': true } %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_start(form, {'attr': { 'id': 'form_media' } }) }}
|
||||
<div class="col-content z-depth-2 p-20 m-t-40">
|
||||
{{ form_row(form.status) }}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">2</span> Ajoutez votre commentaire</h4>
|
||||
</div>
|
||||
<div class="col s10 offset-s1">
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_errors(form.comment) }}
|
||||
{{ form_widget(form.comment) }}
|
||||
{{ form_label(form.comment) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
</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">
|
||||
Envoyer ma candidature
|
||||
</button><br /><br />
|
||||
<a class="color-grey5" href="{{ path(routeObject,{'alias': object.alias }) }}">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'answer/answer_tuto.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script type="text/javascript">
|
||||
var routeComment = '{{ path("anwser_edit_comment", {"id": answer.getId()}) }}';
|
||||
var urlDropzone = '{{ path("upload_media_answer", {"id": answer.getId()}) }}';
|
||||
var urlDelete = '{{ path("delete_media_answer", {"id": answer.getId() }) }}'
|
||||
var idObject = '{{ answer.getId() }}';
|
||||
var typeObject = "answer";
|
||||
{% if video %}
|
||||
if($("#form_media").length){
|
||||
$("#submit").removeClass('disabled');
|
||||
$("#submit").addClass('pulse');
|
||||
}
|
||||
var videoExist = true;
|
||||
var videoOriginal = "{{video.getOriginalUrl()}}";
|
||||
var mockFile = { name: '{{video.getTitle()}}', size: '181818181', type: 'mp4', serverID: 0, accepted: true };
|
||||
{% else %}
|
||||
var videoExist = false;
|
||||
{% endif %}
|
||||
</script>
|
||||
<script src="{{ asset('/js/dropzone.js') }}"></script>
|
||||
<script src="{{ asset('/js/answer.js') }}"></script>
|
||||
<script type="text/javascript">
|
||||
{% if mustLogin == true %}
|
||||
$('#submit').on('click',function(event){
|
||||
event.preventDefault();
|
||||
$('#modal_login').modal('open');
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,55 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block content %}
|
||||
{% if typeObject == 'Ad' %}
|
||||
{% set subtitle = 'Candidature à l\'offre d\'emploi:' %}
|
||||
{% set title = object.title %}
|
||||
{% set route = "answer_create_ad_step2" %}
|
||||
{% elseif typeObject == 'Company' %}
|
||||
{% set subtitle = 'Candidature pour l\'entreprise :' %}
|
||||
{% set title = object.brandName %}
|
||||
{% set route = "answer_create_company_step2" %}
|
||||
{% endif %}
|
||||
|
||||
<div class="fluid-container bg-grey-3">
|
||||
<div class="container contentWrapper contentPage">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content center-align m-t-20">
|
||||
<strong>{{ subtitle }}</strong>
|
||||
<h3 class="color-blue1 m-0 m-t-10">{{ title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12 m6 ">
|
||||
<div class="col-content p-15 bg-blue-1 center-align whiteColor z-depth-2 choice-answer-item">
|
||||
<img src="{{ asset('img/img_popupcv/webcam_cv_video.svg')}}">
|
||||
<h3>J'enregistre mon CV vidéo !</h3>
|
||||
<p>Suivez nos conseils puis enregistrez votre CV vidéo directement depuis votre webcam.</p>
|
||||
<a href="{{ path(route,{'id': object.id,'type': 'webcam' }) }}" class="btn btn-default white">Enregistrer mon CV vidéo</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<div class="col-content p-15 center-align z-depth-2 choice-answer-item bg-white">
|
||||
<img src="{{ asset('img/img_popupcv/videotheque_cv_video.svg')}}">
|
||||
<h3>Je possède un CV vidéo !</h3>
|
||||
<p>Importez une vidéo ou séléctionnez une vidéo<br /> dans votre vidéothèque</p>
|
||||
<a href="{{ path(route,{'id': object.id, 'type': 'import'}) }}" class="btn btn btn-default">Importer mon CV vidéo</a><br /><br />
|
||||
<a id="link-videotheque" href="{{ route_videotheque }}">Choisir une vidéo de ma vidéothèque</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script type="text/javascript">
|
||||
{% if mustLogin == true %}
|
||||
$('#link-videotheque').on('click',function(event){
|
||||
event.preventDefault();
|
||||
$('#modal_login').modal('open');
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,131 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block content %}
|
||||
{% if typeObject == 'Ad' %}
|
||||
{% set subtitle = 'Candidature à l\'offre d\'emploi:' %}
|
||||
{% set title = object.title %}
|
||||
{% set route = "answer_create_ad_step2" %}
|
||||
{% elseif typeObject == 'Company' %}
|
||||
{% set subtitle = 'Candidature pour l\'entreprise :' %}
|
||||
{% set title = object.brandName %}
|
||||
{% set route = "answer_create_company_step2" %}
|
||||
{% endif %}
|
||||
<div class="fluid-container bg-grey-3">
|
||||
<div class="container contentWrapper contentPage" id="answerPage">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="center-align bg-grey-3 m-t-20">
|
||||
<strong>{{ subtitle }}</strong>
|
||||
<h3 class="color-blue1 m-t-10">{{ title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content bg-arrow z-depth-2 p-20">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">1</span> Selectionnez votre CV vidéo</h4>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="row">
|
||||
<div class="col s10 offset-s1">
|
||||
<div class="p-30">
|
||||
{% for vid in videos %}
|
||||
{% set img = "" %}
|
||||
{% if vid.thumbnails.0 is defined %}
|
||||
{% set img = vid.thumbnails.0.sizes.4.link %}
|
||||
{% endif %}
|
||||
<div class="col s4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe src="https://player.vimeo.com{{ vid.getCdnUrl()|replace({ "videos": "video"}) }}" width="100%" height="auto" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div style="cursor:pointer;" class="card-action" data-url="https://player.vimeo.com{{ vid.getCdnUrl()|replace({ "videos": "video"}) }}" data-img="{{ img }}" data-position="top" data-tooltip="Choisir cette vidéo" href="#" data-title="{{ vid.getTitle() }}" data-id="{{ vid.getId() }}">
|
||||
<a class="addExistingVideo" >
|
||||
<span>{{ vid.getTitle() }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_start(form, {'attr': { 'id': 'form_media' } }) }}
|
||||
<div class="col-content z-depth-2 p-20 m-t-40">
|
||||
{{ form_row(form.status) }}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">2</span> Ajoutez votre commentaire</h4>
|
||||
</div>
|
||||
<div class="col s10 offset-s1">
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_errors(form.comment) }}
|
||||
{{ form_widget(form.comment) }}
|
||||
{{ form_label(form.comment) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
</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">
|
||||
Envoyer ma candidature
|
||||
</button><br /><br />
|
||||
<a class="color-grey5" href="{{ path(routeObject,{'alias': object.alias }) }}">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'answer/answer_tuto.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script src="{{ asset('/js/answer.js') }}"></script>
|
||||
<script type="text/javascript">
|
||||
{% if mustLogin == true %}
|
||||
$('#submit').on('click',function(event){
|
||||
event.preventDefault();
|
||||
$('#modal_login').modal('open');
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(".card-action").click(function(){
|
||||
var idVideo = $(this).data("id");
|
||||
var titleVideo = $(this).data("title");
|
||||
var imgVideo = $(this).data("img");
|
||||
var urlVideo = $(this).data("url");
|
||||
var elem = $(this);
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '{{ path("link_media_answer", {"id": answer.getId()}) }}',
|
||||
data: "idVideo="+idVideo,
|
||||
dataType: 'html',
|
||||
success: function (response) {
|
||||
$(".card-action").removeClass('active');
|
||||
elem.addClass('active');
|
||||
Materialize.toast('Vidéo bien associé', 4000);
|
||||
if($("#submit").hasClass('disabled')){
|
||||
$("#submit").removeClass('disabled');
|
||||
$("#submit").addClass('pulse');
|
||||
}
|
||||
},
|
||||
error: function (response, xhr, ajaxOptions, thrownError) {
|
||||
Materialize.toast('Erreur lors de l\'association de la vidéo!', 4000);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,138 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block content %}
|
||||
{% if typeObject == 'Ad' %}
|
||||
{% set subtitle = 'Candidature à l\'offre d\'emploi:' %}
|
||||
{% set title = object.title %}
|
||||
{% set route = "answer_create_ad_step2" %}
|
||||
{% elseif typeObject == 'Company' %}
|
||||
{% set subtitle = 'Candidature pour l\'entreprise :' %}
|
||||
{% set title = object.brandName %}
|
||||
{% set route = "answer_create_company_step2" %}
|
||||
{% endif %}
|
||||
<div class="fluid-container bg-grey-3">
|
||||
<div class="container contentWrapper contentPage" id="answerPage">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="center-align bg-grey-3 m-t-20">
|
||||
<strong>{{ subtitle }}</strong>
|
||||
<h3 class="color-blue1 m-t-10">{{ title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content bg-arrow z-depth-2 p-20">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">1</span> Enregistrez votre cv vidéo</h4>
|
||||
</div>
|
||||
<div class="col m4 offset-m1 s12">
|
||||
<video id="myCvVideo" class="video-js vjs-default-skin"></video>
|
||||
<div class="video-informations-card center-align">
|
||||
<p>Merci de cliquer sur l'icône <span class="vjs-icon-device-perm"></span> afin d'activer votre webcam.</p>
|
||||
<p>Votre webcam activée, lancez l'enregistrement en cliquant sur le bouton rond en bas à gauche du lecteur.</p>
|
||||
<p>Si vous n'êtes pas satisfait(e) de votre CV vidéo après un enregistrement, vous pouvez à tout moment recommencer l'enregistrement.</p>
|
||||
<p><a class="view-tuto">Revoir le tutoriel</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m2 hide-on-small-only">
|
||||
<div class="valign-wrapper" style="align-items:center;justify-content: center;height: 300px;width:100%;">
|
||||
<div style="font-size:40px;">
|
||||
<i class="fa fa-arrow-right center-align" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m4 s12">
|
||||
<video id="preview" controls="true">
|
||||
<span class="vjs-control-text">Play Video</span>
|
||||
</video>
|
||||
<div class="btnContainer center-align" style="display:none;">
|
||||
<a id="saveRecord" href="#!" class="saveVideo btn btn-default">
|
||||
<i class="fa fa-floppy-o" aria-hidden="true"></i> Télécharger mon CV Vidéo
|
||||
</a>
|
||||
<div class="video-informations-card">
|
||||
<p>Une fois téléchargé vous pouvez glisser-déposer votre CV vidéo dans la zone prévue pour lancer le téléchargement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-content bg-arrow z-depth-2 p-20">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">2</span> Importez votre CV Vidéo</h4>
|
||||
</div>
|
||||
<div class="col s10 offset-s1 answer-dropzone">
|
||||
{% include 'media/dropzone.html.twig' with {'deleting': true } %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_start(form, {'attr': { 'id': 'form_media' } }) }}
|
||||
<div class="col-content z-depth-2 p-20 m-t-40">
|
||||
{{ form_row(form.status) }}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h4 class="color-blue1 p-0"><span class="title-bubble">3</span> Ajoutez votre commentaire</h4>
|
||||
</div>
|
||||
<div class="col s10 offset-s1">
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_errors(form.comment) }}
|
||||
{{ form_widget(form.comment) }}
|
||||
{{ form_label(form.comment) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
</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">
|
||||
Envoyer ma candidature
|
||||
</button><br /><br />
|
||||
<a class="color-grey5" href="{{ path(routeObject,{'alias': object.alias }) }}">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'answer/answer_tuto.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script type="text/javascript">
|
||||
var routeComment = '{{ path("anwser_edit_comment", {"id": answer.getId()}) }}';
|
||||
var urlDropzone = '{{ path("upload_media_answer", {"id": answer.getId()}) }}';
|
||||
var urlDelete = '{{ path("delete_media_answer", {"id": answer.getId() }) }}'
|
||||
var idObject = '{{ answer.getId() }}';
|
||||
var typeObject = "answer";
|
||||
{% if video %}
|
||||
if($("#form_media").length){
|
||||
$("#submit").removeClass('disabled');
|
||||
$("#submit").addClass('pulse');
|
||||
}
|
||||
var videoExist = true;
|
||||
var videoOriginal = "{{video.getOriginalUrl()}}";
|
||||
var mockFile = { name: '{{video.getTitle()}}', size: '181818181', type: 'mp4', serverID: 0, accepted: true };
|
||||
{% else %}
|
||||
var videoExist = false;
|
||||
{% endif %}
|
||||
</script>
|
||||
<script src="{{ asset('/js/dropzone.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/video.min.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/RecordRTC.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/videojs.record.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/jquery.browser.min.js') }}"></script>
|
||||
<script src="{{ asset('/js/answer.js') }}"></script>
|
||||
<script type="text/javascript">
|
||||
{% if mustLogin == true %}
|
||||
$('#submit').on('click',function(event){
|
||||
event.preventDefault();
|
||||
$('#modal_login').modal('open');
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,84 @@
|
||||
<div id="modal-tuto" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content">
|
||||
<h3 class="color-blue1 center-align">Les conseils de Talents Tube</h3>
|
||||
<div class="owl-carousel tuto-carousel">
|
||||
<div class="item-tuto-webcam carousel-item">
|
||||
<div class="row">
|
||||
<div class="col s4 offset-s1 hide-on-med-and-down">
|
||||
<img class="responsive-img" src="{{ asset('img/img_popupcv/cv_video_step_1.svg')}}" alt="">
|
||||
</div>
|
||||
<div class="col s11 m11 l6 offset-s1 left-align">
|
||||
<strong><span class="color-blue1">30 Minutes</span> avant l’enregistrement</strong>
|
||||
<br /><br />
|
||||
<u>Préparez un discours <strong>clair</strong> et <strong>concis</strong></u>
|
||||
<br /><br />
|
||||
<strong>Posez-vous les bonnes questions : <br />
|
||||
<ul>
|
||||
<li>Quelle est ma situation ? </li>
|
||||
<li>Quelles sont mes compétences ?</li>
|
||||
<li>Que puis-je apporter à l’entreprise? </li>
|
||||
<li>Pourquoi je souhaite rejoindre l’entreprise?</li>
|
||||
</ul>
|
||||
</strong>
|
||||
Une fois votre scénario terminé, <strong>répétez-le plusieurs fois à voix haute pour maîtriser votre sujet.</strong>
|
||||
<br /><br />
|
||||
N’oubliez pas qu’en vidéo, <strong>il faut rester soi même !</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-tuto-webcam carousel-item">
|
||||
<div class="row">
|
||||
<div class="col s4 offset-s1 hide-on-med-and-down">
|
||||
<img class="responsive-img" src="{{ asset('img/img_popupcv/cv_video_step_2.svg')}}" alt="">
|
||||
</div>
|
||||
<div class="col s11 m11 l6 offset-s1 left-align">
|
||||
<strong><span class="color-blue1">2 Minutes</span> avant l’enregistrement</strong>
|
||||
<br /><br />
|
||||
<u>Préparer votre lieu de tournage :</u>
|
||||
<br /><br />
|
||||
<ul>
|
||||
<li>Privilégiez un fond <strong>neutre</strong> et <strong>clair</strong></li>
|
||||
<li>Trouvez un lieu <strong>peu bruyant</strong></li>
|
||||
<li>Installez-vous dans un endroit <strong>bien éclairé de préférence naturel, sans contre jour</strong></li>
|
||||
<li>Portez des <strong>habits de couleurs neutres et évitez les rayures, les pois et les carreaux.</strong></li>
|
||||
<li>Privilégiez un <strong>cadrage au niveau du buste</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-tuto-webcam carousel-item">
|
||||
<div class="row">
|
||||
<div class="col s4 offset-s1 hide-on-med-and-down">
|
||||
<img class="responsive-img" src="{{ asset('img/img_popupcv/cv_video_step_3.svg')}}" alt="">
|
||||
</div>
|
||||
<div class="col s11 m11 l6 offset-s1 left-align">
|
||||
<strong><span class="color-blue1">10 secondes</span> avant l’enregistrement</strong>
|
||||
<br /><br />
|
||||
<u>Quelques informations à savoir avant le grand bain :</u>
|
||||
<br /><br />
|
||||
<strong>
|
||||
<ul>
|
||||
<li>Le CV doit durer entre 1.30 et 2 minutes.</li>
|
||||
<li>Pensez à bien articuler.</li>
|
||||
<li>Évitez les euuuh et les baaah !</li>
|
||||
<li>Recommencez autant de fois que nécessaire.</li>
|
||||
</ul>
|
||||
<br /><br />
|
||||
C’est à vous !
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-fixed-item right">
|
||||
<a class="text close-tuto">Passer l'intro</a>
|
||||
<a class="btn btn-default next-slide">suivant</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,26 +30,28 @@
|
||||
{% endblock %}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
{# OG et TC #}
|
||||
{% block ogtc %}
|
||||
{#Twitter Card data pour les données enrichies sur Twitter#}
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@TalentsTube">
|
||||
<meta name="twitter:title" content="Talents Tube : Le 1er job board 100% vidéo">
|
||||
<meta name="twitter:description" content="Talents Tube est la première plateforme réservée aux offres d'emploi et aux CV vidéos. Découvrez un nouvelle méthode de recrutement !">
|
||||
<meta name="twitter:image" content="{{ absolute_url(asset('img/mail/logo-talents-tube.png')) }}">
|
||||
{% if app.request.attributes.get('_route') != null %}
|
||||
{% block ogtc %}
|
||||
{#Twitter Card data pour les données enrichies sur Twitter#}
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@TalentsTube">
|
||||
<meta name="twitter:title" content="Talents Tube : Le 1er job board 100% vidéo">
|
||||
<meta name="twitter:description" content="Talents Tube est la première plateforme réservée aux offres d'emploi et aux CV vidéos. Découvrez un nouvelle méthode de recrutement !">
|
||||
<meta name="twitter:image" content="{{ absolute_url(asset('img/mail/logo-talents-tube.png')) }}">
|
||||
|
||||
{#Open Graph data pour le partage sur les réseaux sociaux (ex Facebook..)#}
|
||||
<meta property="og:title" content="Talents Tube : Le 1er job board 100% vidéo" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:image" content="{{ absolute_url(asset('img/mail/logo-talents-tube.png')) }}" />
|
||||
<meta property="og:description" content="Talents Tube est la première plateforme réservée aux offres d'emploi et aux CV vidéos. Découvrez un nouvelle méthode de recrutement !" />
|
||||
<meta property="og:site_name" content="Talents Tube" />
|
||||
<meta property="og:url" content="{{ url(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}" />
|
||||
{#Open Graph data pour le partage sur les réseaux sociaux (ex Facebook..)#}
|
||||
<meta property="og:title" content="Talents Tube : Le 1er job board 100% vidéo" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:image" content="{{ absolute_url(asset('img/mail/logo-talents-tube.png')) }}" />
|
||||
<meta property="og:description" content="Talents Tube est la première plateforme réservée aux offres d'emploi et aux CV vidéos. Découvrez un nouvelle méthode de recrutement !" />
|
||||
<meta property="og:site_name" content="Talents Tube" />
|
||||
<meta property="og:url" content="{{ url(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}" />
|
||||
|
||||
{% endblock %}
|
||||
{# Canonical #}
|
||||
<link rel="canonical"
|
||||
href="{% block urlCanonical %}{{ url(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}{% endblock %}">
|
||||
{% endblock %}
|
||||
{# Canonical #}
|
||||
<link rel="canonical"
|
||||
href="{% block urlCanonical %}{{ url(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}{% endblock %}">
|
||||
{% endif %}
|
||||
{# CSS #}
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Raleway:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&subset=latin-ext"
|
||||
@@ -58,6 +60,7 @@
|
||||
<link rel="stylesheet" href="{{ asset('css/styles.css') }}">
|
||||
{% block stylesheets %}
|
||||
{% endblock %}
|
||||
<script type="text/javascript"> window.$crisp=[];window.CRISP_WEBSITE_ID="78ec5756-1cd5-4f3f-b0db-cb408c8171da";(function(){ d=document;s=d.createElement("script"); s.src="https://client.crisp.chat/l.js"; s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})(); </script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
|
||||
{% block dashContent %}
|
||||
<div class="row bg-bordered p-20">
|
||||
{% include 'company/tabs.html.twig' with {'tab':2} %}
|
||||
|
||||
{% if type == "spontaneous" %}
|
||||
{% include 'company/tabs.html.twig' with {'tab':3} %}
|
||||
{% else %}
|
||||
{% include 'company/tabs.html.twig' with {'tab':2} %}
|
||||
{% endif %}
|
||||
|
||||
<div id="reponses" class="col s12">
|
||||
<table id="table-answers" class="bordered highlight responsive-table">
|
||||
<thead>
|
||||
@@ -20,7 +26,7 @@
|
||||
<td>
|
||||
<a href="{{ path('company_answer_show',{'id':answer.id }) }}">{{ answer.user.firstname }} {{ answer.user.lastname }}</a>
|
||||
</td>
|
||||
<td>{{ answer.ad.title }}</td>
|
||||
<td>{% if answer.ad != null %}{{ answer.ad.title }} {% endif %}</td>
|
||||
<td>{{ answer.cTime()|date('d-m-Y') }}</td>
|
||||
<td>
|
||||
{#{% if answer.notes|length <= 0 %}#}
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
{% block dashContent %}
|
||||
<div class="row bg-bordered p-20">
|
||||
<h1 class="alttitle">Réponse de {{ answer.user.firstname }} {{ answer.user.lastname }}</h1>
|
||||
{% include 'company/tabs.html.twig' with {'tab':2} %}
|
||||
{% if type == "spontaneous" %}
|
||||
{% include 'company/tabs.html.twig' with {'tab':3} %}
|
||||
{% else %}
|
||||
{% include 'company/tabs.html.twig' with {'tab':2} %}
|
||||
{% endif %}
|
||||
|
||||
<div class="col s12 m6 l6 col-padding-right">
|
||||
<div class="bg-bordered inside-m">
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% include 'default/flash_message.html.twig' %}
|
||||
<div class="fluid-container bg-grey-3">
|
||||
<div class="container">
|
||||
<div id="detail-offre-video" class="row">
|
||||
@@ -89,6 +90,16 @@
|
||||
<p class="chip">{{ tag }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="col s12 m-t-20 ">
|
||||
{% if not is_granted('ROLE_COMPANY') %}
|
||||
<p class="item-detail-reply center-align">
|
||||
<a href="{{ path('talent_spontaneous_application_create',{'id': company.id}) }}"
|
||||
class="btn btn-default">
|
||||
Candidature spontanée
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="offers" class="row">
|
||||
@@ -107,6 +118,37 @@
|
||||
{% if company.territories|length %}
|
||||
{% include 'ad/carrousel_territory.html.twig' with {'territories': company.territories } %}
|
||||
{% endif %}
|
||||
|
||||
{% set popup_answer_send = app.session.flashbag.get('popup_answer_send') %}
|
||||
{% set popup_answer_already_send = app.session.flashbag.get('popup_answer_already_send') %}
|
||||
{% if popup_answer_send is not empty %}
|
||||
{% if popup_answer_send[0] == true %}
|
||||
<div id="modal-answer" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content p-30">
|
||||
{% if popup_answer_already_send is not empty and popup_answer_already_send[0] == true %}
|
||||
<h3 class="color-blue1 center-align">Votre candidature a bien été envoyée à {{ company.brandname }} !</h3>
|
||||
<div class="col offset-s2 s8 center-align">
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<div class="col s12">
|
||||
<iframe src="https://player.vimeo.com/video/249822507"
|
||||
width="100%" height="640" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ path('talent_dashboard') }}" class="btn btn-default m-t-20">Accéder à mon profil</a>
|
||||
<br /><br />
|
||||
<a class="text modal-action modal-close">Fermer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -118,8 +160,14 @@
|
||||
{{ parent() }}
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
console.log("passe");
|
||||
$.get("{{ path('company_ajaxRecStat',{'id': company.id }) }}", function (data) {});
|
||||
if ($('#modal-answer').length > 0) {
|
||||
$('#modal-answer').modal({
|
||||
dismissible: false,
|
||||
ready: function(modal, trigger) {}
|
||||
});
|
||||
$('#modal-answer').modal('open');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -106,11 +106,11 @@
|
||||
$('.fa-refresh').show();
|
||||
var month1 = obj.date1.getMonth();
|
||||
var day1 = obj.date1.getDate();
|
||||
var year1 = obj.date1.getUTCFullYear();
|
||||
var year1 = obj.date1.getFullYear();
|
||||
var month2 = obj.date2.getMonth();
|
||||
var day2 = obj.date2.getDate();
|
||||
var year2 = obj.date2.getUTCFullYear();
|
||||
var date1 = (month1 + 1) + "/" + day1 + "/" + year1 +" 00:00:00";
|
||||
var year2 = obj.date2.getFullYear();
|
||||
var date1 = (month1 + 1) + "/" + day1 + "/" + year1 +" 00:00:01";
|
||||
var date2 = (month2 + 1) +"/" + day2 + "/" + year2 +" 23:59:59";
|
||||
getChartData(date1, date2);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
<ul class="tabs">
|
||||
<li class="tab col s6"><a {% if tab == 1 %}class="active"{% endif %} target="_self" href="{{ path('company_ad') }}">{{ 'company.menu.ads.label'|trans }}</a></li>
|
||||
<li class="tab col s6"><a {% if tab == 2 %}class="active"{% endif %} target="_self" href="{{ path('company_answer_list') }}">{{ 'company.menu.answers.label'|trans }}</a></li>
|
||||
{#<li class="tab col s4"><a {% if tab == 3 %}class="active"{% endif %} href="#favoris">{{ 'company.menu.bookmark.label'|trans }}</a></li>#}
|
||||
<li class="tab col s4">
|
||||
<a {% if tab == 1 %}class="active"{% endif %} target="_self"
|
||||
href="{{ path('company_ad') }}">
|
||||
{{ 'company.menu.ads.label'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab col s4">
|
||||
<a {% if tab == 2 %}class="active"{% endif %} target="_self" href="{{ path('company_answer_list') }}">
|
||||
{{ 'company.menu.answers.label'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab col s4">
|
||||
<a {% if tab == 3 %}class="active"{% endif %} target="_self" href="{{ path('company_spontaneous_list') }}">
|
||||
Candidatures spontanées
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -48,7 +48,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}{{ ad.htmlTitle|raw }}{% endblock %}
|
||||
|
||||
@@ -35,13 +35,17 @@
|
||||
<div class="col s12 m12 l8 xl9">
|
||||
{% if ad.video and ad.status != "CLOSED" %}
|
||||
<div class="row m-b-0" id="adVideo">
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<div class="col s12">
|
||||
<iframe src="https://player.vimeo.com/video/{{ ad.video.cdnUrl|replace({ "/videos/": ""}) }}"
|
||||
width="100%" height="640" frameborder="0" webkitallowfullscreen mozallowfullscreen
|
||||
allowfullscreen></iframe>
|
||||
{% if ad.id == 38 %}
|
||||
<img class="responsive-img" src="{{asset('/img/GROUPE-ROCHER-TT.jpg')}}">
|
||||
{% else %}
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<div class="col s12">
|
||||
<iframe src="https://player.vimeo.com/video/{{ ad.video.cdnUrl|replace({ "/videos/": ""}) }}"
|
||||
width="100%" height="640" frameborder="0" webkitallowfullscreen mozallowfullscreen
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ad.isPromoted %}
|
||||
<div class="isPromoted"><img src="{{asset('/img/offre-pourvue-gauche.png')}}" alt="promoted"></div>
|
||||
{% endif %}
|
||||
@@ -124,6 +128,44 @@
|
||||
{% elseif ad.company.territories|length %}
|
||||
{% include 'ad/carrousel_territory.html.twig' with {'territories': ad.company.territories } %}
|
||||
{% endif %}
|
||||
{% set popup_answer_send = app.session.flashbag.get('popup_answer_send') %}
|
||||
{% set popup_answer_already_send = app.session.flashbag.get('popup_answer_already_send') %}
|
||||
{% if popup_answer_send is not empty %}
|
||||
{% if popup_answer_send[0] == true %}
|
||||
<div id="modal-answer" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="col-content p-30">
|
||||
{% if popup_answer_already_send is not empty and popup_answer_already_send[0] == true %}
|
||||
<h3 class="color-blue1 center-align">Candidature pour {{ ad.company.brandname }} !</h3>
|
||||
<div class="col offset-s2 s8 center-align">
|
||||
<p>Vous avez déjà répondu à cette annonce.</p>
|
||||
<a href="{{ path('talent_dashboard') }}" class="btn btn-default m-t-20">Accéder à mon profil</a>
|
||||
<br /><br />
|
||||
<a class="text modal-action modal-close">Fermer</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<h3 class="color-blue1 center-align">Votre candidature a bien été envoyée à {{ ad.company.brandname }} !</h3>
|
||||
<div class="col offset-s2 s8 center-align">
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<div class="col s12">
|
||||
<iframe src="https://player.vimeo.com/video/249822507"
|
||||
width="100%" height="640" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ path('talent_dashboard') }}" class="btn btn-default m-t-20">Accéder à mon profil</a>
|
||||
<br /><br />
|
||||
<a class="text modal-action modal-close">Fermer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
@@ -133,15 +175,19 @@
|
||||
$(document).ready(function(){
|
||||
$('.tooltipped').tooltip();
|
||||
$.get( "{{ path('ad_ajaxRecStat',{'id': ad.id }) }}", function( data ) {});
|
||||
if ($('#modal-answer').length > 0) {
|
||||
$('#modal-answer').modal({
|
||||
dismissible: false,
|
||||
ready: function(modal, trigger) {}
|
||||
});
|
||||
$('#modal-answer').modal('open');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block stylesheets %}
|
||||
|
||||
<script type="application/ld+json">
|
||||
{{- ad.structuredData|raw -}}
|
||||
{{- ad.structuredData|raw -}}
|
||||
</script>
|
||||
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5a095d2dd3cf90df"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="{{ path('company_show',{'alias': ad.company.alias }) }}" title="{{ ad.company.brandName }}" class="btn btn-default btn-small-grey">
|
||||
Découvir l'employeur
|
||||
Découvrir l'employeur
|
||||
</a>
|
||||
<p class="profil-name">
|
||||
<a href="{{ path('company_show',{'alias': company.alias }) }}" title="{{ company.brandName }}">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% if not app.user %}
|
||||
{% if not app.user or is_granted('ROLE_TALENT_TMP')%}
|
||||
<div class="header-link header-link-signin right-align">
|
||||
{% if app.request.get('_route') == "fos_user_security_login" %}
|
||||
{% set href = "" %}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{% if destination_login is defined %}
|
||||
{% set destination = destination_login %}
|
||||
{% else %}
|
||||
{% set destination = path('redirect_dashboard') %}
|
||||
{% endif %}
|
||||
<a class="btn btn-default btn-facebook z-depth-2" href="{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}?_destination={{ destination }}">Connexion avec Facebook</a>
|
||||
<a class="btn btn-default btn-linkedin z-depth-2" href="{{ url("hwi_oauth_service_redirect", {service: "linkedin"}) }}?_destination={{ destination }}">Connexion avec Linkedin</a>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="separator-with-label">
|
||||
<hr>
|
||||
<label><span>ou</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,6 +41,9 @@
|
||||
<a class="white-text td-none" href="https://twitter.com/TalentsTuber" title="Twitter" target="_blank">
|
||||
<i class="fa fa-twitter" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="white-text td-none" href="https://www.youtube.com/channel/UCRNqiJCLAorO0aCzNQu-8ww" title="Youtube" target="_blank">
|
||||
<i class="fa fa-youtube" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="white-text td-none" href="https://www.linkedin.com/company/talentstube" title="Linkedin" target="_blank">
|
||||
<i class="fa fa-linkedin-square" aria-hidden="true"></i>
|
||||
</a>
|
||||
@@ -70,4 +73,4 @@
|
||||
{{ render(controller('AppBundle:SecurityModal:loginModal')) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -9,12 +9,13 @@
|
||||
{# VIDEO #}
|
||||
<div class="col l12 m12 s12 home-content col-noPadding">
|
||||
<div id="homeTeaser" class="valign-wrapper">
|
||||
<h1 class="white-text center-align">1er job board <span>100% vidéo</span></h1><br />
|
||||
<a data-target="modal_concept" href="#!" class="btn btn-default btn-round btn-concept modal-trigger">
|
||||
Le concept en vidéo
|
||||
<img src="{{asset('img/bouton-play.png')}}" />
|
||||
</a>
|
||||
|
||||
<h1 class="white-text center-align">1ère plateforme pour l’emploi <span>100% vidéo</span></h1><br />
|
||||
<div class="link-home-head">
|
||||
<a data-target="modal_concept" href="#!" class="btn btn-default btn-round btn-concept modal-trigger">
|
||||
Le concept en vidéo
|
||||
<img src="{{asset('img/bouton-play.png')}}" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="header-video-inner">
|
||||
<video loop="" preload="metadata" autoplay="" id="vid" muted>
|
||||
<source src="/img/home_video.mp4" type="video/mp4">
|
||||
@@ -198,6 +199,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'testimony/testimony_list.html.twig' %}
|
||||
</div>
|
||||
<div id="modal_concept" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
|
||||
@@ -12,4 +12,9 @@
|
||||
|
||||
{% block description %}{{ page.description }}{% endblock %}
|
||||
|
||||
{% block content %}{{ page.content|raw }}{% endblock %}
|
||||
{% block content %}
|
||||
{{ page.content|raw }}
|
||||
{% if isTestimony is defined %}
|
||||
{% include 'testimony/testimony_list.html.twig' %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -4,7 +4,9 @@
|
||||
<div class="item">
|
||||
<a href="{{ path('talent_show',{'alias': talent.alias }) }}"
|
||||
title="{{ user.firstname }} {{ user.lastname }}">
|
||||
{% if user.photo %}
|
||||
{% if user.socialPicture is not null %}
|
||||
<img class="circle z-depth-3" src="{{ user.socialPicture }}" alt="{{ user.firstname }} {{ user.lastname }}"/>
|
||||
{% elseif user.photo %}
|
||||
<img class="circle z-depth-3" src="{{ user.webPath | imagine_filter('profile_square') }}" alt="{{ user.firstname }} {{ user.lastname }}"/>
|
||||
{% else %}
|
||||
<img class="circle z-depth-3"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class="dz-error-mark"><span>✘</span></div>
|
||||
<div class="dz-error-message"><span data-dz-errormessage></span></div>
|
||||
{% if deleting is defined %}
|
||||
<a href="javascript:undefined;" class="btn btn-default bnt-round dz-remove" data-dz-remove>Supprimer la vidéo</a>
|
||||
<a href="javascript:undefined;" class="dz-remove" data-dz-remove>Supprimer la vidéo</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{#<h1 class="alttitle">Espace offres d'emploi</h1>#}
|
||||
<div class=" row bg-bordered p-20">
|
||||
<ul class="tabs">
|
||||
<li class="tab col s4"><a class="active" href="#reponses">Mes réponses</a></li>
|
||||
<li class="tab col s4"><a class="active" href="#reponses">Mes candidatures</a></li>
|
||||
</ul>
|
||||
<div id="reponses" class="col s12">
|
||||
<table class="bordered highlight responsive-table">
|
||||
@@ -21,15 +21,18 @@
|
||||
{% for a in answers %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ a.ad.title }}<br />
|
||||
{% if a.ad != null %}{{ a.ad.title }}{% else %}{{ a.company.brandname }}{% endif %}<br />
|
||||
{% if a.video is not null %}
|
||||
<a class="waves-effect waves-light btn btn-default modalBtn" href="#" data-url="{{ a.video.cdnUrl }}">Voir la vidéo</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ a.uTime|date('d/m/Y') }}</td>
|
||||
<td>{{ a.ad.countAnswers }}</td>
|
||||
<td>
|
||||
{% if a.status == "DRAFT" %}
|
||||
{% if a.ad != null %} {{ a.ad.countAnswers }}{% endif %}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
{% if a.status == "DRAFT" and a.ad != null %}
|
||||
<a href="{{ path('talent_answer_create',{id:a.ad.id}) }}">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
</a>
|
||||
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block content %}
|
||||
<div id="wrapper" class="contentWrapper">
|
||||
<div class="row">
|
||||
<div class="col s8 offset-s2">
|
||||
<h3>Candidature pour l'entreprise : {{ company.brandName() }}</h3>
|
||||
<div class="card-panel">
|
||||
<strong><b>Comment procéder ?</b></strong>
|
||||
<div class="row">
|
||||
<div class="col s12 m5">
|
||||
<h4 class="color-blue1">Vous ne disposez pas de CV vidéo</h4>
|
||||
<p>Vous pouvez enregistrer directement votre réponse si vous disposez d'une webcam en <b>cliquant
|
||||
sur le bouton ci-dessous</b>.
|
||||
Une fois votre vidéo enregistrée et téléchargée vous pouvez la déposer dans la zone de
|
||||
téléchargement afin de valider votre réponse.</p><br/>
|
||||
<a class="modal-trigger waves-effect waves-light btn btn-default" href="#modal1">Filmer mon
|
||||
CV vidéo</a>
|
||||
</div>
|
||||
<div class="col offset-m2 s12 m5">
|
||||
<h4 class="color-blue1">Vous disposez déjà d'un cv vidéo</h4>
|
||||
<p>Pour répondre à cette annonce il vous suffit de glisser votre vidéo de réponse dans la
|
||||
<strong><a href="#infosDropzone">zone ci-dessous</a></strong>. Une fois la vidéo
|
||||
téléchargée vous pourrez valider votre réponse. Vous pouvez néanmoins laisser
|
||||
un message en complément de la vidéo dans la zone prévue à cette effet plus bas.
|
||||
</p>
|
||||
<a class="modal-trigger waves-effect waves-light btn btn-default" href="#modal2">Choisir une
|
||||
vidéo de ma vidéothèque</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
{% set video = null %}
|
||||
{% include 'media/dropzone.html.twig' %}
|
||||
{{ form_start(form, {'attr': { 'id': 'form_media' } }) }}
|
||||
{{ form_row(form.status) }}
|
||||
<br/><br/>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
{{ form_errors(form.comment) }}
|
||||
{{ form_widget(form.comment) }}
|
||||
{{ form_label(form.comment) }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{{ form_rest(form) }}
|
||||
<button id="submit" class="btn btn-large btn-default disabled" type="submit">
|
||||
Valider ma réponse
|
||||
</button>
|
||||
{{ form_end(form) }}
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal Vidéotheque -->
|
||||
<div id="modal2" class="modal modal-fixed-footer">
|
||||
<div class="modal-content modal-choiceExistingVideo">
|
||||
<h2>Choisir une vidéo existante</h2>
|
||||
<div class="row">
|
||||
{% for vid in videos %}
|
||||
{% set img = "" %}
|
||||
{% if vid.thumbnails.0 is defined %}
|
||||
{% set img = vid.thumbnails.0.sizes.4.link %}
|
||||
{% endif %}
|
||||
<div class="col s4">
|
||||
<a class="addExistingVideo tooltipped btn btn-default"
|
||||
data-url="https://player.vimeo.com{{ vid.getCdnUrl()|replace({ "videos": "video"}) }}"
|
||||
data-img="{{ img }}" data-position="top" data-tooltip="Choisir cette vidéo" href="#"
|
||||
data-title="{{ vid.getTitle() }}" data-id="{{ vid.getId() }}">
|
||||
<span class="truncate">{{ vid.getTitle() }}</span><br/>
|
||||
</a>
|
||||
<iframe src="https://player.vimeo.com{{ vid.getCdnUrl()|replace({ "videos": "video"}) }}"
|
||||
width="100%" height="auto" frameborder="0" webkitallowfullscreen mozallowfullscreen
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal Structure -->
|
||||
<div id="modal1" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<div class="row">
|
||||
<div class="col m5 s12">
|
||||
<h4 class="color-blue1">J'enregistre mon CV vidéo</h4>
|
||||
<video id="myCvVideo" class="video-js vjs-default-skin"></video>
|
||||
<div class="video-informations-card">
|
||||
<p>Merci de cliquer sur l'icone <span class="vjs-icon-device-perm"></span> afin d'activer votre
|
||||
webcam.</p>
|
||||
<p>Votre webcam activée, lancez l'enregistrement en cliquant sur le bouton rond en bas à gauche
|
||||
du lecteur.</p>
|
||||
<p>Si vous n'êtes pas satisfait de votre CV vidéo après un enregistrement, vous pouvez à tout
|
||||
moment recommencer l'enregistrement.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m2 hide-on-small-only">
|
||||
<div class="valign-wrapper"
|
||||
style="align-items:center;justify-content: center;height: 300px;width:100%;">
|
||||
<div style="font-size:40px;">
|
||||
<i class="fa fa-arrow-right center-align" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m5 s12">
|
||||
<h4 class="color-blue1">Je prévisualise mon CV vidéo</h4>
|
||||
<video id="preview" controls="true">
|
||||
<span class="vjs-control-text">Play Video</span>
|
||||
</video>
|
||||
<div class="btnContainer center-align" style="display:none;">
|
||||
<a id="saveRecord" href="#!" class="saveVideo btn btn-default">
|
||||
<i class="fa fa-floppy-o" aria-hidden="true"></i> Télécharger mon cv-vidéo
|
||||
</a>
|
||||
<div class="video-informations-card">
|
||||
<p>Une fois téléchargé vous pouvez glisser-déposer votre CV-vidéo dans la zone prévue pour
|
||||
lancer le téléchargement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-action modal-close waves-effect waves-blue btn-flat ">Fermer</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script>
|
||||
<script type="text/javascript">
|
||||
var urlDropzone = '{{ path("upload_media_answer", {"id": answer.getId()}) }}';
|
||||
var urlDelete = '{{ path("delete_media_answer", {"id": answer.getId() }) }}';
|
||||
var idObject = '{{ answer.getId() }}';
|
||||
var typeObject = "answer";
|
||||
var videoExist = false;
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(".addExistingVideo").click(function () {
|
||||
var idVideo = $(this).data("id");
|
||||
var titleVideo = $(this).data("title");
|
||||
var imgVideo = $(this).data("img");
|
||||
var urlVideo = $(this).data("url");
|
||||
var drop = $("#my-awesome-dropzone")[0].dropzone;
|
||||
drop.removeAllFiles(true);
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '{{ path("link_media_answer", {"id": answer.getId()}) }}',
|
||||
data: "idVideo=" + idVideo,
|
||||
dataType: 'html',
|
||||
success: function (response) {
|
||||
Materialize.toast('Vidéo associé Merci', 4000);
|
||||
$('#modal2').modal();
|
||||
$('#modal2').modal('close');
|
||||
videoOriginal = urlVideo;
|
||||
videoExist = true;
|
||||
var mockFile = {name: titleVideo, size: '100', type: 'mp4', serverID: 0, accepted: true};
|
||||
drop.emit("addedfile", mockFile);
|
||||
drop.files.push(mockFile);
|
||||
iframe = '{% include "media/dropzoneTemplateSuccess.html.twig" with {"url_iframe": "#URL_PLACEHOLDER#"} only %}';
|
||||
iframe = iframe.replace('#URL_PLACEHOLDER#', urlVideo);
|
||||
if ($('#preview_video > iframe').length) {
|
||||
$('#preview_video > iframe').attr('src', urlVideo);
|
||||
$('#preview_video > *').fadeIn();
|
||||
if ($("#form_media #submit").hasClass('disabled')) {
|
||||
$("#form_media > #submit").removeClass('disabled');
|
||||
$("#form_media > #submit").addClass('pulse');
|
||||
}
|
||||
} else {
|
||||
$('#preview_video').html(iframe);
|
||||
}
|
||||
if ($("#form_media #submit").hasClass('disabled')) {
|
||||
$("#form_media > #submit").removeClass('disabled');
|
||||
$("#form_media > #submit").addClass('pulse');
|
||||
}
|
||||
},
|
||||
error: function (response, xhr, ajaxOptions, thrownError) {
|
||||
Materialize.toast('Erreur lors de l\'association de la vidéo!', 4000);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="{{ asset('/js/dropzone.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/video.min.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/RecordRTC.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/videojs.record.js') }}"></script>
|
||||
<script src="{{ asset('/js/vendors/jquery.browser.min.js') }}"></script>
|
||||
<script language="JavaScript">
|
||||
var player = videojs("myCvVideo",
|
||||
{
|
||||
controls: true,
|
||||
width: 320,
|
||||
height: 240,
|
||||
plugins: {
|
||||
record: {
|
||||
audio: true,
|
||||
video: true,
|
||||
maxLength: 300,
|
||||
debug: true,
|
||||
videoMimeType: 'video/mp4',
|
||||
}
|
||||
}
|
||||
});
|
||||
player.on('deviceError', function () {
|
||||
console.log('device error:', player.deviceErrorCode);
|
||||
});
|
||||
player.on('error', function (error) {
|
||||
console.log('error:', error);
|
||||
});
|
||||
player.on('startRecord', function () {
|
||||
console.log('started recording!');
|
||||
});
|
||||
player.on('finishRecord', function () {
|
||||
$(".btnContainer").fadeIn();
|
||||
var preview = document.querySelector('#preview');
|
||||
var file = player.recordedData;
|
||||
var agent = navigator.userAgent;
|
||||
if ($.browser.mozilla) {
|
||||
window.URL = window.URL || window.webkitURL;
|
||||
fileURL = window.URL.createObjectURL(file);
|
||||
preview.src = fileURL;
|
||||
} else {
|
||||
preview.src = URL.createObjectURL(file.video);
|
||||
}
|
||||
});
|
||||
$("#saveRecord").on('click', function () {
|
||||
player.recorder.saveAs({'video': 'mon-cv-talentstube'});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -3,13 +3,20 @@
|
||||
<div class="profil center-align">
|
||||
{% set company = app.user.company %}
|
||||
<div class="profil-picture">
|
||||
{% if app.user.photo %}
|
||||
{% if app.user.photo is not null %}
|
||||
<img src="{{ app.user.webPath | imagine_filter('profile_square') }}"
|
||||
alt="{{ app.user.firstname }} {{ app.user.lastname|first|upper }}"
|
||||
class="circle responsive-img"/>
|
||||
<a href="#modalProfilePicture">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% elseif app.user.socialPicture is not null %}
|
||||
<img src="{{ app.user.socialPicture }}"
|
||||
alt="{{ app.user.firstname }} {{ app.user.lastname|first|upper }}"
|
||||
class="circle responsive-img"/>
|
||||
<a href="#modalProfilePicture">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="circle-letters font-2">{{ app.user.firstname|first|upper }}{{ app.user.lastname|first|upper }}</div>
|
||||
<a href="#modalProfilePicture">
|
||||
@@ -78,7 +85,6 @@
|
||||
'AppBundle:Media:profilePicture'
|
||||
)) }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Fermer</a>
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
<div class="col s12">
|
||||
<span class="bg-blue-1 text-gradient font-2 fs-20">Mes dernières offres consultées</span>
|
||||
</div>
|
||||
<div class="owl-carousel">
|
||||
<div class="owl-carousel owl-carousel-ptalent">
|
||||
{% for historyAd in historyAds %}
|
||||
<div class="item">
|
||||
<a href="{{ path('ad_show',{'alias': historyAd.alias }) }}"
|
||||
|
||||
@@ -113,10 +113,7 @@
|
||||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script src="https://player.vimeo.com/api/player.js"></script>
|
||||
<script>
|
||||
var iframe = document.querySelector('iframe');
|
||||
var player = new Vimeo.Player(iframe);
|
||||
$(document).ready(function(){
|
||||
$.get( "{{ path('talent_ajaxRecStat',{'id': talent.id }) }}", function( data ) {
|
||||
});
|
||||
|
||||
@@ -95,6 +95,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if company.descriptionAdmin %}
|
||||
<div class="col s12 m12 l8 xl9 right">
|
||||
<div class="row bg-bordered">
|
||||
<div class="col s12">
|
||||
<div class="item-detail-description-bo">
|
||||
<p>{{ company.descriptionAdmin|raw }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if companyAds|length > 0 %}
|
||||
<div id="offers" class="row">
|
||||
<div class="col s12">
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<div id="liste-testimony" class="bg-white">
|
||||
<div class="container">
|
||||
<div class="row flexcontainer row-noMargin">
|
||||
<div class="owl-carousel owl-carousel-testimony">
|
||||
<div class="item">
|
||||
<div class="row">
|
||||
<div class="col s12 l2">
|
||||
<img class="circle z-depth-3" src="{{ asset('img/testimony/de-charry.jpg')}}" alt="Jean-Philippe, Gérant, cabinet de Charry"/>
|
||||
</div>
|
||||
<div class="col s12 l8 left-align">
|
||||
<h3><strong>Jean-Philippe</strong>, Gérant, Cabinet de Charry</h3>
|
||||
<p>
|
||||
Notre entreprise amorce une nouvelle dynamique grâce à la vidéo de recrutement.<br />
|
||||
Nous accueillons demain notre nouvel agent commercial, basé à Auray/Lorient.<br />
|
||||
Il sera suivi de près par un autre très bientôt...<br />
|
||||
Nous avons eu beaucoup d’appréciations positives grâce à cette communication.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="row">
|
||||
<div class="col l2">
|
||||
<img class="circle z-depth-3" src="{{ asset('img/testimony/lionel.jpg')}}" alt="Jean-Philippe, Gérant, cabinet de Charry"/>
|
||||
</div>
|
||||
<div class="col s12 l8 left-align text-testimony">
|
||||
<h3><strong>Lionel</strong>, dirigeant, LB Groupe</h3>
|
||||
<p>
|
||||
Talents Tube nous a permis de recruter deux collaborateurs sur des profils bien spécifiques en un temps rapide.<br />
|
||||
L’offre d’emploi vidéo a permis d’atteindre des candidats aux profils plus divers qu’une annonce classique sur papier ou web.<br />
|
||||
Les CV vidéo ont permis de gagner un temps précieux au niveau de la présélection.<br />
|
||||
Atout supplémentaire : nos annonces en vidéo ont contribué à développer notre marque employeur !
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,4 +40,5 @@ assetic:
|
||||
- 'js/vendors/typeahead.js'
|
||||
- 'js/company.js'
|
||||
- 'js/backend.js'
|
||||
- 'js/tags.js'
|
||||
- 'js/tags.js'
|
||||
- 'js/vendors/jquery-confirm.min.js'
|
||||
@@ -25,7 +25,9 @@ framework:
|
||||
engines: ['twig']
|
||||
default_locale: "%locale%"
|
||||
trusted_hosts: ~
|
||||
trusted_proxies: ~
|
||||
# http://symfony.com/doc/master/deployment/proxies.html
|
||||
# https://symfony.com/blog/fixing-the-trusted-proxies-configuration-for-symfony-3-3
|
||||
trusted_proxies: [192.0.0.1, 10.0.0.0/8, 172.16.0.0/12]
|
||||
session:
|
||||
handler_id: session.handler.native_file
|
||||
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%"
|
||||
@@ -157,6 +159,38 @@ doctrine_migrations:
|
||||
table_name: migration_versions
|
||||
name: Application Migrations
|
||||
|
||||
hwi_oauth:
|
||||
connect:
|
||||
confirmation: false
|
||||
account_connector: app.user_provider
|
||||
target_path_parameter: _destination
|
||||
#use_referer: true
|
||||
firewall_names:
|
||||
- main
|
||||
fosub:
|
||||
username_iterations: 30
|
||||
properties:
|
||||
facebook: facebookId
|
||||
linkedin: linkedinId
|
||||
resource_owners:
|
||||
facebook:
|
||||
type: facebook
|
||||
client_id: 1800752833559014
|
||||
client_secret: 454de729b1e58f506f94c8b50ca5c011
|
||||
scope: "email, public_profile, user_birthday"
|
||||
infos_url: "https://graph.facebook.com/me?fields=id,email,first_name,last_name,gender,birthday,picture.type(square)"
|
||||
paths:
|
||||
email: email
|
||||
profilepicture: picture.data.url
|
||||
#csrf: true
|
||||
linkedin:
|
||||
type: linkedin
|
||||
client_id: 86m6hegwyj8lbo
|
||||
client_secret: LIOibqDszsP2vQSr
|
||||
infos_url: "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,location,email-address,picture-urls::(original))?format=json"
|
||||
options:
|
||||
#csrf: true
|
||||
|
||||
# Monolog
|
||||
monolog:
|
||||
handlers:
|
||||
|
||||
@@ -30,5 +30,5 @@ monolog:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
|
||||
#swiftmailer:
|
||||
# delivery_addresses: ['me@example.com']
|
||||
swiftmailer:
|
||||
delivery_addresses: ['%delivery_addresses%']
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
# This file is auto-generated during the composer install
|
||||
parameters:
|
||||
mailer_transport: smtp
|
||||
mailer_host: mail.gandi.net
|
||||
mailer_user: noreply@talentstube.com
|
||||
mailer_password: zfYwOGBHweCQ8OI9ghF6lUyo
|
||||
secret: 416157a2389cec970df2a46fa8ffd361b76516d1
|
||||
database_host: 'tt-website.postgres.dev'
|
||||
database_host: tt-website.postgres.dev
|
||||
database_port: '5432'
|
||||
database_name: database
|
||||
database_user: user
|
||||
database_password: edcl56
|
||||
#Mongo
|
||||
mongodb_server: "mongodb://tt-website.mongo.dev:27017"
|
||||
#Prestashop
|
||||
mongodb_server: 'mongodb://tt-website.mongo.dev:27017'
|
||||
prestashop_key: 9YUQ5jPqT4Z4x5s9B25pb1yuGBtpaeBDxpWDgicPF3CuP8F2p9aK18ZS
|
||||
prestashop_path: /home/projects/prestashop1/store
|
||||
prestashop_id: 1
|
||||
@@ -19,11 +18,10 @@ parameters:
|
||||
prestashop_month_id: 2
|
||||
prestashop_ad_id: 1
|
||||
prestashop_video_corporate_id: 3
|
||||
prestashop_url: https://www.talentstube.com/store/
|
||||
#Media
|
||||
prestashop_url: 'https://www.talentstube.com/store/'
|
||||
media_video_dir: '%kernel.root_dir%/../web/uploads/videos/'
|
||||
media_video_url: 'http://pp-static.talentstube.com/videos/'
|
||||
media_photo_dir: '%kernel.root_dir%/../web/uploads/photos/'
|
||||
|
||||
elastic_host: tt-website.elasticsearch.dev
|
||||
elastic_port: 9200
|
||||
delivery_addresses: thomas@e-declic.com
|
||||
@@ -27,3 +27,4 @@ parameters:
|
||||
|
||||
elastic_host: tt-website.elasticsearch.preprod
|
||||
elastic_port: 9200
|
||||
delivery_addresses: thomas@e-declic.com
|
||||
@@ -13,7 +13,7 @@ parameters:
|
||||
mongodb_server: "mongodb://tt-website.mongo.prod:27017"
|
||||
#Prestashop
|
||||
prestashop_key: 9YUQ5jPqT4Z4x5s9B25pb1yuGBtpaeBDxpWDgicPF3CuP8F2p9aK18ZS
|
||||
prestashop_path: /home/www/website/www/store/
|
||||
prestashop_path: /home/www/website/store/
|
||||
prestashop_id: 1
|
||||
prestashop_avoid: false
|
||||
prestashop_month_id: 11
|
||||
@@ -27,3 +27,4 @@ parameters:
|
||||
|
||||
elastic_host: tt-website.elasticsearch.prod
|
||||
elastic_port: 9200
|
||||
delivery_addresses: thomas@e-declic.com
|
||||
@@ -7,4 +7,16 @@ app:
|
||||
type: annotation
|
||||
|
||||
_liip_imagine:
|
||||
resource: "@LiipImagineBundle/Resources/config/routing.xml"
|
||||
resource: "@LiipImagineBundle/Resources/config/routing.xml"
|
||||
|
||||
hwi_oauth_security:
|
||||
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
|
||||
prefix: /login
|
||||
|
||||
hwi_oauth_connect:
|
||||
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
|
||||
prefix: /login
|
||||
|
||||
hwi_oauth_redirect:
|
||||
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
|
||||
prefix: /login
|
||||
@@ -4,6 +4,7 @@ security:
|
||||
memory: ~
|
||||
fos_userbundle:
|
||||
id: fos_user.user_provider.username_email
|
||||
#id: app.user_provider
|
||||
|
||||
firewalls:
|
||||
dev:
|
||||
@@ -12,17 +13,26 @@ security:
|
||||
|
||||
main:
|
||||
pattern: ^/
|
||||
remember_me:
|
||||
secret: '%kernel.secret%'
|
||||
lifetime: 14515200
|
||||
path: /
|
||||
always_remember_me: true
|
||||
form_login:
|
||||
provider: fos_userbundle
|
||||
csrf_token_generator: security.csrf.token_manager
|
||||
success_handler: redirect.after.login
|
||||
# logout: true
|
||||
logout:
|
||||
handlers: ['edeclic.prestashop.logout']
|
||||
anonymous: true
|
||||
oauth:
|
||||
resource_owners:
|
||||
facebook: "/login/check-facebook"
|
||||
linkedin: "/login/check-linkedin"
|
||||
login_path: "/login"
|
||||
oauth_user_provider:
|
||||
service: app.user_provider
|
||||
anonymous: true
|
||||
switch_user:
|
||||
provider: fos_userbundle
|
||||
|
||||
access_control:
|
||||
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
@@ -32,9 +42,7 @@ security:
|
||||
- { path: ^/admin/config/, role: [ROLE_WEBMASTER,ROLE_SUPER_ADMIN] }
|
||||
- { path: ^/talent/me/, roles: ROLE_TALENT }
|
||||
- { path: ^/talent/recherche/, roles: ROLE_COMPANY }
|
||||
#- { path: ^/talent/(.+)/, roles: ROLE_COMPANY }
|
||||
- { path: ^/entreprise/me/, roles: ROLE_COMPANY }
|
||||
- { path: ^/annonce/(.+)/repondre, roles: ROLE_TALENT }
|
||||
- { path: ^/territoire/me/, roles: ROLE_TERRITORY }
|
||||
|
||||
encoders:
|
||||
|
||||
@@ -43,7 +43,7 @@ services:
|
||||
# Listeners
|
||||
user.registration_listener:
|
||||
class: AppBundle\Utils\EventListener\RegistrationListener
|
||||
arguments: ["@doctrine.orm.entity_manager","@mt.slug","@security.token_storage","@router"]
|
||||
arguments: ["@doctrine.orm.entity_manager","@mt.slug","@security.token_storage","@router","@fos_user.user_manager"]
|
||||
tags:
|
||||
- { name: kernel.event_subscriber }
|
||||
|
||||
@@ -72,3 +72,6 @@ services:
|
||||
class: AppBundle\Utils\Services\ProductManager
|
||||
arguments: ["@doctrine.orm.entity_manager","@security.token_storage", "@app.mail_manager"]
|
||||
|
||||
app.user_provider:
|
||||
class: AppBundle\Security\Core\User\FOSUBUserProvider
|
||||
arguments: ["@fos_user.user_manager","@doctrine.orm.entity_manager","@mt.slug","@service_container", { facebook: facebookId, linkedin: linkedinId}]
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"sensio/framework-extra-bundle": "^3.0.2",
|
||||
"incenteev/composer-parameter-handler": "^2.0",
|
||||
"twig/twig": "^1.0||^2.0",
|
||||
"friendsofsymfony/user-bundle": "~2.0@dev",
|
||||
"friendsofsymfony/user-bundle": "~2.0",
|
||||
"doctrine/mongodb-odm-bundle": "^3.0",
|
||||
"doctrine/mongodb-odm": "^1.0",
|
||||
"alcaeus/mongo-php-adapter": "^1.0",
|
||||
@@ -44,7 +44,13 @@
|
||||
"vimeo/vimeo-api": "^1.1",
|
||||
"pulse00/ffmpeg-bundle": "^0.6.0",
|
||||
"doctrine/doctrine-migrations-bundle": "^1.0",
|
||||
"nmure/crawler-detect-bundle": "^1.0.0"
|
||||
"nmure/crawler-detect-bundle": "^1.0.0",
|
||||
"hwi/oauth-bundle": "^0.6.0",
|
||||
"php-http/guzzle6-adapter": "^1.1",
|
||||
"php-http/httplug-bundle": "^1.8",
|
||||
"symfony/assetic-bundle": "^2.8",
|
||||
"friendsofsymfony/elastica-bundle": "4.1.*",
|
||||
"liip/imagine-bundle": "^1.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"sensio/generator-bundle": "^3.0",
|
||||
|
||||
Generated
+5145
File diff suppressed because it is too large
Load Diff
@@ -417,11 +417,12 @@ class AdController extends Controller
|
||||
}
|
||||
$mediaManager->getThumbnails($a);
|
||||
}
|
||||
|
||||
$session = new Session();
|
||||
|
||||
return $this->render('default/ad_show.html.twig', [
|
||||
'ad' => $ad,
|
||||
'companyAds' => $companyAds,
|
||||
'alreadyAnswered' => $alreadyAnswered
|
||||
'alreadyAnswered' => $alreadyAnswered,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
class AdController extends Controller
|
||||
{
|
||||
|
||||
@@ -111,7 +110,6 @@ class AdController extends Controller
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/ad/{id}/edit", name="admin_ad_edit")
|
||||
*/
|
||||
@@ -130,6 +128,16 @@ class AdController extends Controller
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/ad/{id}/refresh-img", name="admin_ad_refresh_img")
|
||||
*/
|
||||
public function adminAdRefreshImgAction(Request $request, Ad $ad)
|
||||
{
|
||||
$mediaManager = $this->get('media_manager');
|
||||
$mediaManager->getThumbnails($ad, true);
|
||||
return $this->redirectToRoute('admin_ad_list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/ad/{id}/show", name="admin_ad_show")
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
class CompanyController extends Controller
|
||||
{
|
||||
|
||||
@@ -88,4 +87,14 @@ class CompanyController extends Controller
|
||||
'newP' => $newsP,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/company/{id}/refresh-img", name="admin_company_refresh_img")
|
||||
*/
|
||||
public function adminCompanyRefreshImgAction(Request $request, Company $company)
|
||||
{
|
||||
$mediaManager = $this->get('media_manager');
|
||||
$mediaManager->getThumbnails($company, true);
|
||||
return $this->redirectToRoute('admin_config_company');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
class TalentController extends Controller
|
||||
{
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
||||
@@ -30,7 +29,7 @@ class UserController extends Controller
|
||||
}
|
||||
}
|
||||
return $this->render('admin/user_list.html.twig', [
|
||||
'users' => $users
|
||||
'users' => $users,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -64,4 +63,142 @@ class UserController extends Controller
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/user/list", name="admin_config_others_user")
|
||||
*/
|
||||
public function adminOthersUsersListAction(Request $request)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$t = $em->getRepository('AppBundle:User')->findTalentsAndCompanies();
|
||||
return $this->render('admin/users_list.html.twig', array(
|
||||
'users' => $t,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/user/{id}/resend", name="admin_user_resend")
|
||||
*/
|
||||
public function adminUserResendAction(Request $request, $id)
|
||||
{
|
||||
$userManager = $this->get('fos_user.user_manager');
|
||||
$user = $userManager->findUserBy(array('id' => $id));
|
||||
$mailer = $this->get('fos_user.mailer');
|
||||
$mailer->sendConfirmationEmailMessage($user);
|
||||
|
||||
return $this->redirectToRoute('admin_config_user');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/admin/config/user/{id}/delete", name="admin_user_delete")
|
||||
*/
|
||||
public function adminUserDeleteAction(Request $request, $id)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$t = $em->getRepository('AppBundle:User')->findByRole('ROLE_TALENT');
|
||||
|
||||
$userManager = $this->get('fos_user.user_manager');
|
||||
$user = $userManager->findUserBy(array('id' => $id));
|
||||
if (\is_null($user)) {
|
||||
// user not found, generate $notFoundResponse
|
||||
$this->addFlash(
|
||||
'notice',
|
||||
' user not found !'
|
||||
);
|
||||
}
|
||||
|
||||
\assert(!\is_null($user));
|
||||
$company = $user->getCompany();
|
||||
if ($company) {
|
||||
$company->setPresentationVideo(null);
|
||||
$em->persist($company);
|
||||
$em->flush();
|
||||
}
|
||||
$this->deleteRelation($user);
|
||||
$em->remove($user);
|
||||
$em->flush();
|
||||
if ($company) {
|
||||
$em->remove($company);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
// if ($company) {
|
||||
// $em->remove($company);
|
||||
// }
|
||||
$em->flush();
|
||||
|
||||
return $this->redirectToRoute('admin_config_others_user');
|
||||
}
|
||||
|
||||
public function deleteRelation($user)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$sendMessage = $em->getRepository('AppBundle:Message')->findBy(array('sender' => $user));
|
||||
if ($sendMessage) {
|
||||
foreach ($sendMessage as $key => $message) {
|
||||
$message->setSender(null);
|
||||
$message->setAnswer(null);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$recipMessage = $em->getRepository('AppBundle:Message')->findBy(array('recipient' => $user));
|
||||
if ($recipMessage) {
|
||||
foreach ($recipMessage as $key => $message) {
|
||||
$message->setRecipient(null);
|
||||
$message->setAnswer(null);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$bookmarks = $em->getRepository('AppBundle:Bookmark')->findBy(array('creator' => $user));
|
||||
if ($bookmarks) {
|
||||
foreach ($bookmarks as $key => $bookmark) {
|
||||
$em->remove($bookmark);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$answers = $em->getRepository('AppBundle:Answer')->findBy(array('user' => $user));
|
||||
if ($answers) {
|
||||
foreach ($answers as $key => $answer) {
|
||||
$em->remove($answer);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$ads = $em->getRepository('AppBundle:Ad')->findBy(array('creator' => $user));
|
||||
if ($ads) {
|
||||
foreach ($ads as $key => $ad) {
|
||||
$bms = $em->getRepository('AppBundle:BookmarkAd')->findBy(array('ad' => $ad));
|
||||
foreach ($bms as $key2 => $bm) {
|
||||
$em->remove($bm);
|
||||
}
|
||||
$em->remove($ad);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$ads = $em->getRepository('AppBundle:Ad')->findBy(array('company' => $user->getCompany()));
|
||||
if ($ads) {
|
||||
foreach ($ads as $key => $ad) {
|
||||
$bms = $em->getRepository('AppBundle:BookmarkAd')->findBy(array('ad' => $ad));
|
||||
foreach ($bms as $key2 => $bm) {
|
||||
$em->remove($bm);
|
||||
}
|
||||
$em->remove($ad);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$medias = $em->getRepository('AppBundle:Media')->findBy(array('creator' => $user));
|
||||
if ($medias) {
|
||||
foreach ($medias as $key => $media) {
|
||||
$em->remove($media);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,27 +4,284 @@ namespace AppBundle\Controller;
|
||||
|
||||
use AppBundle\Entity\Ad;
|
||||
use AppBundle\Entity\Answer;
|
||||
use AppBundle\Entity\Company;
|
||||
use AppBundle\Entity\Message;
|
||||
use AppBundle\Form\AnswerType;
|
||||
use AppBundle\Form\ContactTalentType;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher,
|
||||
Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken,
|
||||
Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||
|
||||
|
||||
class AnswerController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/anwser/edit/comment/{id}", name="anwser_edit_comment")
|
||||
*/
|
||||
public function anwserEditCommentAction(Request $request, Answer $answer)
|
||||
{
|
||||
if($answer) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$answer->setComment($request->get('comment'));
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
return new JsonResponse(array('success' => "true"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/annonce/{ad}/reponse/{answer}", name="answer_create_ad_step3")
|
||||
* @Security("answer.getUser().getId() == user.getId()")
|
||||
*/
|
||||
public function createAnswerAdStep3Action(Request $request, Ad $ad, Answer $answer)
|
||||
{
|
||||
return $this->finishAnswerAction($request, $ad, $answer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/company/{company}/reponse/{answer}", name="answer_create_company_step3")
|
||||
* @Security("answer.getUser().getId() == user.getId()")
|
||||
*/
|
||||
public function createAnswerCompanyStep3Action(Request $request, Company $company, Answer $answer)
|
||||
{
|
||||
return $this->finishAnswerAction($request, $company, $answer);
|
||||
}
|
||||
|
||||
public function finishAnswerAction($request, $object, $answer) {
|
||||
$securityContext = $this->container->get('security.authorization_checker');
|
||||
if($object instanceof Ad) {
|
||||
$route = "ad_show";
|
||||
$varReqAnswer = "ad";
|
||||
$contact = $object->getCreator();
|
||||
$title = $answer->getAd()->getTitle();
|
||||
}
|
||||
if($object instanceof Company) {
|
||||
$route = "company_show";
|
||||
$varReqAnswer = "company";
|
||||
$contact = $object->getMainUser();
|
||||
$title = $object->getBrandName();
|
||||
}
|
||||
if (!$securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
|
||||
return $this->redirectToRoute($route, array('alias' => $object->getAlias()));
|
||||
}
|
||||
if($answer) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$existAnswer = $em->getRepository('AppBundle:Answer')->findOneBy(array('user' => $this->getUser(), $varReqAnswer => $object));
|
||||
if (!$this->getUser()->hasRole('ROLE_TALENT')) {
|
||||
$em->remove($answer);
|
||||
$session = new Session();
|
||||
$session->getFlashBag()->add('popup_answer_not_allowed', true);
|
||||
} else {
|
||||
if($existAnswer && ($existAnswer->getId() !== $answer->getid())){
|
||||
$em->remove($answer);
|
||||
$session = new Session();
|
||||
$session->getFlashBag()->add('popup_answer_already_send', true);
|
||||
} else {
|
||||
$session = new Session();
|
||||
$session->getFlashBag()->add('popup_answer_already_send', false);
|
||||
$answer->setStatus('SENDED');
|
||||
$em->persist($answer);
|
||||
|
||||
$mediaManager = $this->get('media_manager');
|
||||
$mediaManager->getThumbnails($answer);
|
||||
$thumbnailsArray = $answer->getVideo()->getThumbnails();
|
||||
$img = $thumbnailsArray[0]['sizes'][3]['link'];
|
||||
$mailManager = $this->get('app.mail_manager');
|
||||
$link = $this->generateUrl('company_answer_show', array('id' => $answer->getId()),UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
$mailManager->sendMail(
|
||||
'Candidature TalentsTube ',
|
||||
'<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:0px;" align="center"><table cellpadding="0" cellspacing="0" style="border-collapse:collapse;border-spacing:0px;" align="center"><tbody><tr><td><img alt="" src="'.$img.'" style="border:none;display:block;outline:none;text-decoration:none;width:100%;max-width:600px;height:auto;" width="600" height="auto"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>
|
||||
|
||||
<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:20px 35px 20px 35px;" align="left"><div class="mj-content" style="cursor:auto;color:#534F4F;font-family:Trebuchet,Helvetica,sans-serif;font-size:14px;line-height:22px;"><p>Bonjour '.$contact->getLastname().' '.$contact->getFirstname().',</p>
|
||||
<p>Le talent '.$answer->getUser()->getFirstname().' '.$answer->getUser()->getLastname().' a répondu à votre annonce '.$title.'.</p></div></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>
|
||||
|
||||
<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px 0px 40px 0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:15px 30px;" align="center"><table cellpadding="0" cellspacing="0" style="border:none;border-radius:30px;" align="center"><tbody><tr><td style="background:#1689FB;border-radius:30px;color:#FFFFFF;cursor:auto;" align="center" valign="middle" bgcolor="#1689FB"><a class="mj-content" href="'.$link.'" style="display:inline-block;text-decoration:none;background:#1689FB;border:1px solid #1689FB;border-radius:30px;color:#FFFFFF;font-family:Trebuchet,Helvetica,sans-serif;font-size:14px;font-weight:normal;padding:15px 30px;" target="_blank">Découvrir le talent</a></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>',
|
||||
$contact,
|
||||
'contact_default'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$session->getFlashBag()->add('popup_answer_send', true);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
return $this->redirect($this->generateUrl($route, array('alias' => $object->getAlias())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/annonce/{id}/repondre/{type}", name="answer_create_ad_step2")
|
||||
*/
|
||||
public function createAnswerAdAction(Request $request, Ad $ad, $type = 'default')
|
||||
{
|
||||
return $this->generateStep2($request, $ad, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/entreprise/{id}/repondre/{type}", name="answer_create_company_step2")
|
||||
*/
|
||||
public function createAnswerCompanyAction(Request $request, Company $company, $type = 'default')
|
||||
{
|
||||
return $this->generateStep2($request, $company, $type);
|
||||
}
|
||||
|
||||
public function generateStep2(Request $request, $object, $type) {
|
||||
if($object instanceof Ad) {
|
||||
$route = "ad_show";
|
||||
$routeStep3 = 'answer_create_ad_step3';
|
||||
$varReqAnswer = "ad";
|
||||
$typeObject = "Ad";
|
||||
}
|
||||
if($object instanceof Company) {
|
||||
$route = "company_show";
|
||||
$routeStep3 = 'answer_create_company_step3';
|
||||
$varReqAnswer = "company";
|
||||
$typeObject = "Company";
|
||||
}
|
||||
$securityContext = $this->container->get('security.authorization_checker');
|
||||
if (!$securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
|
||||
return $this->redirectToRoute($route, array('alias' => $object->getAlias()));
|
||||
}
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$user = $this->getUser();
|
||||
$existAnswer = $em->getRepository('AppBundle:Answer')->findOneBy(array('user' => $user, $varReqAnswer => $object, 'status' => 'DRAFT'));
|
||||
if ($existAnswer) {
|
||||
$answer = $existAnswer;
|
||||
} else {
|
||||
return $this->redirectToRoute($route, array('alias' => $object->getAlias()));
|
||||
}
|
||||
$video = $answer->getVideo();
|
||||
$videos = $em->getRepository('AppBundle:Media')->findBy(array('creator' => $this->getUser()));
|
||||
$form = $this->createForm(AnswerType::class, $answer);
|
||||
$form->handleRequest($request);
|
||||
$mustLogin = false;
|
||||
if (!$user->hasRole('ROLE_TALENT')) {
|
||||
$mustLogin = true;
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
if(!$mustLogin){
|
||||
return $this->redirect($this->generateUrl($routeStep3, array($varReqAnswer => $object->getId(), 'answer'=> $answer->getId())));
|
||||
}
|
||||
}
|
||||
|
||||
/*Definition des urls de destination pour ouath login et register*/
|
||||
$destination_login = $this->generateUrl($routeStep3, array($varReqAnswer => $object->getId(), 'answer'=> $answer->getId()));
|
||||
$this->get('twig')->addGlobal('destination_login', $destination_login);
|
||||
$session = new Session();
|
||||
$session->set('registration_destination', $destination_login);
|
||||
|
||||
return $this->render('answer/answer_create_'.$type.'.twig', array(
|
||||
'routeObject' => $route,
|
||||
'typeObject' => $typeObject,
|
||||
'object' => $object,
|
||||
'form' => $form->createView(),
|
||||
'answer' => $answer,
|
||||
'video' => $video,
|
||||
'videos' => $videos,
|
||||
$varReqAnswer => $object,
|
||||
'mustLogin' => $mustLogin
|
||||
));
|
||||
}
|
||||
|
||||
private function createAnonymousUser() {
|
||||
$userManager = $this->get('fos_user.user_manager');
|
||||
$user = $userManager->createUser();
|
||||
$uniqId = uniqId();
|
||||
$user->setUsername("anonym_".$uniqId);
|
||||
$user->setFirstname("anonym");
|
||||
$user->setLastname("anonym");
|
||||
$user->setEmail("anonym_".$uniqId."@talentstube.com");
|
||||
$user->setPlainPassword($uniqId);
|
||||
$user->setEnabled(false);
|
||||
$user->setRoles(array('ROLE_TALENT_TMP'));
|
||||
$company = new Company();
|
||||
$company->setAlias("anonym_".$uniqId);
|
||||
$company->setType("TALENT_TMP");
|
||||
$user->setCompany($company);
|
||||
$userManager->updateUser($user);
|
||||
$token = new UsernamePasswordToken($user, $user->getPassword(), "public", $user->getRoles());
|
||||
$this->get("security.token_storage")->setToken($token);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/entreprise/{id}/repondre/", name="talent_spontaneous_application_create")
|
||||
*/
|
||||
public function talentCreateSpontaneaousAction(Request $request, Company $company)
|
||||
{
|
||||
$securityContext = $this->container->get('security.authorization_checker');
|
||||
if (!$securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
|
||||
$this->createAnonymousUser();
|
||||
}
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$existAnswer = $em->getRepository('AppBundle:Answer')->findOneBy(array('user' => $this->getUser(), 'company' => $company));
|
||||
if ($existAnswer) {
|
||||
if ($existAnswer->getStatus() == "SENDED") {
|
||||
$answer = new Answer($this->getUser(), null, 'DRAFT', $company);
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
} else {
|
||||
$answer = $existAnswer;
|
||||
}
|
||||
} else {
|
||||
$answer = new Answer($this->getUser(), null, 'DRAFT', $company);
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
}
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
$user = $this->getUser();
|
||||
$mustLogin = false;
|
||||
if (!$user->hasRole('ROLE_TALENT')) {
|
||||
$mustLogin = true;
|
||||
}
|
||||
$route_videotheque = $this->generateUrl("answer_create_company_step2", array('id' => $company->getId(), 'type' => 'videotheque'));
|
||||
$this->get('twig')->addGlobal('destination_login', $route_videotheque);
|
||||
|
||||
return $this->render('answer/answer_create_step1.html.twig', array(
|
||||
'typeObject' => 'Company',
|
||||
'answer' => $answer,
|
||||
'object' => $company,
|
||||
'mustLogin' => $mustLogin,
|
||||
'route_videotheque' => $route_videotheque
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/annonce/{id}/repondre/", name="talent_answer_create")
|
||||
*/
|
||||
public function talentCreateAnswerAction(Request $request, Ad $ad)
|
||||
{
|
||||
|
||||
$securityContext = $this->container->get('security.authorization_checker');
|
||||
if (!$securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
|
||||
$this->createAnonymousUser();
|
||||
}
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$existAnswer = $em->getRepository('AppBundle:Answer')->findOneBy(array('user' => $this->getUser(), 'ad' => $ad));
|
||||
|
||||
if ($existAnswer) {
|
||||
if ($existAnswer->getStatus() == "SENDED") {
|
||||
return $this->redirectToRoute('ad_show', array('alias' => $ad->getAlias()));
|
||||
@@ -35,65 +292,37 @@ class AnswerController extends Controller
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
}
|
||||
$videos = $em->getRepository('AppBundle:Media')->findBy(array('creator' => $this->getUser()));
|
||||
$video = $answer->getVideo();
|
||||
$form = $this->createForm(AnswerType::class, $answer);
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$answer = $form->getData();
|
||||
$answer->setStatus('SENDED');
|
||||
$em->persist($answer);
|
||||
$em->flush();
|
||||
$link = $this->generateUrl('company_answer_show', array('id' => $answer->getAd()->getId()),UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
|
||||
$mediaManager = $this->get('media_manager');
|
||||
$mediaManager->getThumbnails($answer);
|
||||
$thumbnailsArray = $answer->getVideo()->getThumbnails();
|
||||
$img = $thumbnailsArray[0]['sizes'][3]['link'];
|
||||
$mailManager = $this->get('app.mail_manager');
|
||||
$mailManager->sendMail(
|
||||
'Candidature TalentsTube ',
|
||||
'<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:0px;" align="center"><table cellpadding="0" cellspacing="0" style="border-collapse:collapse;border-spacing:0px;" align="center"><tbody><tr><td><img alt="" src="'.$img.'" style="border:none;display:block;outline:none;text-decoration:none;width:100%;max-width:600px;height:auto;" width="600" height="auto"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>
|
||||
|
||||
<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:20px 35px 20px 35px;" align="left"><div class="mj-content" style="cursor:auto;color:#534F4F;font-family:Trebuchet,Helvetica,sans-serif;font-size:14px;line-height:22px;"><p>Bonjour '.$ad->getCreator()->getLastname().' '.$ad->getCreator()->getFirstname().',</p>
|
||||
<p>Le talent '.$answer->getUser()->getFirstname().' '.$answer->getUser()->getLastname().' a répondu à votre annonce '.$answer->getAd()->getTitle().'.</p></div></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>
|
||||
|
||||
<div style="margin:0 auto;max-width:600px;background:#FFFFFF;"><table class="" cellpadding="0" cellspacing="0" style="width:100%;font-size:0px;background:#FFFFFF;" align="center"><tbody><tr><td style="text-align:center;vertical-align:top;font-size:0;padding:0px 0px 40px 0px;"><!--[if mso]>
|
||||
<table border="0" cellpadding="0" cellspacing="0"><tr><td style="width:600px;">
|
||||
<![endif]--><div style="vertical-align:top;display:inline-block;font-size:13px;text-align:left;width:100%;" class="mj-column-per-100" aria-labelledby="mj-column-per-100"><table width="100%"><tbody><tr><td style="font-size:0;padding:15px 30px;" align="center"><table cellpadding="0" cellspacing="0" style="border:none;border-radius:30px;" align="center"><tbody><tr><td style="background:#1689FB;border-radius:30px;color:#FFFFFF;cursor:auto;" align="center" valign="middle" bgcolor="#1689FB"><a class="mj-content" href="'.$link.'" style="display:inline-block;text-decoration:none;background:#1689FB;border:1px solid #1689FB;border-radius:30px;color:#FFFFFF;font-family:Trebuchet,Helvetica,sans-serif;font-size:14px;font-weight:normal;padding:15px 30px;" target="_blank">Découvrir le talent</a></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]--></td></tr></tbody></table></div>',
|
||||
$ad->getCreator(),
|
||||
'contact_default'
|
||||
);
|
||||
|
||||
$this->addFlash('notice', $this->get('translator')->trans('ad.answer.mail.send'));
|
||||
return $this->redirectToRoute('ad_show', array('alias' => $ad->getAlias()));
|
||||
$user = $this->getUser();
|
||||
$mustLogin = false;
|
||||
if (!$user->hasRole('ROLE_TALENT')) {
|
||||
$mustLogin = true;
|
||||
}
|
||||
|
||||
return $this->render('talent/answer_create.html.twig', array(
|
||||
'form' => $form->createView(),
|
||||
$route_videotheque = $this->generateUrl("answer_create_ad_step2", array('id' => $ad->getId(), 'type' => 'videotheque'));
|
||||
$this->get('twig')->addGlobal('destination_login', $route_videotheque);
|
||||
|
||||
return $this->render('answer/answer_create_step1.html.twig', array(
|
||||
'typeObject' => 'Ad',
|
||||
'answer' => $answer,
|
||||
'video' => $video,
|
||||
'videos' => $videos,
|
||||
'ad' => $ad
|
||||
'object' => $ad,
|
||||
'mustLogin' => $mustLogin,
|
||||
'route_videotheque' => $route_videotheque
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/entreprise/me/espace-oe/reponse/{id}/", name="company_answer_show")
|
||||
* @Security("answer.getAd().getCompany() == user.getCompany()")
|
||||
* @Security("answer.checkCompany(user.getCompany()) == true")
|
||||
*/
|
||||
public function companyShowAnswerAction(Request $request, Answer $answer)
|
||||
{
|
||||
if ($answer->getAd() == null) {
|
||||
$type = 'spontaneous';
|
||||
$title = $answer->getCompany()->getBrandName();
|
||||
} else {
|
||||
$type = 'answer';
|
||||
$title = $answer->getAd()->getTitle();
|
||||
}
|
||||
$user = $this->getUser();
|
||||
$form = $this->createForm(ContactTalentType::class);
|
||||
$form->handleRequest($request);
|
||||
@@ -109,15 +338,15 @@ class AnswerController extends Controller
|
||||
'user' => $answer->getUser(),
|
||||
));
|
||||
$email = \Swift_Message::newInstance()
|
||||
->setSubject('Candidature : ' . $answer->getAd()->getTitle())
|
||||
->setFrom($this->getParameter('mailer_user'),$user->getEmail())
|
||||
->setSubject('Candidature : ' . $title)
|
||||
->setFrom($this->getParameter('mailer_user'), $user->getEmail())
|
||||
->setReplyTo($user->getEmail())
|
||||
->setTo($answer->getUser()->getEmail())
|
||||
->setBody($htmlView, 'text/html')
|
||||
->addPart($plainView, 'text/plain');
|
||||
$this->get('mailer')->send($email);
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$messageObj = new message('Candidature : ' . $answer->getAd()->getTitle(), $message, $user, $answer->getUser(), $form['status']->getData(), $answer);
|
||||
$messageObj = new message('Candidature : ' . $title, $message, $user, $answer->getUser(), $form['status']->getData(), $answer);
|
||||
$em->persist($messageObj);
|
||||
$em->flush();
|
||||
return $this->redirectToRoute('company_answer_show', ['id' => $answer->getId()]);
|
||||
@@ -125,6 +354,7 @@ class AnswerController extends Controller
|
||||
return $this->render('company/answer_show.html.twig', [
|
||||
'answer' => $answer,
|
||||
'form' => $form->createView(),
|
||||
'type' => $type,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -137,7 +367,23 @@ class AnswerController extends Controller
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$answers = $em->getRepository('AppBundle:Answer')->getAnswerByCompany($user->getCompany()->getId());
|
||||
return $this->render('company/answer_list.html.twig', [
|
||||
'answers' => $answers
|
||||
'answers' => $answers,
|
||||
'type' => 'answer'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/entreprise/me/espace-oe/candidature-spontanee/", name="company_spontaneous_list")
|
||||
*/
|
||||
public function companyListSpontaneousAction()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$answers = $em->getRepository('AppBundle:Answer')->findBy(array('company' => $user->getCompany()->getId(), 'status' => 'SENDED'));
|
||||
return $this->render('company/answer_list.html.twig', [
|
||||
'answers' => $answers,
|
||||
'type' => 'spontaneous'
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -187,7 +433,7 @@ class AnswerController extends Controller
|
||||
return new JsonResponse($message);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @Route("/media/linkAnswer/{id}", name="link_media_answer")
|
||||
*/
|
||||
public function mediaLinkAction(Request $request, Answer $answer)
|
||||
|
||||
@@ -109,12 +109,17 @@ class CompanyController extends Controller
|
||||
$this->get('translator')->trans('company.account.save.title')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$formFactory = $this->container->get('fos_user.change_password.form.factory');
|
||||
$formPw = $formFactory->createForm();
|
||||
$formPw->setData($user);
|
||||
$formPw->handleRequest($request);
|
||||
if ($formPw->isSubmitted() && $formPw->isValid()) {
|
||||
$userManager->updateUser($user);
|
||||
$this->addFlash(
|
||||
'notice',
|
||||
$this->get('translator')->trans('company.account.save.title')
|
||||
);
|
||||
}
|
||||
return $this->render('company/my_account.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
|
||||
@@ -7,6 +7,7 @@ use AppBundle\Entity\Company;
|
||||
use AppBundle\Form\AdSearchType;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
class DefaultController extends Controller
|
||||
@@ -66,6 +67,27 @@ class DefaultController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/redirect_dashboard", name="redirect_dashboard")
|
||||
*/
|
||||
public function redirect_dashboard()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
if($user){
|
||||
if ($user->hasRole('ROLE_TALENT')) {
|
||||
|
||||
return $this->redirectToRoute('talent_dashboard');
|
||||
} elseif ($user->hasRole('ROLE_COMPANY')) {
|
||||
|
||||
return $this->redirectToRoute('company_dashboard');
|
||||
}
|
||||
} else {
|
||||
|
||||
return $this->redirectToRoute('homepage');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/test", name="test")
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@ class NoteController extends Controller
|
||||
|
||||
/**
|
||||
* @Route("/entreprise/me/espace-oe/reponse/{id}/note/create", name="answer_note_create")
|
||||
* @Security("answer.getAd().getCompany() == user.getCompany()")
|
||||
* @Security("answer.checkCompany(user.getCompany()) == true")
|
||||
*/
|
||||
public function CompanyCreateAnswerNoteAction(Request $request, Answer $answer)
|
||||
{
|
||||
|
||||
@@ -188,7 +188,8 @@ class PageController extends Controller
|
||||
$page = $em->getRepository('AppBundle:Page')->findOneByRef('OFFREEMPLOI');
|
||||
|
||||
return $this->render('default/page.html.twig', [
|
||||
'page' => $page
|
||||
'page' => $page,
|
||||
'isTestimony' => true
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -201,7 +202,8 @@ class PageController extends Controller
|
||||
$page = $em->getRepository('AppBundle:Page')->findOneByRef('MARQUEEMPLOYEUR');
|
||||
|
||||
return $this->render('default/page.html.twig', [
|
||||
'page' => $page
|
||||
'page' => $page,
|
||||
'isTestimony' => true
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,11 +35,15 @@ class SecurityModalController extends Controller
|
||||
$csrfToken = $this->has('security.csrf.token_manager')
|
||||
? $this->get('security.csrf.token_manager')->getToken('authenticate')->getValue()
|
||||
: null;
|
||||
|
||||
$formFactory = $this->get('fos_user.registration.form.factory');
|
||||
$form = $formFactory->createForm();
|
||||
|
||||
return $this->render('@FOSUser/Security/loginModal.html.twig', array(
|
||||
'last_username' => $lastUsername,
|
||||
'error' => $error,
|
||||
'csrf_token' => $csrfToken,
|
||||
'register_form' => $form->createView()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -173,25 +173,30 @@ class Ad
|
||||
***********************/
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Answer", mappedBy="ad", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Answer", mappedBy="ad", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $answers;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ProductAd", mappedBy="ad", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ProductAd", mappedBy="ad", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $products;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $draftNotes;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="ad", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="ad", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $territories;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\BookmarkAd", mappedBy="ad", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $bookmarkAds;
|
||||
|
||||
|
||||
/***********************
|
||||
* Constructor
|
||||
@@ -392,9 +397,9 @@ class Ad
|
||||
public function getHtmlDescription()
|
||||
{
|
||||
$address = $this->getAddress();
|
||||
$desc = 'Découvrez la vidéo de l\'offre d\'emploi ' . $this->title . ' - ';
|
||||
$desc = 'Découvrez la vidéo de l\'offre d\'emploi ' . $this->title;
|
||||
if (isset($address['locality'])) {
|
||||
$desc .= $address['locality'];
|
||||
$desc .= ' - ' .$address['locality'];
|
||||
}
|
||||
if (isset($address['postal_code'])) {
|
||||
$zip = substr($address['postal_code'], 0, 2);
|
||||
|
||||
@@ -32,9 +32,16 @@ class Answer
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Ad", inversedBy="answers")
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private $ad;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Company", inversedBy="spontaneousApplications")
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private $company;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="answers", cascade={"persist"})
|
||||
*/
|
||||
@@ -60,38 +67,58 @@ class Answer
|
||||
private $comment;
|
||||
|
||||
/***********************
|
||||
* OneToMany Array's
|
||||
***********************/
|
||||
* OneToMany Array's
|
||||
***********************/
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $notes;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message", mappedBy="answer", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message", mappedBy="answer", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $messages;
|
||||
|
||||
/***********************
|
||||
* Constructor
|
||||
***********************/
|
||||
|
||||
|
||||
public function __construct($user = null, $ad = null, $status = null)
|
||||
public function __construct($user = null, $ad = null, $status = null, $company = null)
|
||||
{
|
||||
$this->notes = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
$this->messages = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
$this->user = $user ;
|
||||
$this->ad = $ad ;
|
||||
$this->user = $user;
|
||||
$this->ad = $ad;
|
||||
$this->status = $status;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/***********************
|
||||
* Custom Functions
|
||||
***********************/
|
||||
|
||||
public function checkCompany(Company $company)
|
||||
{
|
||||
if ($this->ad != null) {
|
||||
$c = $this->ad->getCompany();
|
||||
} elseif ($this->company != null) {
|
||||
$c = $this->company;
|
||||
} else {
|
||||
$c = null;
|
||||
}
|
||||
if ($company == $c) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***********************
|
||||
* Getters & Setters
|
||||
***********************/
|
||||
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
@@ -293,4 +320,28 @@ class Answer
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set company.
|
||||
*
|
||||
* @param \AppBundle\Entity\Company|null $company
|
||||
*
|
||||
* @return Answer
|
||||
*/
|
||||
public function setCompany(\AppBundle\Entity\Company $company = null)
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get company.
|
||||
*
|
||||
* @return \AppBundle\Entity\Company|null
|
||||
*/
|
||||
public function getCompany()
|
||||
{
|
||||
return $this->company;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class Bookmark
|
||||
***********************/
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\User", mappedBy="sharedBookmarks" ,cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\User", mappedBy="sharedBookmarks" ,cascade={"persist", "remove"})
|
||||
*/
|
||||
private $sharedWith;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class BookmarkAd
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist","remove"})
|
||||
*/
|
||||
private $notes;
|
||||
|
||||
@@ -42,7 +42,6 @@ class BookmarkAd
|
||||
*/
|
||||
private $ad;
|
||||
|
||||
|
||||
/***********************
|
||||
* Constructor
|
||||
***********************/
|
||||
@@ -57,7 +56,6 @@ class BookmarkAd
|
||||
* Getters & Setters
|
||||
***********************/
|
||||
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
|
||||
@@ -48,7 +48,7 @@ class BookmarkUser
|
||||
***********************/
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Note", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $notes;
|
||||
|
||||
|
||||
@@ -56,6 +56,13 @@ class Company
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var text
|
||||
*
|
||||
* @ORM\Column(name="description_admin", type="text", length=255, nullable=true)
|
||||
*/
|
||||
private $descriptionAdmin;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@@ -78,10 +85,10 @@ class Company
|
||||
private $alias;
|
||||
|
||||
/**
|
||||
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Media", cascade={"persist"})
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Media", cascade={"persist", "remove"})
|
||||
* @ORM\JoinColumn(name="presentation_video_id", nullable=true)
|
||||
*/
|
||||
private $presentation_video;
|
||||
private $presentationVideo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -128,20 +135,24 @@ class Company
|
||||
private $users;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Ad",mappedBy="company", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Ad",mappedBy="company", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $ads;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="territory", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="territory", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $territoryAds;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="company", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TerritoryAd", mappedBy="company", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $territories;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Answer",mappedBy="company", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $spontaneousApplications;
|
||||
|
||||
/***********************
|
||||
* Constructor
|
||||
@@ -159,7 +170,8 @@ class Company
|
||||
* Custom Function
|
||||
***********************/
|
||||
|
||||
public function init(){
|
||||
public function init()
|
||||
{
|
||||
$this->initAddress();
|
||||
$this->initTags();
|
||||
$this->initExtra();
|
||||
@@ -240,8 +252,8 @@ class Company
|
||||
{
|
||||
$arrayPublishedAds = array();
|
||||
foreach ($this->getAds() as $ad) {
|
||||
if( $ad->getStatus() == "PUBLISHED") {
|
||||
array_push($arrayPublishedAds, $ad);
|
||||
if ($ad->getStatus() == "PUBLISHED") {
|
||||
array_push($arrayPublishedAds, $ad);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +274,6 @@ class Company
|
||||
* Getter & Setters
|
||||
***********************/
|
||||
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
@@ -486,7 +497,7 @@ class Company
|
||||
*/
|
||||
public function setPresentationVideo(\AppBundle\Entity\Media $presentationVideo = null)
|
||||
{
|
||||
$this->presentation_video = $presentationVideo;
|
||||
$this->presentationVideo = $presentationVideo;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -498,7 +509,7 @@ class Company
|
||||
*/
|
||||
public function getPresentationVideo()
|
||||
{
|
||||
return $this->presentation_video;
|
||||
return $this->presentationVideo;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -589,7 +600,6 @@ class Company
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set emphasis.
|
||||
*
|
||||
@@ -733,4 +743,64 @@ class Company
|
||||
{
|
||||
return $this->territories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add spontaneousApplication.
|
||||
*
|
||||
* @param \AppBundle\Entity\Answer $spontaneousApplication
|
||||
*
|
||||
* @return Company
|
||||
*/
|
||||
public function addSpontaneousApplication(\AppBundle\Entity\Answer $spontaneousApplication)
|
||||
{
|
||||
$this->spontaneousApplications[] = $spontaneousApplication;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove spontaneousApplication.
|
||||
*
|
||||
* @param \AppBundle\Entity\Answer $spontaneousApplication
|
||||
*
|
||||
* @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
|
||||
*/
|
||||
public function removeSpontaneousApplication(\AppBundle\Entity\Answer $spontaneousApplication)
|
||||
{
|
||||
return $this->spontaneousApplications->removeElement($spontaneousApplication);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get spontaneousApplications.
|
||||
*
|
||||
* @return \Doctrine\Common\Collections\Collection
|
||||
*/
|
||||
public function getSpontaneousApplications()
|
||||
{
|
||||
return $this->spontaneousApplications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set descriptionAdmin.
|
||||
*
|
||||
* @param string|null $descriptionAdmin
|
||||
*
|
||||
* @return Company
|
||||
*/
|
||||
public function setDescriptionAdmin($descriptionAdmin = null)
|
||||
{
|
||||
$this->descriptionAdmin = $descriptionAdmin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get descriptionAdmin.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescriptionAdmin()
|
||||
{
|
||||
return $this->descriptionAdmin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class ProductAd
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Product", cascade={"persist"})
|
||||
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Product", cascade={"persist" , "remove"})
|
||||
*/
|
||||
private $product;
|
||||
|
||||
|
||||
@@ -69,52 +69,85 @@ class User extends BaseUser
|
||||
|
||||
private $file;
|
||||
|
||||
|
||||
/***********************
|
||||
* OneToMany Array's
|
||||
***********************/
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Answer",mappedBy="user", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Answer",mappedBy="user", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $answers;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Ad",mappedBy="creator", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Ad",mappedBy="creator", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $ads;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Product",mappedBy="user", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Product",mappedBy="user", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $products;
|
||||
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Media",mappedBy="creator", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Media",mappedBy="creator", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $medias;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Bookmark",mappedBy="creator", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Bookmark",mappedBy="creator", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $bookmarks;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Bookmark", inversedBy="sharedWith", cascade={"persist"})
|
||||
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Bookmark", inversedBy="sharedWith", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $sharedBookmarks;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message",mappedBy="sender", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message",mappedBy="sender", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $sendedMessages;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message",mappedBy="recipient", cascade={"persist"})
|
||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Message",mappedBy="recipient", cascade={"persist", "remove"})
|
||||
*/
|
||||
private $receivedMessages;
|
||||
|
||||
/************************
|
||||
* Social Network
|
||||
************************/
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="facebook_id", type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $facebookId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="facebook_access_token", type="text", nullable=true)
|
||||
*/
|
||||
private $facebookAccessToken;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="linkedin_id", type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $linkedinId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="linkedin_access_token", type="text", nullable=true)
|
||||
*/
|
||||
|
||||
private $linkedinAccessToken;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="social_picture", type="text", nullable=true)
|
||||
*/
|
||||
private $socialPicture;
|
||||
|
||||
/***********************
|
||||
* Constructor
|
||||
@@ -123,6 +156,7 @@ class User extends BaseUser
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
parent::setUsername(uniqId());
|
||||
$this->answers = new ArrayCollection();
|
||||
$this->ads = new ArrayCollection();
|
||||
$this->bookmarks = new ArrayCollection();
|
||||
@@ -161,6 +195,22 @@ class User extends BaseUser
|
||||
return null === $this->photo ? null : $this->getUploadDir() . '/' . $this->photo;
|
||||
}
|
||||
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file
|
||||
*
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
*/
|
||||
public function setFile(UploadedFile $file = null)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return array|string
|
||||
@@ -218,6 +268,15 @@ class User extends BaseUser
|
||||
}
|
||||
}
|
||||
|
||||
public function setEmail($email)
|
||||
{
|
||||
$email = is_null($email) ? '' : $email;
|
||||
parent::setEmail($email);
|
||||
$this->setUsername($email);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/***********************
|
||||
* Getters & Setters
|
||||
***********************/
|
||||
@@ -366,6 +425,30 @@ class User extends BaseUser
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set facebookId.
|
||||
*
|
||||
* @param string|null $facebookId
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setFacebookId($facebookId = null)
|
||||
{
|
||||
$this->facebookId = $facebookId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get facebookId.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFacebookId()
|
||||
{
|
||||
return $this->facebookId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set company.
|
||||
*
|
||||
@@ -606,22 +689,6 @@ class User extends BaseUser
|
||||
return $this->sharedBookmarks;
|
||||
}
|
||||
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file
|
||||
*
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
*/
|
||||
public function setFile(UploadedFile $file = null)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sendedMessage.
|
||||
*
|
||||
@@ -693,4 +760,100 @@ class User extends BaseUser
|
||||
{
|
||||
return $this->receivedMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set linkedinId.
|
||||
*
|
||||
* @param string|null $linkedinId
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setLinkedinId($linkedinId = null)
|
||||
{
|
||||
$this->linkedinId = $linkedinId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get linkedinId.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLinkedinId()
|
||||
{
|
||||
return $this->linkedinId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set socialPicture.
|
||||
*
|
||||
* @param string|null $socialPicture
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setSocialPicture($socialPicture = null)
|
||||
{
|
||||
$this->socialPicture = $socialPicture;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get socialPicture.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSocialPicture()
|
||||
{
|
||||
return $this->socialPicture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set facebookAccessToken.
|
||||
*
|
||||
* @param string|null $facebookAccessToken
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setFacebookAccessToken($facebookAccessToken = null)
|
||||
{
|
||||
$this->facebookAccessToken = $facebookAccessToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get facebookAccessToken.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFacebookAccessToken()
|
||||
{
|
||||
return $this->facebookAccessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set linkedinAccessToken.
|
||||
*
|
||||
* @param string|null $linkedinAccessToken
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setLinkedinAccessToken($linkedinAccessToken = null)
|
||||
{
|
||||
$this->linkedinAccessToken = $linkedinAccessToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get linkedinAccessToken.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLinkedinAccessToken()
|
||||
{
|
||||
return $this->linkedinAccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,15 @@ namespace AppBundle\Form\Admin;
|
||||
|
||||
use AppBundle\Entity\Company;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\UrlType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\Extension\Core\Type\UrlType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
|
||||
class TerritoryAdminType extends AbstractType
|
||||
{
|
||||
@@ -32,6 +33,7 @@ class TerritoryAdminType extends AbstractType
|
||||
$builder
|
||||
->add('brandName', TextType::class, array('label' => 'Nom'))
|
||||
->add('description', TextType::class, array('label' => 'profile.company.description', 'required' => false))
|
||||
->add('descriptionAdmin', TextareaType::class, array('label' => 'Description additionel réservé aux administrateur (Attention contenu affiché en front)', 'required' => false))
|
||||
->add('website', UrlType::class, array(
|
||||
'label' => 'profile.company.website',
|
||||
'required' => false,
|
||||
|
||||
@@ -14,6 +14,16 @@ class CompanyRepository extends EntityRepository
|
||||
{
|
||||
public function getCompanySortByAds()
|
||||
{
|
||||
$qb = $this
|
||||
->createQueryBuilder('c')
|
||||
->andWhere('c.type = :type')
|
||||
->setParameter(':type', "COMPANY")
|
||||
->andWhere('c.presentationVideo IS NOT NULL')
|
||||
->orderBy('c.cTime', 'DESC');
|
||||
|
||||
|
||||
$badCompany = $qb->getQuery()->getResult();
|
||||
|
||||
$qb = $this
|
||||
->createQueryBuilder('c')
|
||||
->from('AppBundle:Ad', 'a')
|
||||
@@ -21,10 +31,26 @@ class CompanyRepository extends EntityRepository
|
||||
->andWhere('a.status = :status')
|
||||
->orderBy('a.publishedAt', 'DESC')
|
||||
->setParameter(':status', "PUBLISHED");
|
||||
|
||||
$firstCompany = $qb->getQuery()->getResult();
|
||||
|
||||
return $qb
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
$mergeArray = array();
|
||||
array_map(function($a, $b) use (&$mergeArray) {
|
||||
if($a){
|
||||
if(!isset($mergeArray[$a->getId()])) {
|
||||
$mergeArray[$a->getId()] = $a;
|
||||
}
|
||||
}
|
||||
if ($b) {
|
||||
if (!isset($mergeArray[$b->getId()])) {
|
||||
$mergeArray[$b->getId()] = $b;
|
||||
}
|
||||
}
|
||||
}, $firstCompany, $badCompany);
|
||||
|
||||
|
||||
return $mergeArray;
|
||||
}
|
||||
|
||||
public function getTerritorySortByAds()
|
||||
|
||||
@@ -12,4 +12,27 @@ use Doctrine\ORM\EntityRepository;
|
||||
*/
|
||||
class UserRepository extends EntityRepository
|
||||
{
|
||||
public function findByRole($role)
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from($this->_entityName, 'u')
|
||||
->where('u.roles LIKE :roles')
|
||||
->setParameter('roles', '%"' . $role . '"%');
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function findTalentsAndCompanies()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from($this->_entityName, 'u')
|
||||
->where('u.roles LIKE :roleT')
|
||||
->orWhere('u.roles LIKE :roleC')
|
||||
->setParameter('roleC', '%ROLE_COMPANY%')
|
||||
->setParameter('roleT', '%ROLE_TALENT%');
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Security\Core\User;
|
||||
|
||||
|
||||
use FOS\UserBundle\Model\UserInterface as FOSUserInterface;
|
||||
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;
|
||||
|
||||
class FOSUBUserProvider extends BaseFOSUBProvider
|
||||
{
|
||||
protected $container;
|
||||
|
||||
public function __construct($userManager, $em, $slug, $container, array $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()){
|
||||
$userConnected = $this->container->get('security.token_storage')->getToken()->getUser();
|
||||
if ($userConnected->hasRole('ROLE_TALENT_TMP')) {
|
||||
$isTmpUser = true;
|
||||
$idTmpUser = $userConnected->getId();
|
||||
}
|
||||
}
|
||||
$this->disconnect($user, $response);
|
||||
$property = $this->getProperty($response);
|
||||
$username = $response->getUsername(); // get the unique user identifier
|
||||
$serviceName = $response->getResourceOwner()->getName();
|
||||
$propertyQuery = str_replace('_', '', lcfirst(ucwords($property, '_')));
|
||||
$setter = 'set' . ucfirst($serviceName) . 'Id';
|
||||
$setterToken = 'set' . ucfirst($serviceName) . 'AccessToken';
|
||||
$existingUser = $this->userManager->findUserBy(array($propertyQuery => $username));
|
||||
if (null === $existingUser) {
|
||||
$userEmail = $response->getEmail();
|
||||
$existingUser = $this->userManager->findUserByEmail($userEmail);
|
||||
}
|
||||
if (null !== $existingUser) {
|
||||
$this->disconnect($existingUser, $response);
|
||||
if($isTmpUser){
|
||||
$this->assignToRealAccount($userConnected, $existingUser);
|
||||
$user = $existingUser;
|
||||
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
|
||||
$this->container->get("security.token_storage")->setToken($token);
|
||||
}
|
||||
$existingUser->$setter($username);
|
||||
$existingUser->$setterToken($response->getAccessToken());
|
||||
$this->userManager->updateUser($existingUser);
|
||||
} else {
|
||||
if($isTmpUser){
|
||||
$existingUser = $this->loadUserByOAuthUserResponse($response);
|
||||
$this->assignToRealAccount($userConnected, $existingUser);
|
||||
$existingUser->$setter($username);
|
||||
$existingUser->$setterToken($response->getAccessToken());
|
||||
$this->userManager->updateUser($existingUser);
|
||||
|
||||
} else {
|
||||
$user->$setter($username);
|
||||
$user->$setterToken($response->getAccessToken());
|
||||
$this->userManager->updateUser($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
foreach ($medias as $key => $media) {
|
||||
$media->setCreator($existingUser);
|
||||
}
|
||||
$this->em->flush();
|
||||
foreach ($answers as $key => $answer) {
|
||||
$answer->setUser($existingUser);
|
||||
}
|
||||
$this->em->flush();
|
||||
$this->userManager->deleteUser($userConnected);
|
||||
}
|
||||
|
||||
public function loadUserByUsername($username)
|
||||
{
|
||||
$existingUser = $this->userManager->findUserByEmail($username);
|
||||
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}
|
||||
*/
|
||||
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
|
||||
{
|
||||
$serviceName = $response->getResourceOwner()->getName();
|
||||
$data = $response->getData();
|
||||
$userConnected = null;
|
||||
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"){
|
||||
$id = $data['id'];
|
||||
$birthday = null;
|
||||
$gender = null;
|
||||
$userPhoto = $data['pictureUrls']['values'][0];
|
||||
$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'];
|
||||
$id = $data['id'];
|
||||
$firstname = $data['first_name'];
|
||||
$lastname = $data['last_name'];
|
||||
}
|
||||
|
||||
if (null === $user) {
|
||||
$user = $this->userManager->createUser();
|
||||
$user->setUsername($firstname."-".$lastname);
|
||||
$user->setFirstname($firstname);
|
||||
$user->setLastname($lastname);
|
||||
$user->setEmail($userEmail);
|
||||
$user->setPlainPassword(uniqid());
|
||||
$user->setEnabled(true);
|
||||
$user->setSocialPicture($userPhoto);
|
||||
$user->setRoles(array('ROLE_TALENT'));
|
||||
$user->setBirthday($birthday);
|
||||
$user->setGender($gender);
|
||||
if($serviceName == "linkedin"){
|
||||
$user->setLinkedinId($id);
|
||||
}
|
||||
if($serviceName == "facebook"){
|
||||
$user->setFacebookId($id);
|
||||
}
|
||||
$this->userManager->updateUser($user);
|
||||
if ($user->getCompany() == null) {
|
||||
$company = new Company();
|
||||
$slugService = $this->slugService;
|
||||
$alias = $slugService->slugify($user->getId() . "-" . $user->getFirstname() . "-" . $user->getLastname());
|
||||
$company->setAlias($alias);
|
||||
$company->setType("TALENT");
|
||||
$user->setCompany($company);
|
||||
$this->userManager->updateUser($user);
|
||||
}
|
||||
|
||||
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
|
||||
$this->container->get("security.token_storage")->setToken($token);
|
||||
|
||||
return $user;
|
||||
} else {
|
||||
if($userConnected) {
|
||||
$userConnected->hasRole('ROLE_TALENT_TMP');
|
||||
if ($userConnected->hasRole('ROLE_TALENT_TMP')) {
|
||||
$user->setUsername($firstname."-".$lastname);
|
||||
$user->setFirstname($firstname);
|
||||
$user->setLastname($lastname);
|
||||
$user->setEmail($userEmail);
|
||||
$user->setPlainPassword(uniqid());
|
||||
$user->setEnabled(true);
|
||||
$user->setSocialPicture($userPhoto);
|
||||
$user->setRoles(array('ROLE_TALENT'));
|
||||
$user->setBirthday($birthday);
|
||||
$user->setGender($gender);
|
||||
if($serviceName == "linkedin"){
|
||||
$user->setLinkedinId($id);
|
||||
}
|
||||
if($serviceName == "facebook"){
|
||||
$user->setFacebookId($id);
|
||||
}
|
||||
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
|
||||
$this->container->get("security.token_storage")->setToken($token);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$serviceName = $response->getResourceOwner()->getName();
|
||||
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
|
||||
$user->$setter($response->getAccessToken());
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ use FOS\UserBundle\Event\FilterUserResponseEvent;
|
||||
use FOS\UserBundle\Event\FormEvent;
|
||||
use FOS\UserBundle\FOSUserEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
class RegistrationListener implements EventSubscriberInterface
|
||||
{
|
||||
@@ -16,12 +18,13 @@ class RegistrationListener implements EventSubscriberInterface
|
||||
protected $security;
|
||||
protected $router;
|
||||
|
||||
public function __construct($em, $slugService, $security, $router)
|
||||
public function __construct($em, $slugService, $security, $router, $userManager)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->slugService = $slugService;
|
||||
$this->security = $security;
|
||||
$this->router = $router;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
@@ -48,6 +51,29 @@ class RegistrationListener implements EventSubscriberInterface
|
||||
$user->addRole('ROLE_COMPANY');
|
||||
break;
|
||||
}
|
||||
$session = new Session();
|
||||
if ($session->get('registration_destination')) {
|
||||
$userConnected = $this->security->getToken()->getUser();
|
||||
$this->em->persist($user);
|
||||
$this->assignToRealAccount($userConnected, $user);
|
||||
$redirection = $session->get('registration_destination');
|
||||
$response = new RedirectResponse($redirection);
|
||||
$event->setResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
foreach ($medias as $key => $media) {
|
||||
$media->setCreator($existingUser);
|
||||
}
|
||||
$this->em->flush();
|
||||
foreach ($answers as $key => $answer) {
|
||||
$answer->setUser($existingUser);
|
||||
}
|
||||
$this->em->flush();
|
||||
$this->userManager->deleteUser($userConnected);
|
||||
}
|
||||
|
||||
public function redirectUser(FilterUserResponseEvent $event)
|
||||
|
||||
@@ -28,21 +28,19 @@ class MediaManager
|
||||
$this->env = $env;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rename video to vimeo
|
||||
*/
|
||||
|
||||
public function editName($video)
|
||||
{
|
||||
if($video){
|
||||
$response = $this->vimeo->request($video->getCdnUrl(), ['name'=>$video->getTitle()], 'PATCH');
|
||||
return array('success' => "true",'data' => $response);
|
||||
} else {
|
||||
public function editName($video)
|
||||
{
|
||||
if ($video) {
|
||||
$response = $this->vimeo->request($video->getCdnUrl(), ['name' => $video->getTitle()], 'PATCH');
|
||||
return array('success' => "true", 'data' => $response);
|
||||
} else {
|
||||
return array('success' => "false");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $entity
|
||||
@@ -50,7 +48,7 @@ class MediaManager
|
||||
*
|
||||
* Get Thumbnail of a video (Ad or Company)
|
||||
*/
|
||||
public function getThumbnails($entity)
|
||||
public function getThumbnails($entity, $force = false)
|
||||
{
|
||||
if ($entity instanceof Ad) {
|
||||
$video = $entity->getVideo();
|
||||
@@ -62,11 +60,11 @@ class MediaManager
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if($video){
|
||||
if ($video) {
|
||||
$arrayThumb = $video->getThumbnails();
|
||||
if (empty($arrayThumb[0])) {
|
||||
if ($force == true || empty($arrayThumb[0])) {
|
||||
$response = $this->vimeo->request($video->getCdnUrl() . '/pictures', [], 'GET');
|
||||
if(!isset($response['body']['error'])){
|
||||
if (!isset($response['body']['error'])) {
|
||||
$video->setThumbnails($response['body']['data']);
|
||||
$this->em->persist($video);
|
||||
$this->em->flush();
|
||||
@@ -84,7 +82,9 @@ class MediaManager
|
||||
{
|
||||
$video = $entity;
|
||||
if (unlink($this->mediaVideoDir . $video->getOriginalUrl())) {
|
||||
$response = $this->vimeo->request($video->getCdnUrl(), [], 'DELETE');
|
||||
if ($this->env != "dev") {
|
||||
$response = $this->vimeo->request($video->getCdnUrl(), [], 'DELETE');
|
||||
}
|
||||
$this->em->remove($video);
|
||||
$this->em->flush();
|
||||
|
||||
@@ -124,12 +124,12 @@ class MediaManager
|
||||
$metadata = array();
|
||||
//@TODO: trouver un fix pour la duration
|
||||
/*if($extension != "mkv"){
|
||||
$duration = $this->ffprobe->format($filePath)->get('duration');
|
||||
$metadata['duration'] = $duration;
|
||||
$duration = $this->ffprobe->format($filePath)->get('duration');
|
||||
$metadata['duration'] = $duration;
|
||||
}*/
|
||||
$thumbnails = array();
|
||||
//PUSH VIDEO TO Vimeo
|
||||
if ( $this->env == "dev" ) {
|
||||
//PUSH VIDEO TO Vimeo
|
||||
if ($this->env == "dev") {
|
||||
$uriVimeo = "/videos/215657518";
|
||||
$nameVimeo = "name";
|
||||
$linkVimeo = "/videos/215657518";
|
||||
@@ -141,8 +141,8 @@ class MediaManager
|
||||
$nameVimeo = $response['body']['name'];
|
||||
$linkVimeo = $response['body']['link'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//SAVE MEDIA
|
||||
$media->setCreator($creator);
|
||||
$media->setTitle($fileName);
|
||||
@@ -155,11 +155,15 @@ class MediaManager
|
||||
$this->em->persist($media);
|
||||
if (!is_null($entity)) {
|
||||
if ($entity instanceof Answer) {
|
||||
$media->setTitle("Video réponse à : ".$entity->getAd()->getTitle());
|
||||
if ($entity->getAd() == null) {
|
||||
$media->setTitle("Candidature pour : " . $entity->getCompany()->getBrandName());
|
||||
} else {
|
||||
$media->setTitle("Video réponse à : " . $entity->getAd()->getTitle());
|
||||
}
|
||||
$entity->setVideo($media);
|
||||
$this->em->persist($entity);
|
||||
} elseif ($entity instanceof Ad) {
|
||||
$media->setTitle("Video annonce de : ".$entity->getTitle());
|
||||
$media->setTitle("Video annonce de : " . $entity->getTitle());
|
||||
$entity->setVideo($media);
|
||||
$this->em->persist($entity);
|
||||
} elseif ($entity instanceof User) {
|
||||
@@ -169,7 +173,7 @@ class MediaManager
|
||||
$this->em->persist($entity);
|
||||
}
|
||||
} else {
|
||||
$media->setTitle("Vidéo ".$creator->getLastname()." ".$creator->getFirstname());
|
||||
$media->setTitle("Vidéo " . $creator->getLastname() . " " . $creator->getFirstname());
|
||||
}
|
||||
if ($creator->getCompany()->getType() == "TALENT") {
|
||||
$media->setStatus("TO_MODERATE");
|
||||
@@ -181,14 +185,14 @@ class MediaManager
|
||||
'filename' => $media->getTitle(),
|
||||
'originalFilename' => $uploadedFile->getClientOriginalName(),
|
||||
'uriVimeo' => str_replace('videos', 'video', $uriVimeo),
|
||||
'mediaId' => $media->getId()
|
||||
'mediaId' => $media->getId(),
|
||||
);
|
||||
} else {
|
||||
$message = array('success' => 500,
|
||||
'message' => "Error Upload"
|
||||
'message' => "Error Upload",
|
||||
);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ class StatsManager
|
||||
$lineDatesLabel[] = $stringDate;
|
||||
}
|
||||
}
|
||||
$arrByAd[$ad->getId()]['count'] ++;
|
||||
}
|
||||
$arrByAd[$ad->getId()]['count'] = $nbVisitTalentByAd + $nbVisitCompanyByAd + $nbVisitAnonymByAd;
|
||||
$arrByAd[$ad->getId()]['object'] = $ad;
|
||||
}
|
||||
}
|
||||
@@ -228,9 +228,9 @@ class StatsManager
|
||||
$lineDatesLabel[] = $stringDate;
|
||||
}
|
||||
}
|
||||
$arrByAd[$ad->getId()]['count'] ++;
|
||||
}
|
||||
}
|
||||
$arrByAd[$ad->getId()]['count'] = $nbVisitTalentByAd + $nbVisitCompanyByAd + $nbVisitAnonymByAd;
|
||||
$arrByAd[$ad->getId()]['object'] = $ad;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,12 +633,6 @@ class SymfonyRequirements extends RequirementCollection
|
||||
'Install and enable the <strong>mbstring</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('iconv'),
|
||||
'iconv() should be available',
|
||||
'Install and enable the <strong>iconv</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('utf8_decode'),
|
||||
'utf8_decode() should be available',
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/vendor
|
||||
/composer.lock
|
||||
@@ -0,0 +1,26 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
# - 5.3 # requires old distro, see below
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- hhvm # ignore errors, see below
|
||||
|
||||
# lock distro so new future defaults will not break the build
|
||||
dist: trusty
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
dist: precise
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
|
||||
install:
|
||||
- composer install --no-interaction
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit --coverage-text
|
||||
@@ -0,0 +1,54 @@
|
||||
# Changelog
|
||||
|
||||
## 1.4.0 (2017-08-18)
|
||||
|
||||
* Feature / Fix: The `fun()` function does not pass filter parameter `null`
|
||||
to underlying `stream_filter_append()` by default
|
||||
(#15 by @Nyholm)
|
||||
|
||||
Certain filters (such as `convert.quoted-printable-encode`) do not accept
|
||||
a filter parameter at all. If no explicit filter parameter is given, we no
|
||||
longer pass a default `null` value.
|
||||
|
||||
```php
|
||||
$encode = Filter\fun('convert.quoted-printable-encode');
|
||||
assert('t=C3=A4st' === $encode('täst'));
|
||||
```
|
||||
|
||||
* Add examples and improve documentation
|
||||
(#13 and #20 by @clue and #18 by @Nyholm)
|
||||
|
||||
* Improve test suite by adding PHPUnit to require-dev,
|
||||
fix HHVM build for now again and ignore future HHVM build errors,
|
||||
lock Travis distro so new future defaults will not break the build
|
||||
and test on PHP 7.1
|
||||
(#12, #14 and #19 by @clue and #16 by @Nyholm)
|
||||
|
||||
## 1.3.0 (2015-11-08)
|
||||
|
||||
* Feature: Support accessing built-in filters as callbacks
|
||||
(#5 by @clue)
|
||||
|
||||
```php
|
||||
$fun = Filter\fun('zlib.deflate');
|
||||
|
||||
$ret = $fun('hello') . $fun('world') . $fun();
|
||||
assert('helloworld' === gzinflate($ret));
|
||||
```
|
||||
|
||||
## 1.2.0 (2015-10-23)
|
||||
|
||||
* Feature: Invoke close event when closing filter (flush buffer)
|
||||
(#9 by @clue)
|
||||
|
||||
## 1.1.0 (2015-10-22)
|
||||
|
||||
* Feature: Abort filter operation when catching an Exception
|
||||
(#10 by @clue)
|
||||
|
||||
* Feature: Additional safeguards to prevent filter state corruption
|
||||
(#7 by @clue)
|
||||
|
||||
## 1.0.0 (2015-10-18)
|
||||
|
||||
* First tagged release
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Christian Lück
|
||||
|
||||
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,297 @@
|
||||
# clue/stream-filter [](https://travis-ci.org/clue/php-stream-filter)
|
||||
|
||||
A simple and modern approach to stream filtering in PHP
|
||||
|
||||
**Table of contents**
|
||||
|
||||
* [Why?](#why)
|
||||
* [Usage](#usage)
|
||||
* [append()](#append)
|
||||
* [prepend()](#prepend)
|
||||
* [fun()](#fun)
|
||||
* [remove()](#remove)
|
||||
* [Install](#install)
|
||||
* [Tests](#tests)
|
||||
* [License](#license)
|
||||
|
||||
## Why?
|
||||
|
||||
PHP's stream filtering system is great!
|
||||
|
||||
It offers very powerful stream filtering options and comes with a useful set of built-in filters.
|
||||
These filters can be used to easily and efficiently perform various transformations on-the-fly, such as:
|
||||
|
||||
* read from a gzip'ed input file,
|
||||
* transcode from ISO-8859-1 (Latin1) to UTF-8,
|
||||
* write to a bzip output file
|
||||
* and much more.
|
||||
|
||||
But let's face it:
|
||||
Its API is [*difficult to work with*](http://php.net/manual/en/php-user-filter.filter.php)
|
||||
and its documentation is [*subpar*](http://stackoverflow.com/questions/27103269/what-is-a-bucket-brigade).
|
||||
This combined means its powerful features are often neglected.
|
||||
|
||||
This project aims to make these features more accessible to a broader audience.
|
||||
* **Lightweight, SOLID design** -
|
||||
Provides a thin abstraction that is [*just good enough*](http://en.wikipedia.org/wiki/Principle_of_good_enough)
|
||||
and does not get in your way.
|
||||
Custom filters require trivial effort.
|
||||
* **Good test coverage** -
|
||||
Comes with an automated tests suite and is regularly tested in the *real world*
|
||||
|
||||
## Usage
|
||||
|
||||
This lightweight library consists only of a few simple functions.
|
||||
All functions reside under the `Clue\StreamFilter` namespace.
|
||||
|
||||
The below examples assume you use an import statement similar to this:
|
||||
|
||||
```php
|
||||
use Clue\StreamFilter as Filter;
|
||||
|
||||
Filter\append(…);
|
||||
```
|
||||
|
||||
Alternatively, you can also refer to them with their fully-qualified name:
|
||||
|
||||
```php
|
||||
\Clue\StreamFilter\append(…);
|
||||
```
|
||||
|
||||
### append()
|
||||
|
||||
The `append($stream, $callback, $read_write = STREAM_FILTER_ALL)` function can be used to
|
||||
append a filter callback to the given stream.
|
||||
|
||||
Each stream can have a list of filters attached.
|
||||
This function appends a filter to the end of this list.
|
||||
|
||||
This function returns a filter resource which can be passed to [`remove()`](#remove).
|
||||
If the given filter can not be added, it throws an `Exception`.
|
||||
|
||||
The `$stream` can be any valid stream resource, such as:
|
||||
|
||||
```php
|
||||
$stream = fopen('demo.txt', 'w+');
|
||||
```
|
||||
|
||||
The `$callback` should be a valid callable function which accepts an individual chunk of data
|
||||
and should return the updated chunk:
|
||||
|
||||
```php
|
||||
$filter = Filter\append($stream, function ($chunk) {
|
||||
// will be called each time you read or write a $chunk to/from the stream
|
||||
return $chunk;
|
||||
});
|
||||
```
|
||||
|
||||
As such, you can also use native PHP functions or any other `callable`:
|
||||
|
||||
```php
|
||||
Filter\append($stream, 'strtoupper');
|
||||
|
||||
// will write "HELLO" to the underlying stream
|
||||
fwrite($stream, 'hello');
|
||||
```
|
||||
|
||||
If the `$callback` accepts invocation without parameters, then this signature
|
||||
will be invoked once ending (flushing) the filter:
|
||||
|
||||
```php
|
||||
Filter\append($stream, function ($chunk = null) {
|
||||
if ($chunk === null) {
|
||||
// will be called once ending the filter
|
||||
return 'end';
|
||||
}
|
||||
// will be called each time you read or write a $chunk to/from the stream
|
||||
return $chunk;
|
||||
});
|
||||
|
||||
fclose($stream);
|
||||
```
|
||||
|
||||
> Note: Legacy PHP versions (PHP < 5.4) do not support passing additional data
|
||||
from the end signal handler if the stream is being closed.
|
||||
|
||||
If your callback throws an `Exception`, then the filter process will be aborted.
|
||||
In order to play nice with PHP's stream handling, the `Exception` will be
|
||||
transformed to a PHP warning instead:
|
||||
|
||||
```php
|
||||
Filter\append($stream, function ($chunk) {
|
||||
throw new \RuntimeException('Unexpected chunk');
|
||||
});
|
||||
|
||||
// raises an E_USER_WARNING with "Error invoking filter: Unexpected chunk"
|
||||
fwrite($stream, 'hello');
|
||||
```
|
||||
|
||||
The optional `$read_write` parameter can be used to only invoke the `$callback` when either writing to the stream or only when reading from the stream:
|
||||
|
||||
```php
|
||||
Filter\append($stream, function ($chunk) {
|
||||
// will be called each time you write to the stream
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
Filter\append($stream, function ($chunk) {
|
||||
// will be called each time you read from the stream
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_READ);
|
||||
```
|
||||
|
||||
> Note that once a filter has been added to stream, the stream can no longer be passed to
|
||||
> [`stream_select()`](http://php.net/manual/en/function.stream-select.php)
|
||||
> (and family).
|
||||
>
|
||||
> > Warning: stream_select(): cannot cast a filtered stream on this system in {file} on line {line}
|
||||
>
|
||||
> This is due to limitations of PHP's stream filter support, as it can no longer reliably
|
||||
> tell when the underlying stream resource is actually ready.
|
||||
> As an alternative, consider calling `stream_select()` on the unfiltered stream and
|
||||
> then pass the unfiltered data through the [`fun()`](#fun) function.
|
||||
|
||||
### prepend()
|
||||
|
||||
The `prepend($stream, $callback, $read_write = STREAM_FILTER_ALL)` function can be used to
|
||||
prepend a filter callback to the given stream.
|
||||
|
||||
Each stream can have a list of filters attached.
|
||||
This function prepends a filter to the start of this list.
|
||||
|
||||
This function returns a filter resource which can be passed to [`remove()`](#remove).
|
||||
If the given filter can not be added, it throws an `Exception`.
|
||||
|
||||
```php
|
||||
$filter = Filter\prepend($stream, function ($chunk) {
|
||||
// will be called each time you read or write a $chunk to/from the stream
|
||||
return $chunk;
|
||||
});
|
||||
```
|
||||
|
||||
Except for the position in the list of filters, this function behaves exactly
|
||||
like the [`append()`](#append) function.
|
||||
For more details about its behavior, see also the [`append()`](#append) function.
|
||||
|
||||
### fun()
|
||||
|
||||
The `fun($filter, $parameters = null)` function can be used to
|
||||
create a filter function which uses the given built-in `$filter`.
|
||||
|
||||
PHP comes with a useful set of [built-in filters](http://php.net/manual/en/filters.php).
|
||||
Using `fun()` makes accessing these as easy as passing an input string to filter
|
||||
and getting the filtered output string.
|
||||
|
||||
```php
|
||||
$fun = Filter\fun('string.rot13');
|
||||
|
||||
assert('grfg' === $fun('test'));
|
||||
assert('test' === $fun($fun('test'));
|
||||
```
|
||||
|
||||
Please note that not all filter functions may be available depending on installed
|
||||
PHP extensions and the PHP version in use.
|
||||
In particular, [HHVM](http://hhvm.com/) may not offer the same filter functions
|
||||
or parameters as Zend PHP.
|
||||
Accessing an unknown filter function will result in a `RuntimeException`:
|
||||
|
||||
```php
|
||||
Filter\fun('unknown'); // throws RuntimeException
|
||||
```
|
||||
|
||||
Some filters may accept or require additional filter parameters – most
|
||||
filters do not require filter parameters.
|
||||
If given, the optional `$parameters` argument will be passed to the
|
||||
underlying filter handler as-is.
|
||||
In particular, note how *not passing* this parameter at all differs from
|
||||
explicitly passing a `null` value (which many filters do not accept).
|
||||
Please refer to the individual filter definition for more details.
|
||||
For example, the `string.strip_tags` filter can be invoked like this:
|
||||
|
||||
```php
|
||||
$fun = Filter\fun('string.strip_tags', '<a><b>');
|
||||
|
||||
$ret = $fun('<b>h<br>i</b>');
|
||||
assert('<b>hi</b>' === $ret);
|
||||
```
|
||||
|
||||
Under the hood, this function allocates a temporary memory stream, so it's
|
||||
recommended to clean up the filter function after use.
|
||||
Also, some filter functions (in particular the
|
||||
[zlib compression filters](http://php.net/manual/en/filters.compression.php))
|
||||
may use internal buffers and may emit a final data chunk on close.
|
||||
The filter function can be closed by invoking without any arguments:
|
||||
|
||||
```php
|
||||
$fun = Filter\fun('zlib.deflate');
|
||||
|
||||
$ret = $fun('hello') . $fun('world') . $fun();
|
||||
assert('helloworld' === gzinflate($ret));
|
||||
```
|
||||
|
||||
The filter function must not be used anymore after it has been closed.
|
||||
Doing so will result in a `RuntimeException`:
|
||||
|
||||
```php
|
||||
$fun = Filter\fun('string.rot13');
|
||||
$fun();
|
||||
|
||||
$fun('test'); // throws RuntimeException
|
||||
```
|
||||
|
||||
> Note: If you're using the zlib compression filters, then you should be wary
|
||||
about engine inconsistencies between different PHP versions and HHVM.
|
||||
These inconsistencies exist in the underlying PHP engines and there's little we
|
||||
can do about this in this library.
|
||||
[Our test suite](tests/) contains several test cases that exhibit these issues.
|
||||
If you feel some test case is missing or outdated, we're happy to accept PRs! :)
|
||||
|
||||
### remove()
|
||||
|
||||
The `remove($filter)` function can be used to
|
||||
remove a filter previously added via [`append()`](#append) or [`prepend()`](#prepend).
|
||||
|
||||
```php
|
||||
$filter = Filter\append($stream, function () {
|
||||
// …
|
||||
});
|
||||
Filter\remove($filter);
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
The recommended way to install this library is [through Composer](https://getcomposer.org).
|
||||
[New to Composer?](https://getcomposer.org/doc/00-intro.md)
|
||||
|
||||
This will install the latest supported version:
|
||||
|
||||
```bash
|
||||
$ composer require clue/stream-filter:^1.4
|
||||
```
|
||||
|
||||
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
|
||||
|
||||
This project aims to run on any platform and thus does not require any PHP
|
||||
extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
|
||||
HHVM.
|
||||
It's *highly recommended to use PHP 7+* for this project.
|
||||
Older PHP versions may suffer from a number of inconsistencies documented above.
|
||||
|
||||
## Tests
|
||||
|
||||
To run the test suite, you first need to clone this repo and then install all
|
||||
dependencies [through Composer](http://getcomposer.org):
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
```
|
||||
|
||||
To run the test suite, go to the project root and run:
|
||||
|
||||
```bash
|
||||
$ php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "clue/stream-filter",
|
||||
"description": "A simple and modern approach to stream filtering in PHP",
|
||||
"keywords": ["stream", "callback", "filter", "php_user_filter", "stream_filter_append", "stream_filter_register", "bucket brigade"],
|
||||
"homepage": "https://github.com/clue/php-stream-filter",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@lueck.tv"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.0 || ^4.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Clue\\StreamFilter\\": "src/" },
|
||||
"files": [ "src/functions.php" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
// $ echo test | php examples/base64_encode.php | php examples/base64_decode.php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
// decoding requires buffering in chunks of 4 bytes each
|
||||
$buffer = '';
|
||||
Clue\StreamFilter\append(STDIN, function ($chunk = null) use (&$buffer) {
|
||||
if ($chunk === null) {
|
||||
if (strlen($buffer) % 4 !== 0) {
|
||||
throw new \UnexpectedValueException('Invalid length');
|
||||
}
|
||||
$chunk = $buffer;
|
||||
} else {
|
||||
$buffer .= $chunk;
|
||||
$len = strlen($buffer) - (strlen($buffer) % 4);
|
||||
$chunk = (string)substr($buffer, 0, $len);
|
||||
$buffer = (string)substr($buffer, $len);
|
||||
}
|
||||
|
||||
$ret = base64_decode($chunk, true);
|
||||
if ($ret === false) {
|
||||
throw new \UnexpectedValueException('Not a valid base64 encoded chunk');
|
||||
}
|
||||
return $ret;
|
||||
}, STREAM_FILTER_READ);
|
||||
|
||||
fpassthru(STDIN);
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
// $ echo test | php examples/base64_encode.php | base64 --decode
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
// encoding requires buffering in chunks of 3 bytes each
|
||||
$buffer = '';
|
||||
Clue\StreamFilter\append(STDIN, function ($chunk = null) use (&$buffer) {
|
||||
if ($chunk === null) {
|
||||
return base64_encode($buffer);
|
||||
}
|
||||
$buffer .= $chunk;
|
||||
$len = strlen($buffer) - (strlen($buffer) % 3);
|
||||
$chunk = substr($buffer, 0, $len);
|
||||
$buffer = substr($buffer, $len);
|
||||
|
||||
return base64_encode($chunk);
|
||||
}, STREAM_FILTER_READ);
|
||||
|
||||
fpassthru(STDIN);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// $ echo test | php examples/uppercase.php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
Clue\StreamFilter\append(STDIN, 'strtoupper');
|
||||
|
||||
fpassthru(STDIN);
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\StreamFilter;
|
||||
|
||||
use php_user_filter;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionFunction;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @see append()
|
||||
* @see prepend()
|
||||
*/
|
||||
class CallbackFilter extends php_user_filter
|
||||
{
|
||||
private $callback;
|
||||
private $closed = true;
|
||||
private $supportsClose = false;
|
||||
|
||||
public function onCreate()
|
||||
{
|
||||
$this->closed = false;
|
||||
|
||||
if (!is_callable($this->params)) {
|
||||
throw new InvalidArgumentException('No valid callback parameter given to stream_filter_(append|prepend)');
|
||||
}
|
||||
$this->callback = $this->params;
|
||||
|
||||
// callback supports end event if it accepts invocation without arguments
|
||||
$ref = new ReflectionFunction($this->callback);
|
||||
$this->supportsClose = ($ref->getNumberOfRequiredParameters() === 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onClose()
|
||||
{
|
||||
$this->closed = true;
|
||||
|
||||
// callback supports closing and is not already closed
|
||||
if ($this->supportsClose) {
|
||||
$this->supportsClose = false;
|
||||
// invoke without argument to signal end and discard resulting buffer
|
||||
try {
|
||||
call_user_func($this->callback);
|
||||
} catch (Exception $ignored) {
|
||||
// this might be called during engine shutdown, so it's not safe
|
||||
// to raise any errors or exceptions here
|
||||
// trigger_error('Error closing filter: ' . $ignored->getMessage(), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
$this->callback = null;
|
||||
}
|
||||
|
||||
public function filter($in, $out, &$consumed, $closing)
|
||||
{
|
||||
// concatenate whole buffer from input brigade
|
||||
$data = '';
|
||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||
$consumed += $bucket->datalen;
|
||||
$data .= $bucket->data;
|
||||
}
|
||||
|
||||
// skip processing callback that already ended
|
||||
if ($this->closed) {
|
||||
return PSFS_FEED_ME;
|
||||
}
|
||||
|
||||
// only invoke filter function if buffer is not empty
|
||||
// this may skip flushing a closing filter
|
||||
if ($data !== '') {
|
||||
try {
|
||||
$data = call_user_func($this->callback, $data);
|
||||
} catch (Exception $e) {
|
||||
// exception should mark filter as closed
|
||||
$this->onClose();
|
||||
trigger_error('Error invoking filter: ' . $e->getMessage(), E_USER_WARNING);
|
||||
|
||||
return PSFS_ERR_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
// mark filter as closed after processing closing chunk
|
||||
if ($closing) {
|
||||
$this->closed = true;
|
||||
|
||||
// callback supports closing and is not already closed
|
||||
if ($this->supportsClose) {
|
||||
$this->supportsClose = false;
|
||||
|
||||
// invoke without argument to signal end and append resulting buffer
|
||||
try {
|
||||
$data .= call_user_func($this->callback);
|
||||
} catch (Exception $e) {
|
||||
trigger_error('Error ending filter: ' . $e->getMessage(), E_USER_WARNING);
|
||||
|
||||
return PSFS_ERR_FATAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($data !== '') {
|
||||
// create a new bucket for writing the resulting buffer to the output brigade
|
||||
// reusing an existing bucket turned out to be bugged in some environments (ancient PHP versions and HHVM)
|
||||
$bucket = @stream_bucket_new($this->stream, $data);
|
||||
|
||||
// legacy PHP versions (PHP < 5.4) do not support passing data from the event signal handler
|
||||
// because closing the stream invalidates the stream and its stream bucket brigade before
|
||||
// invoking the filter close handler.
|
||||
if ($bucket !== false) {
|
||||
stream_bucket_append($out, $bucket);
|
||||
}
|
||||
}
|
||||
|
||||
return PSFS_PASS_ON;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\StreamFilter;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* append a callback filter to the given stream
|
||||
*
|
||||
* @param resource $stream
|
||||
* @param callable $callback
|
||||
* @param int $read_write
|
||||
* @return resource filter resource which can be used for `remove()`
|
||||
* @throws Exception on error
|
||||
* @uses stream_filter_append()
|
||||
*/
|
||||
function append($stream, $callback, $read_write = STREAM_FILTER_ALL)
|
||||
{
|
||||
$ret = @stream_filter_append($stream, register(), $read_write, $callback);
|
||||
|
||||
if ($ret === false) {
|
||||
$error = error_get_last() + array('message' => '');
|
||||
throw new RuntimeException('Unable to append filter: ' . $error['message']);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepend a callback filter to the given stream
|
||||
*
|
||||
* @param resource $stream
|
||||
* @param callable $callback
|
||||
* @param int $read_write
|
||||
* @return resource filter resource which can be used for `remove()`
|
||||
* @throws Exception on error
|
||||
* @uses stream_filter_prepend()
|
||||
*/
|
||||
function prepend($stream, $callback, $read_write = STREAM_FILTER_ALL)
|
||||
{
|
||||
$ret = @stream_filter_prepend($stream, register(), $read_write, $callback);
|
||||
|
||||
if ($ret === false) {
|
||||
$error = error_get_last() + array('message' => '');
|
||||
throw new RuntimeException('Unable to prepend filter: ' . $error['message']);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates filter fun (function) which uses the given built-in $filter
|
||||
*
|
||||
* Some filters may accept or require additional filter parameters – most
|
||||
* filters do not require filter parameters.
|
||||
* If given, the optional `$parameters` argument will be passed to the
|
||||
* underlying filter handler as-is.
|
||||
* In particular, note how *not passing* this parameter at all differs from
|
||||
* explicitly passing a `null` value (which many filters do not accept).
|
||||
* Please refer to the individual filter definition for more details.
|
||||
*
|
||||
* @param string $filter built-in filter name. See stream_get_filters() or http://php.net/manual/en/filters.php
|
||||
* @param mixed $parameters (optional) parameters to pass to the built-in filter as-is
|
||||
* @return callable a filter callback which can be append()'ed or prepend()'ed
|
||||
* @throws RuntimeException on error
|
||||
* @link http://php.net/manual/en/filters.php
|
||||
* @see stream_get_filters()
|
||||
* @see append()
|
||||
*/
|
||||
function fun($filter, $parameters = null)
|
||||
{
|
||||
$fp = fopen('php://memory', 'w');
|
||||
if (func_num_args() === 1) {
|
||||
$filter = @stream_filter_append($fp, $filter, STREAM_FILTER_WRITE);
|
||||
} else {
|
||||
$filter = @stream_filter_append($fp, $filter, STREAM_FILTER_WRITE, $parameters);
|
||||
}
|
||||
|
||||
if ($filter === false) {
|
||||
fclose($fp);
|
||||
$error = error_get_last() + array('message' => '');
|
||||
throw new RuntimeException('Unable to access built-in filter: ' . $error['message']);
|
||||
}
|
||||
|
||||
// append filter function which buffers internally
|
||||
$buffer = '';
|
||||
append($fp, function ($chunk) use (&$buffer) {
|
||||
$buffer .= $chunk;
|
||||
|
||||
// always return empty string in order to skip actually writing to stream resource
|
||||
return '';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
$closed = false;
|
||||
|
||||
return function ($chunk = null) use ($fp, $filter, &$buffer, &$closed) {
|
||||
if ($closed) {
|
||||
throw new \RuntimeException('Unable to perform operation on closed stream');
|
||||
}
|
||||
if ($chunk === null) {
|
||||
$closed = true;
|
||||
$buffer = '';
|
||||
fclose($fp);
|
||||
return $buffer;
|
||||
}
|
||||
// initialize buffer and invoke filters by attempting to write to stream
|
||||
$buffer = '';
|
||||
fwrite($fp, $chunk);
|
||||
|
||||
// buffer now contains everything the filter function returned
|
||||
return $buffer;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a callback filter from the given stream
|
||||
*
|
||||
* @param resource $filter
|
||||
* @return boolean true on success or false on error
|
||||
* @throws Exception on error
|
||||
* @uses stream_filter_remove()
|
||||
*/
|
||||
function remove($filter)
|
||||
{
|
||||
if (@stream_filter_remove($filter) === false) {
|
||||
throw new RuntimeException('Unable to remove given filter');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* registers the callback filter and returns the resulting filter name
|
||||
*
|
||||
* There should be little reason to call this function manually.
|
||||
*
|
||||
* @return string filter name
|
||||
* @uses CallbackFilter
|
||||
*/
|
||||
function register()
|
||||
{
|
||||
static $registered = null;
|
||||
if ($registered === null) {
|
||||
$registered = 'stream-callback';
|
||||
stream_filter_register($registered, __NAMESPACE__ . '\CallbackFilter');
|
||||
}
|
||||
return $registered;
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
|
||||
use Clue\StreamFilter;
|
||||
|
||||
class FilterTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testAppendSimpleCallback()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
return strtoupper($chunk);
|
||||
});
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
fwrite($stream, 'world');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('HELLOWORLD', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendNativePhpFunction()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, 'strtoupper');
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
fwrite($stream, 'world');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('HELLOWORLD', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendChangingChunkSize()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
return str_replace(array('a','e','i','o','u'), '', $chunk);
|
||||
});
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
fwrite($stream, 'world');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('hllwrld', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendReturningEmptyStringWillNotPassThrough()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
return '';
|
||||
});
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
fwrite($stream, 'world');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendEndEventCanBeBufferedOnClose()
|
||||
{
|
||||
if (PHP_VERSION < 5.4) $this->markTestSkipped('Not supported on legacy PHP');
|
||||
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, function ($chunk = null) {
|
||||
if ($chunk === null) {
|
||||
// this signals the end event
|
||||
return '!';
|
||||
}
|
||||
return $chunk . ' ';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
$buffered = '';
|
||||
StreamFilter\append($stream, function ($chunk) use (&$buffered) {
|
||||
$buffered .= $chunk;
|
||||
return '';
|
||||
});
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
fwrite($stream, 'world');
|
||||
|
||||
fclose($stream);
|
||||
|
||||
$this->assertEquals('hello world !', $buffered);
|
||||
}
|
||||
|
||||
public function testAppendEndEventWillBeCalledOnRemove()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
$ended = false;
|
||||
$filter = StreamFilter\append($stream, function ($chunk = null) use (&$ended) {
|
||||
if ($chunk === null) {
|
||||
$ended = true;
|
||||
}
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
$this->assertEquals(0, $ended);
|
||||
StreamFilter\remove($filter);
|
||||
$this->assertEquals(1, $ended);
|
||||
}
|
||||
|
||||
public function testAppendEndEventWillBeCalledOnClose()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
$ended = false;
|
||||
StreamFilter\append($stream, function ($chunk = null) use (&$ended) {
|
||||
if ($chunk === null) {
|
||||
$ended = true;
|
||||
}
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
$this->assertEquals(0, $ended);
|
||||
fclose($stream);
|
||||
$this->assertEquals(1, $ended);
|
||||
}
|
||||
|
||||
public function testAppendWriteOnly()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
$invoked = 0;
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) use (&$invoked) {
|
||||
++$invoked;
|
||||
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
fwrite($stream, 'a');
|
||||
fwrite($stream, 'b');
|
||||
fwrite($stream, 'c');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals(3, $invoked);
|
||||
$this->assertEquals('abc', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendReadOnly()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
$invoked = 0;
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) use (&$invoked) {
|
||||
++$invoked;
|
||||
|
||||
return $chunk;
|
||||
}, STREAM_FILTER_READ);
|
||||
|
||||
fwrite($stream, 'a');
|
||||
fwrite($stream, 'b');
|
||||
fwrite($stream, 'c');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals(0, $invoked);
|
||||
$this->assertEquals('abc', stream_get_contents($stream));
|
||||
$this->assertEquals(1, $invoked);
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testOrderCallingAppendAfterPrepend()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
return '[' . $chunk . ']';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
StreamFilter\prepend($stream, function ($chunk) {
|
||||
return '(' . $chunk . ')';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('[(hello)]', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testRemoveFilter()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
$first = StreamFilter\append($stream, function ($chunk) {
|
||||
return $chunk . '?';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
return $chunk . '!';
|
||||
}, STREAM_FILTER_WRITE);
|
||||
|
||||
StreamFilter\remove($first);
|
||||
|
||||
fwrite($stream, 'hello');
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('hello!', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendFunDechunk()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (dechunk filter does not exist)');
|
||||
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, StreamFilter\fun('dechunk'), STREAM_FILTER_WRITE);
|
||||
|
||||
fwrite($stream, "2\r\nhe\r\n");
|
||||
fwrite($stream, "3\r\nllo\r\n");
|
||||
fwrite($stream, "0\r\n\r\n");
|
||||
rewind($stream);
|
||||
|
||||
$this->assertEquals('hello', stream_get_contents($stream));
|
||||
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
public function testAppendThrows()
|
||||
{
|
||||
$this->createErrorHandler($errors);
|
||||
|
||||
$stream = $this->createStream();
|
||||
$this->createErrorHandler($errors);
|
||||
|
||||
StreamFilter\append($stream, function ($chunk) {
|
||||
throw new \DomainException($chunk);
|
||||
});
|
||||
|
||||
fwrite($stream, 'test');
|
||||
|
||||
$this->removeErrorHandler();
|
||||
$this->assertCount(1, $errors);
|
||||
$this->assertContains('test', $errors[0]);
|
||||
}
|
||||
|
||||
public function testAppendThrowsDuringEnd()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
$this->createErrorHandler($errors);
|
||||
|
||||
StreamFilter\append($stream, function ($chunk = null) {
|
||||
if ($chunk === null) {
|
||||
throw new \DomainException('end');
|
||||
}
|
||||
return $chunk;
|
||||
});
|
||||
|
||||
fclose($stream);
|
||||
|
||||
$this->removeErrorHandler();
|
||||
|
||||
// We can only assert we're not seeing an exception here…
|
||||
// * php 5.3-5.6 sees one error here
|
||||
// * php 7 does not see any error here
|
||||
// * hhvm sees the same error twice
|
||||
//
|
||||
// If you're curious:
|
||||
//
|
||||
// var_dump($errors);
|
||||
// $this->assertCount(1, $errors);
|
||||
// $this->assertContains('end', $errors[0]);
|
||||
}
|
||||
|
||||
public function testAppendThrowsShouldTriggerEnd()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
$this->createErrorHandler($errors);
|
||||
|
||||
$ended = false;
|
||||
StreamFilter\append($stream, function ($chunk = null) use (&$ended) {
|
||||
if ($chunk === null) {
|
||||
$ended = true;
|
||||
return '';
|
||||
}
|
||||
throw new \DomainException($chunk);
|
||||
});
|
||||
|
||||
$this->assertEquals(false, $ended);
|
||||
fwrite($stream, 'test');
|
||||
$this->assertEquals(true, $ended);
|
||||
|
||||
$this->removeErrorHandler();
|
||||
$this->assertCount(1, $errors);
|
||||
$this->assertContains('test', $errors[0]);
|
||||
}
|
||||
|
||||
public function testAppendThrowsShouldTriggerEndButIgnoreExceptionDuringEnd()
|
||||
{
|
||||
//$this->markTestIncomplete();
|
||||
$stream = $this->createStream();
|
||||
$this->createErrorHandler($errors);
|
||||
|
||||
StreamFilter\append($stream, function ($chunk = null) {
|
||||
if ($chunk === null) {
|
||||
$chunk = 'end';
|
||||
//return '';
|
||||
}
|
||||
throw new \DomainException($chunk);
|
||||
});
|
||||
|
||||
fwrite($stream, 'test');
|
||||
|
||||
$this->removeErrorHandler();
|
||||
$this->assertCount(1, $errors);
|
||||
$this->assertContains('test', $errors[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testAppendInvalidStreamIsRuntimeError()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid stream)');
|
||||
StreamFilter\append(false, function () { });
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testPrependInvalidStreamIsRuntimeError()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid stream)');
|
||||
StreamFilter\prepend(false, function () { });
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testRemoveInvalidFilterIsRuntimeError()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid filters)');
|
||||
StreamFilter\remove(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testInvalidCallbackIsInvalidArgument()
|
||||
{
|
||||
$stream = $this->createStream();
|
||||
|
||||
StreamFilter\append($stream, 'a-b-c');
|
||||
}
|
||||
|
||||
private function createStream()
|
||||
{
|
||||
return fopen('php://memory', 'r+');
|
||||
}
|
||||
|
||||
private function createErrorHandler(&$errors)
|
||||
{
|
||||
$errors = array();
|
||||
set_error_handler(function ($_, $message) use (&$errors) {
|
||||
$errors []= $message;
|
||||
});
|
||||
}
|
||||
|
||||
private function removeErrorHandler()
|
||||
{
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use Clue\StreamFilter as Filter;
|
||||
|
||||
class FunTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testFunInRot13()
|
||||
{
|
||||
$rot = Filter\fun('string.rot13');
|
||||
|
||||
$this->assertEquals('grfg', $rot('test'));
|
||||
$this->assertEquals('test', $rot($rot('test')));
|
||||
$this->assertEquals(null, $rot());
|
||||
}
|
||||
|
||||
public function testFunInQuotedPrintable()
|
||||
{
|
||||
$encode = Filter\fun('convert.quoted-printable-encode');
|
||||
$decode = Filter\fun('convert.quoted-printable-decode');
|
||||
|
||||
$this->assertEquals('t=C3=A4st', $encode('täst'));
|
||||
$this->assertEquals('täst', $decode($encode('täst')));
|
||||
$this->assertEquals(null, $encode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testFunWriteAfterCloseRot13()
|
||||
{
|
||||
$rot = Filter\fun('string.rot13');
|
||||
|
||||
$this->assertEquals(null, $rot());
|
||||
$rot('test');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testFunInvalid()
|
||||
{
|
||||
Filter\fun('unknown');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use Clue\StreamFilter;
|
||||
|
||||
class BuiltInZlibTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testFunZlibDeflateHelloWorld()
|
||||
{
|
||||
$deflate = StreamFilter\fun('zlib.deflate');
|
||||
|
||||
$data = $deflate('hello') . $deflate(' ') . $deflate('world') . $deflate();
|
||||
|
||||
$this->assertEquals(gzdeflate('hello world'), $data);
|
||||
}
|
||||
|
||||
public function testFunZlibDeflateEmpty()
|
||||
{
|
||||
if (PHP_VERSION >= 7) $this->markTestSkipped('Not supported on PHP7 (empty string does not invoke filter)');
|
||||
|
||||
$deflate = StreamFilter\fun('zlib.deflate');
|
||||
|
||||
//$data = gzdeflate('');
|
||||
$data = $deflate();
|
||||
|
||||
$this->assertEquals("\x03\x00", $data);
|
||||
}
|
||||
|
||||
public function testFunZlibDeflateBig()
|
||||
{
|
||||
$deflate = StreamFilter\fun('zlib.deflate');
|
||||
|
||||
$n = 1000;
|
||||
$expected = str_repeat('hello', $n);
|
||||
|
||||
$bytes = '';
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$bytes .= $deflate('hello');
|
||||
}
|
||||
$bytes .= $deflate();
|
||||
|
||||
$this->assertEquals($expected, gzinflate($bytes));
|
||||
}
|
||||
|
||||
public function testFunZlibInflateHelloWorld()
|
||||
{
|
||||
$inflate = StreamFilter\fun('zlib.inflate');
|
||||
|
||||
$data = $inflate(gzdeflate('hello world')) . $inflate();
|
||||
|
||||
$this->assertEquals('hello world', $data);
|
||||
}
|
||||
|
||||
public function testFunZlibInflateEmpty()
|
||||
{
|
||||
$inflate = StreamFilter\fun('zlib.inflate');
|
||||
|
||||
$data = $inflate("\x03\x00") . $inflate();
|
||||
|
||||
$this->assertEquals('', $data);
|
||||
}
|
||||
|
||||
public function testFunZlibInflateBig()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (final chunk will not be emitted)');
|
||||
|
||||
$inflate = StreamFilter\fun('zlib.inflate');
|
||||
|
||||
$expected = str_repeat('hello', 10);
|
||||
$bytes = gzdeflate($expected);
|
||||
|
||||
$ret = '';
|
||||
foreach (str_split($bytes, 2) as $chunk) {
|
||||
$ret .= $inflate($chunk);
|
||||
}
|
||||
$ret .= $inflate();
|
||||
|
||||
$this->assertEquals($expected, $ret);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ return array(
|
||||
'Locale' => $vendorDir . '/symfony/symfony/src/Symfony/Component/Intl/Resources/stubs/Locale.php',
|
||||
'NumberFormatter' => $vendorDir . '/symfony/symfony/src/Symfony/Component/Intl/Resources/stubs/NumberFormatter.php',
|
||||
'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
|
||||
'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
|
||||
'SqlFormatter' => $vendorDir . '/jdorn/sql-formatter/lib/SqlFormatter.php',
|
||||
'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
|
||||
);
|
||||
|
||||
@@ -6,15 +6,20 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php',
|
||||
'06dd8487319ccd8403765f5b8c9f2d61' => $vendorDir . '/alcaeus/mongo-php-adapter/lib/Mongo/functions.php',
|
||||
'92c8763cd6170fce6fcfe7e26b4e8c10' => $vendorDir . '/symfony/phpunit-bridge/bootstrap.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'ddc0a4d7e61c0286f0f8593b1903e894' => $vendorDir . '/clue/stream-filter/src/functions.php',
|
||||
'8cff32064859f4559445b89279f3199c' => $vendorDir . '/php-http/message/src/filters.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'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',
|
||||
'3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php',
|
||||
'ce89ac35a6c330c55f4710717db9ff78' => $vendorDir . '/kriswallsmith/assetic/src/functions.php',
|
||||
'06dd8487319ccd8403765f5b8c9f2d61' => $vendorDir . '/alcaeus/mongo-php-adapter/lib/Mongo/functions.php',
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user