major refactoring and cleanup
This commit is contained in:
36
README.md
36
README.md
@@ -1,22 +1,29 @@
|
||||
# Kimai - Time Tracking Application
|
||||
# Kimai v2 - Time Tracking
|
||||
|
||||
Kimai v2 - the reloaded open source Time-Tracking application, based on Symfony and powered by PHP.
|
||||
Kimai v2 - the reloaded open source Time-Tracking application.
|
||||
|
||||
[](https://travis-ci.org/kevinpapst/kimai2)
|
||||
|
||||
Requirements
|
||||
------------
|
||||
## Introduction
|
||||
|
||||
This is the reloaded version of the open source time-tracking application [Kimai](http://www.kimai.org).
|
||||
|
||||
It is based on the following components:
|
||||
- Symfony Framework 2.x
|
||||
- AdminLTE Control Panel Template (through the AdminThemeBundle)
|
||||
|
||||
## Requirements
|
||||
|
||||
* PHP 5.5.9 or higher;
|
||||
* One PHP extension of PDO-SQLite and/or PDO-MySQL enabled;
|
||||
* and the [usual Symfony application requirements](http://symfony.com/doc/current/reference/requirements.html).
|
||||
* bower (through npm)
|
||||
|
||||
If unsure about meeting these requirements, download the demo application and
|
||||
browse the `http://localhost:8000/config.php` script to get more detailed
|
||||
information.
|
||||
|
||||
Installation
|
||||
------------
|
||||
## Installation
|
||||
|
||||
[](https://heroku.com/deploy)
|
||||
|
||||
@@ -29,6 +36,13 @@ $ cd kimai2/
|
||||
$ composer install
|
||||
```
|
||||
|
||||
Lets prepare the environment
|
||||
```bash
|
||||
$ php bin/console assets:install --symlink
|
||||
$ php bin/console avanzu:admin:fetch-vendor
|
||||
```
|
||||
|
||||
|
||||
This was the basic task of the installation. If you have not yet setup a database, you
|
||||
can create it and import example data by executing these commands:
|
||||
```bash
|
||||
@@ -44,8 +58,7 @@ If you have imported the example data, you can login with two accounts:
|
||||
- Username: *tony_teamlead* / Password: *kitten* / Role: Teamlead
|
||||
- Username: *anna_admin* / Password: *kitten* / Role: Administrator
|
||||
|
||||
Usage
|
||||
-----
|
||||
## Usage
|
||||
|
||||
There is no need to configure a virtual host in your web server to access the application.
|
||||
Just use the built-in web server:
|
||||
@@ -65,3 +78,10 @@ terminal.
|
||||
> Kimai, configure it to point at the `web/` directory of the project.
|
||||
> For more details, see:
|
||||
> http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Cannot see any assets (like images) and/or missing styles? Try executing:
|
||||
```bash
|
||||
$ php bin/console assets:install --symlink
|
||||
```
|
||||
@@ -32,9 +32,9 @@ class AppKernel extends Kernel
|
||||
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
|
||||
new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
|
||||
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
|
||||
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
|
||||
new AppBundle\AppBundle(),
|
||||
new TimesheetBundle\TimesheetBundle(),
|
||||
new Avanzu\AdminThemeBundle\AvanzuAdminThemeBundle(),
|
||||
];
|
||||
|
||||
// Bundles only used for development or unit and functional tests
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{{ 'http_error.description'|trans({ '%status_code%': status_code }) }}
|
||||
</p>
|
||||
<p>
|
||||
{{ 'http_error.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
|
||||
{{ 'http_error.suggestion'|trans({ '%url%': path('homepage') })|raw }}
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{{ 'http_error_404.description'|trans }}
|
||||
</p>
|
||||
<p>
|
||||
{{ 'http_error_404.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
|
||||
{{ 'http_error_404.suggestion'|trans({ '%url%': path('homepage') })|raw }}
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{{ 'http_error_500.description'|trans }}
|
||||
</p>
|
||||
<p>
|
||||
{{ 'http_error_500.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
|
||||
{{ 'http_error_500.suggestion'|trans({ '%url%': path('homepage') })|raw }}
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -2,6 +2,52 @@
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
|
||||
<body>
|
||||
<trans-unit id="browser.title">
|
||||
<source>browser.title</source>
|
||||
<target>Kimai - Time Tracking</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="app.title">
|
||||
<source>app.title</source>
|
||||
<target>Kimai</target>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="http_error.name">
|
||||
<source>http_error.name</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error.description">
|
||||
<source>http_error.description</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error.suggestion">
|
||||
<source>http_error.suggestion</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_403.description">
|
||||
<source>http_error_403.description</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_403.suggestion">
|
||||
<source>http_error_403.suggestion</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_404.description">
|
||||
<source>http_error_404.description</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_404.suggestion">
|
||||
<source>http_error_404.suggestion</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_405.description">
|
||||
<source>http_error_405.description</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="http_error_405.suggestion">
|
||||
<source>http_error_405.suggestion</source>
|
||||
<target>Error</target>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="action.browse_admin">
|
||||
<source>action.browse_admin</source>
|
||||
<target>Zum Backend</target>
|
||||
@@ -38,10 +84,6 @@
|
||||
<source>menu.logout</source>
|
||||
<target>Abmelden</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu.homepage">
|
||||
<source>menu.homepage</source>
|
||||
<target>Blog</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu.admin">
|
||||
<source>menu.admin</source>
|
||||
<target>Backend</target>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
{#
|
||||
By default, forms enable client-side validation. This means that you can't
|
||||
test the server-side validation errors from the browser. To temporarily
|
||||
disable this validation, add the 'novalidate' attribute:
|
||||
|
||||
{{ form_start(form, { attr: { novalidate: 'novalidate' } }) }}
|
||||
#}
|
||||
|
||||
{% if show_confirmation|default(false) %}
|
||||
{% set attr = {'data-confirmation': 'true'} %}
|
||||
{{ include('blog/_delete_post_confirmation.html.twig') }}
|
||||
{% endif %}
|
||||
|
||||
{{ form_start(form, { attr: attr|default({}) }) }}
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<input type="submit" value="{{ button_label|default('label.create_post'|trans) }}"
|
||||
class="{{ button_css|default("btn btn-primary") }}" />
|
||||
|
||||
{% if include_back_to_home_link|default(false) %}
|
||||
<a href="{{ path('admin_post_index') }}" class="btn btn-link">
|
||||
{{ 'action.back_to_list'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{{ form_end(form) }}
|
||||
@@ -1,26 +0,0 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_edit' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.edit_post'|trans({'%id%': post.id}) }}</h1>
|
||||
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: edit_form,
|
||||
button_label: 'action.save'|trans,
|
||||
include_back_to_home_link: true,
|
||||
}, with_context = false) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section actions">
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: delete_form,
|
||||
button_label: 'action.delete_post'|trans,
|
||||
button_css: 'btn btn-lg btn-block btn-danger',
|
||||
show_confirmation: true,
|
||||
}, with_context = false) }}
|
||||
</div>
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -1,57 +0,0 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_index' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.post_list'|trans }}</h1>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'label.title'|trans }}</th>
|
||||
<th><i class="fa fa-user"></i> {{ 'label.author'|trans }}</th>
|
||||
<th><i class="fa fa-calendar"></i> {{ 'label.published_at'|trans }}</th>
|
||||
<th><i class="fa fa-cogs"></i> {{ 'label.actions'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for post in posts %}
|
||||
<tr>
|
||||
<td>{{ post.title }}</td>
|
||||
<td>{{ post.authorEmail }}</td>
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<td>{% if post.publishedAt %}{{ post.publishedAt|localizeddate('short', 'short', null, 'UTC') }}{% endif %}</td>
|
||||
<td>
|
||||
<div class="item-actions">
|
||||
<a href="{{ path('admin_post_show', { id: post.id }) }}" class="btn btn-sm btn-default">
|
||||
{{ 'action.show'|trans }}
|
||||
</a>
|
||||
|
||||
{% if post.isAuthor(app.user) %}
|
||||
<a href="{{ path('admin_post_edit', { id: post.id }) }}" class="btn btn-sm btn-primary">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4" align="center">{{ 'post.no_posts_found'|trans }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section actions">
|
||||
<a href="{{ path('admin_post_new') }}" class="btn btn-lg btn-block btn-success">
|
||||
<i class="fa fa-plus"></i> {{ 'action.create_post'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -1,27 +0,0 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_new' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.post_new'|trans }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.title) }}
|
||||
{{ form_row(form.summary) }}
|
||||
{{ form_row(form.content) }}
|
||||
{{ form_row(form.authorEmail) }}
|
||||
{{ form_row(form.publishedAt) }}
|
||||
|
||||
<input type="submit" value="{{ 'label.create_post'|trans }}" class="btn btn-primary" />
|
||||
|
||||
{{ form_widget(form.saveAndCreateNew, { label: 'label.save_and_create_new', attr: { class: 'btn btn-primary' } }) }}
|
||||
|
||||
<a href="{{ path('admin_post_index') }}" class="btn btn-link">
|
||||
{{ 'action.back_to_list'|trans }}
|
||||
</a>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_show' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>{{ 'label.summary'|trans }}</th>
|
||||
<td>{{ post.summary|md2html }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.content'|trans }}</th>
|
||||
<td>{{ post.content|md2html }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.author'|trans }}</th>
|
||||
<td><p>{{ post.authorEmail }}</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.published_at'|trans }}</th>
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<td><p>{{ post.publishedAt|localizeddate('long', 'medium', null, 'UTC') }}</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section">
|
||||
<a href="{{ path('admin_post_edit', { id: post.id }) }}" class="btn btn-lg btn-block btn-success">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit_contents'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: delete_form,
|
||||
button_label: 'action.delete_post'|trans,
|
||||
button_css: 'btn btn-lg btn-block btn-danger',
|
||||
show_confirmation: true,
|
||||
}, with_context = false) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,9 +0,0 @@
|
||||
{#
|
||||
This is the base template of the all backend pages.
|
||||
See http://symfony.com/doc/current/book/templating.html#template-inheritance-and-layouts
|
||||
#}
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block header_navigation_links %}
|
||||
{{ knp_menu_render('admin', {'template': 'menu/admin_menu.html.twig'}) }}
|
||||
{% endblock %}
|
||||
@@ -1,122 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>{% block title %}Symfony Demo application{% endblock %}</title>
|
||||
{% extends 'AvanzuAdminThemeBundle:layout:base-layout.html.twig' %}
|
||||
|
||||
{% block stylesheets %}
|
||||
{# uncomment the following lines to compile SCSS assets with Assetic
|
||||
{% block page_content %}
|
||||
{% block main %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% stylesheets filter="scssphp" output="css/app.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/bootstrap-flatly.scss"
|
||||
"%kernel.root_dir%/Resources/assets/scss/font-awesome.scss"
|
||||
"%kernel.root_dir%/Resources/assets/css/*.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/main.scss"
|
||||
%}
|
||||
<link rel="stylesheet" href="{{ asset_url }}" />
|
||||
{% endstylesheets %}
|
||||
#}
|
||||
{% block flash_messages %}
|
||||
{{ include('default/_flash_messages.html.twig') }}
|
||||
{% endblock %}
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{#
|
||||
<title>{% block title %}{{ 'browser.title'|trans }}{% endblock %}</title>
|
||||
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
|
||||
</head>
|
||||
|
||||
<body id="{% block body_id %}{% endblock %}">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-globe"></i> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu locales" role="menu">
|
||||
{% for locale in locales() %}
|
||||
<li {% if app.request.locale == locale.code %}class="active"{% endif %}><a href="{{ path(app.request.get('_route', 'homepage'), app.request.get('_route_params', [])|merge({ _locale: locale.code })) }}">{{ locale.name|capitalize }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
{% block header %}
|
||||
<header>
|
||||
<div class="navbar navbar-default navbar-static-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="{{ path('homepage') }}">
|
||||
Timesheet
|
||||
</a>
|
||||
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse"
|
||||
data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
|
||||
{% block header_navigation_links %}
|
||||
{{ knp_menu_render('main', {'template': 'menu/main_menu.html.twig'}) }}
|
||||
{% endblock %}
|
||||
<p>© {{ 'now'|date('Y') }} - {{ 'kimai.footer'|trans }}</p>
|
||||
<p>{{ 'kimai.license'|trans }}</p>
|
||||
|
||||
{#
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-globe"></i> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu locales" role="menu">
|
||||
{% for locale in locales() %}
|
||||
<li {% if app.request.locale == locale.code %}class="active"{% endif %}><a href="{{ path(app.request.get('_route', 'blog_index'), app.request.get('_route_params', [])|merge({ _locale: locale.code })) }}">{{ locale.name|capitalize }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
#}
|
||||
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
<div class="container body-container">
|
||||
{% block body %}
|
||||
<div class="row">
|
||||
<div id="main" class="col-sm-12">
|
||||
{{ include('default/_flash_messages.html.twig') }}
|
||||
|
||||
{% block main %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block footer %}
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div id="footer-copyright" class="col-md-6">
|
||||
<p>© {{ 'now'|date('Y') }} - {{ 'kimai.footer'|trans }}</p>
|
||||
<p>{{ 'kimai.license'|trans }}</p>
|
||||
</div>
|
||||
<div id="footer-resources" class="col-md-6">
|
||||
<p>
|
||||
<a href="https://twitter.com/symfony"><i class="fa fa-twitter"></i></a>
|
||||
<a href="https://www.facebook.com/SensioLabs"><i class="fa fa-facebook"></i></a>
|
||||
<a href="https://symfony.com/blog/"><i class="fa fa-rss"></i></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{# uncomment the following lines to combine and minimize JavaScript assets with Assetic
|
||||
{% javascripts filter="?jsqueeze" output="js/app.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/jquery-2.1.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/moment.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-3.3.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/highlight.pack.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-datetimepicker.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/main.js" %}
|
||||
<script src="{{ asset_url }}"></script>
|
||||
{% endjavascripts %}
|
||||
#}
|
||||
|
||||
<script src="{{ asset('js/app.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
</body>
|
||||
</html>
|
||||
#}
|
||||
@@ -1,35 +0,0 @@
|
||||
{#
|
||||
By default, forms enable client-side validation. This means that you can't
|
||||
test the server-side validation errors from the browser. To temporarily
|
||||
disable this validation, add the 'novalidate' attribute:
|
||||
|
||||
{{ form_start(form, { method: ..., action: ..., attr: { novalidate: 'novalidate' } }) }}
|
||||
#}
|
||||
|
||||
{{ form_start(form, { method: 'POST', action: path('comment_new', { 'postSlug': post.slug }) }) }}
|
||||
{# instead of displaying form fields one by one, you can also display them
|
||||
all with their default options and styles just by calling to this function:
|
||||
|
||||
{{ form_widget(form) }}
|
||||
#}
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ 'title.add_comment'|trans }}</legend>
|
||||
|
||||
{# Render any global form error (e.g. when a constraint on a public getter method failed) #}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<div class="form-group {% if not form.content.vars.valid %}has-error{% endif %}">
|
||||
{{ form_label(form.content, 'label.content', { label_attr: { class: 'hidden' }}) }}
|
||||
|
||||
{# Render any errors for the "content" field (e.g. when a class property constraint failed) #}
|
||||
{{ form_errors(form.content) }}
|
||||
|
||||
{{ form_widget(form.content, { attr: { rows: 10 } }) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button class="btn btn-primary pull-right" type="submit">{{ 'action.publish_comment'|trans }}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{ form_end(form) }}
|
||||
@@ -1,19 +0,0 @@
|
||||
{# Bootstrap modal, see http://getbootstrap.com/javascript/#modals #}
|
||||
<div class="modal fade" id="confirmationModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<h4>{{ 'delete_post_modal.title'|trans }}</h4>
|
||||
<p>{{ 'delete_post_modal.body'|trans }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" id="btnNo" data-dismiss="modal">
|
||||
{{ 'label.cancel'|trans }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger" id="btnYes" data-dismiss="modal">
|
||||
{{ 'label.delete_post'|trans }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,15 +0,0 @@
|
||||
<div class="section about">
|
||||
<div class="well well-lg">
|
||||
<p>
|
||||
{{ 'help.app_description'|trans|raw }}
|
||||
</p>
|
||||
<p>
|
||||
{{ 'help.more_information'|trans|raw }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<!-- Fragment rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
@@ -1,11 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'comment_form_error' %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-danger">{{ 'title.comment_error'|trans }}</h1>
|
||||
|
||||
<div class="well">
|
||||
{{ include('blog/_comment_form.html.twig') }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,27 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'blog_index' %}
|
||||
|
||||
{% block main %}
|
||||
{% for post in posts %}
|
||||
<article class="post">
|
||||
<h2>
|
||||
<a href="{{ path('blog_post', { slug: post.slug }) }}">
|
||||
{{ post.title }}
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
{{ post.summary|md2html }}
|
||||
</article>
|
||||
{% else %}
|
||||
<div class="well">{{ 'post.no_posts_found'|trans }}</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="navigation text-center">
|
||||
{{ pagerfanta(posts, 'twitter_bootstrap3_translated', { routeName: 'blog_index_paginated' }) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -1,64 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'blog_post_show' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
{{ post.content|md2html }}
|
||||
|
||||
<div id="post-add-comment" class="well">
|
||||
{# The 'IS_AUTHENTICATED_FULLY' role ensures that the user has entered
|
||||
his/her credentials (login + password) during this session. If he/she
|
||||
is automatically logged via the 'Remember Me' functionality, he/she won't
|
||||
be able to add a comment.
|
||||
See http://symfony.com/doc/current/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources
|
||||
#}
|
||||
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
|
||||
{{ render(controller('AppBundle:Blog:commentForm', { 'id': post.id })) }}
|
||||
{% else %}
|
||||
<p>
|
||||
<a class="btn btn-success" href="{{ path('security_login') }}">
|
||||
<i class="fa fa-sign-in"></i> {{ 'action.sign_in'|trans }}
|
||||
</a>
|
||||
{{ 'post.to_publish_a_comment'|trans }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h3>{{ 'post.num_comments'|transchoice(post.comments|length) }}</h3>
|
||||
|
||||
{% for comment in post.comments %}
|
||||
<div class="row post-comment">
|
||||
<h4 class="col-sm-3">
|
||||
<strong>{{ comment.authorEmail }}</strong> {{ 'post.commented_on'|trans }}
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<strong>{{ comment.publishedAt|localizeddate('medium', 'short', null, 'UTC') }}</strong>
|
||||
</h4>
|
||||
<div class="col-sm-9">
|
||||
{{ comment.content|md2html }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="post-comment">
|
||||
<p>{{ 'post.no_comments'|trans }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% if app.user and post.isAuthor(app.user) %}
|
||||
<div class="section">
|
||||
<a class="btn btn-lg btn-block btn-success" href="{{ path('admin_post_edit', { id: post.id }) }}">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit_post'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# the parent() function includes the contents defined by the parent template
|
||||
('base.html.twig') for this block ('sidebar'). This is a very convenient way
|
||||
to share common contents in different templates #}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
119
app/Resources/views/bootstrap.html.twig
Normal file
119
app/Resources/views/bootstrap.html.twig
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>{% block title %}{{ 'browser.title'|trans }}{% endblock %}</title>
|
||||
|
||||
{% block stylesheets %}
|
||||
{# uncomment the following lines to compile SCSS assets with Assetic
|
||||
|
||||
{% stylesheets filter="scssphp" output="css/app.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/bootstrap-flatly.scss"
|
||||
"%kernel.root_dir%/Resources/assets/scss/font-awesome.scss"
|
||||
"%kernel.root_dir%/Resources/assets/css/*.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/main.scss"
|
||||
%}
|
||||
<link rel="stylesheet" href="{{ asset_url }}" />
|
||||
{% endstylesheets %}
|
||||
#}
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
{% endblock %}
|
||||
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
|
||||
</head>
|
||||
|
||||
<body id="{% block body_id %}{% endblock %}">
|
||||
|
||||
{% block header %}
|
||||
<header>
|
||||
<div class="navbar navbar-default navbar-static-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="{{ path('homepage') }}">
|
||||
{{ 'app.title'|trans }}
|
||||
</a>
|
||||
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse"
|
||||
data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
{#
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-globe"></i> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu locales" role="menu">
|
||||
{% for locale in locales() %}
|
||||
<li {% if app.request.locale == locale.code %}class="active"{% endif %}><a href="{{ path(app.request.get('_route', 'blog_index'), app.request.get('_route_params', [])|merge({ _locale: locale.code })) }}">{{ locale.name|capitalize }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
#}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
<div class="container body-container">
|
||||
{% block body %}
|
||||
<div class="row">
|
||||
<div id="main" class="col-sm-12">
|
||||
{{ include('default/_flash_messages.html.twig') }}
|
||||
|
||||
{% block main %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block footer %}
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div id="footer-copyright" class="col-md-6">
|
||||
<p>© {{ 'now'|date('Y') }} - {{ 'kimai.footer'|trans }}</p>
|
||||
<p>{{ 'kimai.license'|trans }}</p>
|
||||
</div>
|
||||
<div id="footer-resources" class="col-md-6">
|
||||
{#
|
||||
<p>
|
||||
<a href="https://twitter.com/symfony"><i class="fa fa-twitter"></i></a>
|
||||
<a href="https://www.facebook.com/SensioLabs"><i class="fa fa-facebook"></i></a>
|
||||
<a href="https://symfony.com/blog/"><i class="fa fa-rss"></i></a>
|
||||
</p>
|
||||
#}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{# uncomment the following lines to combine and minimize JavaScript assets with Assetic
|
||||
{% javascripts filter="?jsqueeze" output="js/app.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/jquery-2.1.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/moment.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-3.3.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/highlight.pack.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-datetimepicker.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/main.js" %}
|
||||
<script src="{{ asset_url }}"></script>
|
||||
{% endjavascripts %}
|
||||
#}
|
||||
|
||||
<script src="{{ asset('js/app.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
</body>
|
||||
</html>
|
||||
7
app/Resources/views/dashboard/index.html.twig
Normal file
7
app/Resources/views/dashboard/index.html.twig
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}Dashboard{% endblock %}
|
||||
{% block page_subtitle %}Welcome!{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% endblock %}
|
||||
@@ -1 +0,0 @@
|
||||
{% extends 'menu/main_menu.html.twig' %}
|
||||
@@ -1,18 +0,0 @@
|
||||
{% extends 'knp_menu.html.twig' %}
|
||||
|
||||
{% block linkElement %}
|
||||
<a href="{{ item.uri }}"{{ knp_menu.attributes(item.linkAttributes) }}>
|
||||
{% if item.childrenAttributes.icon is defined %}
|
||||
<i class="fa fa-{{ item.childrenAttributes.icon }} }}"></i>
|
||||
{% endif %}
|
||||
{{ block('label') }}
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block label %}
|
||||
{% if options.allow_safe_labels and item.getExtra('safe_label', false) %}
|
||||
{{ item.label|raw }}
|
||||
{% else %}
|
||||
{{ item.label|trans }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% extends 'bootstrap.html.twig' %}
|
||||
|
||||
{% block body_id 'login' %}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
{{ parent() }}
|
||||
|
||||
<script>
|
||||
// FIXME remove me
|
||||
$(document).ready(function() {
|
||||
var usernameEl = $('#username');
|
||||
var passwordEl = $('#password');
|
||||
|
||||
@@ -57,6 +57,8 @@ twig:
|
||||
form_themes:
|
||||
- "bootstrap_3_layout.html.twig"
|
||||
- "form/fields.html.twig"
|
||||
globals:
|
||||
admin_skin: skin-blue
|
||||
|
||||
# Assetic Configuration (used for managing web assets: CSS, JavaScript, Sass, etc.)
|
||||
assetic:
|
||||
@@ -86,3 +88,6 @@ swiftmailer:
|
||||
username: "%mailer_user%"
|
||||
password: "%mailer_password%"
|
||||
spool: { type: memory }
|
||||
|
||||
#avanzu_admin_theme:
|
||||
# use_assetic: false
|
||||
|
||||
@@ -32,3 +32,8 @@ homepage:
|
||||
_controller: FrameworkBundle:Redirect:redirect
|
||||
route: timesheet
|
||||
permanent: true
|
||||
|
||||
avanzu_admin_profile:
|
||||
path: /profile/{userid}/
|
||||
avanzu_admin_logout:
|
||||
path: /logout
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
services:
|
||||
# First we define some basic services to make these utilities available in
|
||||
# the entire application
|
||||
slugger:
|
||||
class: AppBundle\Utils\Slugger
|
||||
|
||||
@@ -21,19 +19,21 @@ services:
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
|
||||
# a route listener, that injects the locale through a URL directory
|
||||
app.redirect_to_preferred_locale_listener:
|
||||
class: AppBundle\EventListener\RedirectToPreferredLocaleListener
|
||||
arguments: ['@router', '%app_locales%', '%locale%']
|
||||
tags:
|
||||
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
|
||||
|
||||
# event-listener to populate the navigation
|
||||
app.menu_builder:
|
||||
class: AppBundle\Menu\MenuBuilder
|
||||
arguments: ["@knp_menu.factory", "@event_dispatcher", "@security.authorization_checker"]
|
||||
class: AppBundle\EventListener\MenuBuilder
|
||||
arguments: ["@event_dispatcher", "@security.authorization_checker"]
|
||||
tags:
|
||||
- { name: knp_menu.menu_builder, method: createMainMenu, alias: main }
|
||||
- { name: knp_menu.menu_builder, method: createAdminMenu, alias: admin }
|
||||
- { name: kernel.event_listener, event:theme.sidebar_setup_menu, method:onSetupNavbar }
|
||||
|
||||
# service that prefixes every database table
|
||||
app.tableprefix_subscriber:
|
||||
class: AppBundle\Doctrine\TablePrefixSubscriber
|
||||
arguments: ["%database_prefix%"]
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"symfony/symfony": "^3.1",
|
||||
"twig/extensions": "^1.3",
|
||||
"white-october/pagerfanta-bundle": "^1.0",
|
||||
"knplabs/knp-menu-bundle": "^2.0"
|
||||
"avanzu/admin-theme-bundle": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"sensio/generator-bundle": "~3.0",
|
||||
|
||||
172
composer.lock
generated
172
composer.lock
generated
@@ -4,9 +4,54 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "5047e9bd8560365d5765f09e782b4ced",
|
||||
"content-hash": "7a606e9098e49dd364fa6e997f56e699",
|
||||
"hash": "8c9fa238b0d9190a97312f91782fb7a2",
|
||||
"content-hash": "5c5c4734f4e8e74afdfd434661f75a7d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "avanzu/admin-theme-bundle",
|
||||
"version": "1.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/avanzu/AdminThemeBundle.git",
|
||||
"reference": "24a1ac93ace744b5e8cffe6681009a4cc8f3a133"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/avanzu/AdminThemeBundle/zipball/24a1ac93ace744b5e8cffe6681009a4cc8f3a133",
|
||||
"reference": "24a1ac93ace744b5e8cffe6681009a4cc8f3a133",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/assetic-bundle": ">=2.3",
|
||||
"symfony/event-dispatcher": ">=2.3",
|
||||
"symfony/http-foundation": ">=2.3",
|
||||
"symfony/http-kernel": ">=2.3",
|
||||
"symfony/twig-bundle": ">=2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"hamcrest/hamcrest-php": "dev-master",
|
||||
"mockery/mockery": "0.9.*@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Avanzu\\AdminThemeBundle\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marc Bach",
|
||||
"email": "mail@avanzu.de"
|
||||
}
|
||||
],
|
||||
"description": "Admin Theme based on the AdminLTE Template for easy integration into symfony",
|
||||
"time": "2015-12-29 23:17:55"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "v1.2.7",
|
||||
@@ -1073,129 +1118,6 @@
|
||||
],
|
||||
"time": "2014-01-12 16:20:24"
|
||||
},
|
||||
{
|
||||
"name": "knplabs/knp-menu",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/KnpLabs/KnpMenu.git",
|
||||
"reference": "964b5b3ca7fd23019147991f4f75f361d061eb20"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/KnpLabs/KnpMenu/zipball/964b5b3ca7fd23019147991f4f75f361d061eb20",
|
||||
"reference": "964b5b3ca7fd23019147991f4f75f361d061eb20",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"pimple/pimple": "~1.0",
|
||||
"silex/silex": "~1.0",
|
||||
"symfony/phpunit-bridge": "~2.7|~3.0",
|
||||
"symfony/routing": "~2.3|~3.0",
|
||||
"twig/twig": "~1.16|~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"pimple/pimple": "for the built-in implementations of the menu provider and renderer provider",
|
||||
"silex/silex": "for the integration with your silex application",
|
||||
"twig/twig": "for the TwigRenderer and the integration with your templates"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Knp\\Menu\\": "src/Knp/Menu"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christophe Coevoet",
|
||||
"email": "stof@notk.org"
|
||||
},
|
||||
{
|
||||
"name": "KnpLabs",
|
||||
"homepage": "http://knplabs.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://github.com/KnpLabs/KnpMenu/contributors"
|
||||
}
|
||||
],
|
||||
"description": "An object oriented menu library",
|
||||
"homepage": "http://knplabs.com",
|
||||
"keywords": [
|
||||
"menu",
|
||||
"tree"
|
||||
],
|
||||
"time": "2016-09-22 07:36:19"
|
||||
},
|
||||
{
|
||||
"name": "knplabs/knp-menu-bundle",
|
||||
"version": "2.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/KnpLabs/KnpMenuBundle.git",
|
||||
"reference": "0e4af7209dc03e39c51ec70b68ab2ba3177c25de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/KnpLabs/KnpMenuBundle/zipball/0e4af7209dc03e39c51ec70b68ab2ba3177c25de",
|
||||
"reference": "0e4af7209dc03e39c51ec70b68ab2ba3177c25de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"knplabs/knp-menu": "~2.2",
|
||||
"symfony/framework-bundle": "~2.3|~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/expression-language": "~2.4|~3.0",
|
||||
"symfony/phpunit-bridge": "~2.7|~3.0"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Knp\\Bundle\\MenuBundle\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christophe Coevoet",
|
||||
"email": "stof@notk.org"
|
||||
},
|
||||
{
|
||||
"name": "Knplabs",
|
||||
"homepage": "http://knplabs.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://github.com/KnpLabs/KnpMenuBundle/contributors"
|
||||
}
|
||||
],
|
||||
"description": "This bundle provides an integration of the KnpMenu library",
|
||||
"keywords": [
|
||||
"menu"
|
||||
],
|
||||
"time": "2016-09-22 12:24:40"
|
||||
},
|
||||
{
|
||||
"name": "kriswallsmith/assetic",
|
||||
"version": "v1.3.2",
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use AppBundle\Entity\User;
|
||||
|
||||
/**
|
||||
* A command console that creates users and stores them in the database.
|
||||
* To use this command, open a terminal window, enter into your project
|
||||
* directory and execute the following:
|
||||
*
|
||||
* $ php bin/console app:add-user
|
||||
*
|
||||
* To output detailed information, increase the command verbosity:
|
||||
*
|
||||
* $ php bin/console app:add-user -vv
|
||||
*
|
||||
* See http://symfony.com/doc/current/cookbook/console/console_command.html
|
||||
*
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class AddUserCommand extends ContainerAwareCommand
|
||||
{
|
||||
const MAX_ATTEMPTS = 5;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
// a good practice is to use the 'app:' prefix to group all your custom application commands
|
||||
->setName('app:add-user')
|
||||
->setDescription('Creates users and stores them in the database')
|
||||
->setHelp($this->getCommandHelp())
|
||||
// commands can optionally define arguments and/or options (mandatory and optional)
|
||||
// see http://symfony.com/doc/current/components/console/console_arguments.html
|
||||
->addArgument('username', InputArgument::OPTIONAL, 'The username of the new user')
|
||||
->addArgument('password', InputArgument::OPTIONAL, 'The plain password of the new user')
|
||||
->addArgument('email', InputArgument::OPTIONAL, 'The email of the new user')
|
||||
->addOption('is-admin', null, InputOption::VALUE_NONE, 'If set, the user is created as an administrator')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed before the interact() and the execute() methods.
|
||||
* It's main purpose is to initialize the variables used in the rest of the
|
||||
* command methods.
|
||||
*
|
||||
* Beware that the input options and arguments are validated after executing
|
||||
* the interact() method, so you can't blindly trust their values in this method.
|
||||
*/
|
||||
protected function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->entityManager = $this->getContainer()->get('doctrine')->getManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed after initialize() and before execute(). Its purpose
|
||||
* is to check if some of the options/arguments are missing and interactively
|
||||
* ask the user for those values.
|
||||
*
|
||||
* This method is completely optional. If you are developing an internal console
|
||||
* command, you probably should not implement this method because it requires
|
||||
* quite a lot of work. However, if the command is meant to be used by external
|
||||
* users, this method is a nice way to fall back and prevent errors.
|
||||
*/
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (null !== $input->getArgument('username') && null !== $input->getArgument('password') && null !== $input->getArgument('email')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// multi-line messages can be displayed this way...
|
||||
$output->writeln('');
|
||||
$output->writeln('Add User Command Interactive Wizard');
|
||||
$output->writeln('-----------------------------------');
|
||||
|
||||
// ...but you can also pass an array of strings to the writeln() method
|
||||
$output->writeln([
|
||||
'',
|
||||
'If you prefer to not use this interactive wizard, provide the',
|
||||
'arguments required by this command as follows:',
|
||||
'',
|
||||
' $ php bin/console app:add-user username password email@example.com',
|
||||
'',
|
||||
]);
|
||||
|
||||
$output->writeln([
|
||||
'',
|
||||
'Now we\'ll ask you for the value of all the missing command arguments.',
|
||||
'',
|
||||
]);
|
||||
|
||||
// See http://symfony.com/doc/current/components/console/helpers/questionhelper.html
|
||||
$console = $this->getHelper('question');
|
||||
|
||||
// Ask for the username if it's not defined
|
||||
$username = $input->getArgument('username');
|
||||
if (null === $username) {
|
||||
$question = new Question(' > <info>Username</info>: ');
|
||||
$question->setValidator(function ($answer) {
|
||||
if (empty($answer)) {
|
||||
throw new \RuntimeException('The username cannot be empty');
|
||||
}
|
||||
|
||||
return $answer;
|
||||
});
|
||||
$question->setMaxAttempts(self::MAX_ATTEMPTS);
|
||||
|
||||
$username = $console->ask($input, $output, $question);
|
||||
$input->setArgument('username', $username);
|
||||
} else {
|
||||
$output->writeln(' > <info>Username</info>: '.$username);
|
||||
}
|
||||
|
||||
// Ask for the password if it's not defined
|
||||
$password = $input->getArgument('password');
|
||||
if (null === $password) {
|
||||
$question = new Question(' > <info>Password</info> (your type will be hidden): ');
|
||||
$question->setValidator([$this, 'passwordValidator']);
|
||||
$question->setHidden(true);
|
||||
$question->setMaxAttempts(self::MAX_ATTEMPTS);
|
||||
|
||||
$password = $console->ask($input, $output, $question);
|
||||
$input->setArgument('password', $password);
|
||||
} else {
|
||||
$output->writeln(' > <info>Password</info>: '.str_repeat('*', strlen($password)));
|
||||
}
|
||||
|
||||
// Ask for the email if it's not defined
|
||||
$email = $input->getArgument('email');
|
||||
if (null === $email) {
|
||||
$question = new Question(' > <info>Email</info>: ');
|
||||
$question->setValidator([$this, 'emailValidator']);
|
||||
$question->setMaxAttempts(self::MAX_ATTEMPTS);
|
||||
|
||||
$email = $console->ask($input, $output, $question);
|
||||
$input->setArgument('email', $email);
|
||||
} else {
|
||||
$output->writeln(' > <info>Email</info>: '.$email);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed after interact() and initialize(). It usually
|
||||
* contains the logic to execute to complete this command task.
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
|
||||
$username = $input->getArgument('username');
|
||||
$plainPassword = $input->getArgument('password');
|
||||
$email = $input->getArgument('email');
|
||||
$isAdmin = $input->getOption('is-admin');
|
||||
|
||||
// first check if a user with the same username already exists
|
||||
$existingUser = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $username]);
|
||||
|
||||
if (null !== $existingUser) {
|
||||
throw new \RuntimeException(sprintf('There is already a user registered with the "%s" username.', $username));
|
||||
}
|
||||
|
||||
// create the user and encode its password
|
||||
$user = new User();
|
||||
$user->setUsername($username);
|
||||
$user->setEmail($email);
|
||||
$user->setRoles([$isAdmin ? 'ROLE_ADMIN' : 'ROLE_USER']);
|
||||
|
||||
// See http://symfony.com/doc/current/book/security.html#security-encoding-password
|
||||
$encoder = $this->getContainer()->get('security.password_encoder');
|
||||
$encodedPassword = $encoder->encodePassword($user, $plainPassword);
|
||||
$user->setPassword($encodedPassword);
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln(sprintf('[OK] %s was successfully created: %s (%s)', $isAdmin ? 'Administrator user' : 'User', $user->getUsername(), $user->getEmail()));
|
||||
|
||||
if ($output->isVerbose()) {
|
||||
$finishTime = microtime(true);
|
||||
$elapsedTime = $finishTime - $startTime;
|
||||
|
||||
$output->writeln(sprintf('[INFO] New user database id: %d / Elapsed time: %.2f ms', $user->getId(), $elapsedTime*1000));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal method should be private, but it's declared as public to
|
||||
* maintain PHP 5.3 compatibility when using it in a callback.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function passwordValidator($plainPassword)
|
||||
{
|
||||
if (empty($plainPassword)) {
|
||||
throw new \Exception('The password can not be empty');
|
||||
}
|
||||
|
||||
if (strlen(trim($plainPassword)) < 6) {
|
||||
throw new \Exception('The password must be at least 6 characters long');
|
||||
}
|
||||
|
||||
return $plainPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal method should be private, but it's declared as public to
|
||||
* maintain PHP 5.3 compatibility when using it in a callback.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function emailValidator($email)
|
||||
{
|
||||
if (empty($email)) {
|
||||
throw new \Exception('The email can not be empty');
|
||||
}
|
||||
|
||||
if (false === strpos($email, '@')) {
|
||||
throw new \Exception('The email should look like a real email');
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* The command help is usually included in the configure() method, but when
|
||||
* it's too long, it's better to define a separate method to maintain the
|
||||
* code readability.
|
||||
*/
|
||||
private function getCommandHelp()
|
||||
{
|
||||
return <<<HELP
|
||||
The <info>%command.name%</info> command creates new users and saves them in the database:
|
||||
|
||||
<info>php %command.full_name%</info> <comment>username password email</comment>
|
||||
|
||||
By default the command creates regular users. To create administrator users,
|
||||
add the <comment>--is-admin</comment> option:
|
||||
|
||||
<info>php %command.full_name%</info> username password email <comment>--is-admin</comment>
|
||||
|
||||
If you omit any of the three required arguments, the command will ask you to
|
||||
provide the missing values:
|
||||
|
||||
# command will ask you for the email
|
||||
<info>php %command.full_name%</info> <comment>username password</comment>
|
||||
|
||||
# command will ask you for the email and password
|
||||
<info>php %command.full_name%</info> <comment>username</comment>
|
||||
|
||||
# command will ask you for all arguments
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
HELP;
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Command;
|
||||
|
||||
use AppBundle\Entity\User;
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
/**
|
||||
* A command console that deletes users from the database.
|
||||
* To use this command, open a terminal window, enter into your project
|
||||
* directory and execute the following:
|
||||
*
|
||||
* $ php bin/console app:delete-user
|
||||
*
|
||||
* Check out the code of the src/AppBundle/Command/AddUserCommand.php file for
|
||||
* the full explanation about Symfony commands.
|
||||
* See http://symfony.com/doc/current/cookbook/console/console_command.html
|
||||
*
|
||||
* @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
|
||||
*/
|
||||
class DeleteUserCommand extends ContainerAwareCommand
|
||||
{
|
||||
const MAX_ATTEMPTS = 5;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('app:delete-user')
|
||||
->setDescription('Deletes users from the database')
|
||||
->addArgument('username', InputArgument::REQUIRED, 'The username of an existing user')
|
||||
->setHelp(<<<HELP
|
||||
The <info>%command.name%</info> command deletes users from the database:
|
||||
|
||||
<info>php %command.full_name%</info> <comment>username</comment>
|
||||
|
||||
If you omit the argument, the command will ask you to
|
||||
provide the missing value:
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
HELP
|
||||
);
|
||||
}
|
||||
|
||||
protected function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->entityManager = $this->getContainer()->get('doctrine')->getManager();
|
||||
}
|
||||
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (null !== $input->getArgument('username')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln('Delete User Command Interactive Wizard');
|
||||
$output->writeln('-----------------------------------');
|
||||
|
||||
$output->writeln([
|
||||
'',
|
||||
'If you prefer to not use this interactive wizard, provide the',
|
||||
'arguments required by this command as follows:',
|
||||
'',
|
||||
' $ php bin/console app:delete-user username',
|
||||
'',
|
||||
]);
|
||||
|
||||
$output->writeln([
|
||||
'',
|
||||
'Now we\'ll ask you for the value of all the missing command arguments.',
|
||||
'',
|
||||
]);
|
||||
|
||||
$helper = $this->getHelper('question');
|
||||
|
||||
$question = new Question(' > <info>Username</info>: ');
|
||||
$question->setValidator([$this, 'usernameValidator']);
|
||||
$question->setMaxAttempts(self::MAX_ATTEMPTS);
|
||||
|
||||
$username = $helper->ask($input, $output, $question);
|
||||
$input->setArgument('username', $username);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$username = $input->getArgument('username');
|
||||
$this->usernameValidator($username);
|
||||
|
||||
$repository = $this->entityManager->getRepository(User::class);
|
||||
/** @var User $user */
|
||||
$user = $repository->findOneByUsername($username);
|
||||
|
||||
if (null === $user) {
|
||||
throw new \RuntimeException(sprintf('User with username "%s" not found.', $username));
|
||||
}
|
||||
|
||||
// After an entity has been removed its in-memory state is the same
|
||||
// as before the removal, except for generated identifiers.
|
||||
// See http://docs.doctrine-project.org/en/latest/reference/working-with-objects.html#removing-entities
|
||||
$userId = $user->getId();
|
||||
|
||||
$this->entityManager->remove($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln(sprintf('[OK] User "%s" (ID: %d, email: %s) was successfully deleted.', $user->getUsername(), $userId, $user->getEmail()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal method should be private, but it's declared public to
|
||||
* maintain PHP 5.3 compatibility when using it in a callback.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function usernameValidator($username)
|
||||
{
|
||||
if (empty($username)) {
|
||||
throw new \Exception('The username can not be empty.');
|
||||
}
|
||||
|
||||
if (1 !== preg_match('/^[a-z_]+$/', $username)) {
|
||||
throw new \Exception('The username must contain only lowercase latin characters and underscores.');
|
||||
}
|
||||
|
||||
return $username;
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Command;
|
||||
|
||||
use AppBundle\Entity\User;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
/**
|
||||
* A command console that lists all the existing users. To use this command, open
|
||||
* a terminal window, enter into your project directory and execute the following:
|
||||
*
|
||||
* $ php bin/console app:list-users
|
||||
*
|
||||
* See http://symfony.com/doc/current/cookbook/console/console_command.html
|
||||
*
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class ListUsersCommand extends ContainerAwareCommand
|
||||
{
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
// a good practice is to use the 'app:' prefix to group all your custom application commands
|
||||
->setName('app:list-users')
|
||||
->setDescription('Lists all the existing users')
|
||||
->setHelp(<<<HELP
|
||||
The <info>%command.name%</info> command lists all the users registered in the application:
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
By default the command only displays the 50 most recent users. Set the number of
|
||||
results to display with the <comment>--max-results</comment> option:
|
||||
|
||||
<info>php %command.full_name%</info> <comment>--max-results=2000</comment>
|
||||
|
||||
In addition to displaying the user list, you can also send this information to
|
||||
the email address specified in the <comment>--send-to</comment> option:
|
||||
|
||||
<info>php %command.full_name%</info> <comment>--send-to=fabien@symfony.com</comment>
|
||||
|
||||
HELP
|
||||
)
|
||||
// commands can optionally define arguments and/or options (mandatory and optional)
|
||||
// see http://symfony.com/doc/current/components/console/console_arguments.html
|
||||
->addOption('max-results', null, InputOption::VALUE_OPTIONAL, 'Limits the number of users listed', 50)
|
||||
->addOption('send-to', null, InputOption::VALUE_OPTIONAL, 'If set, the result is sent to the given email address')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed before the the execute() method. It's main purpose
|
||||
* is to initialize the variables used in the rest of the command methods.
|
||||
*/
|
||||
protected function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->entityManager = $this->getContainer()->get('doctrine')->getManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed after initialize(). It usually contains the logic
|
||||
* to execute to complete this command task.
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$maxResults = $input->getOption('max-results');
|
||||
// Use ->findBy() instead of ->findAll() to allow result sorting and limiting
|
||||
$users = $this->entityManager->getRepository(User::class)->findBy([], ['id' => 'DESC'], $maxResults);
|
||||
|
||||
// Doctrine query returns an array of objects and we need an array of plain arrays
|
||||
$usersAsPlainArrays = array_map(function (User $user) {
|
||||
return [$user->getId(), $user->getUsername(), $user->getEmail(), implode(', ', $user->getRoles())];
|
||||
}, $users);
|
||||
|
||||
// In your console commands you should always use the regular output type,
|
||||
// which outputs contents directly in the console window. However, this
|
||||
// particular command uses the BufferedOutput type instead.
|
||||
// The reason is that the table displaying the list of users can be sent
|
||||
// via email if the '--send-to' option is provided. Instead of complicating
|
||||
// things, the BufferedOutput allows to get the command output and store
|
||||
// it in a variable before displaying it.
|
||||
$bufferedOutput = new BufferedOutput();
|
||||
|
||||
$table = new Table($bufferedOutput);
|
||||
$table
|
||||
->setHeaders(['ID', 'Username', 'Email', 'Roles'])
|
||||
->setRows($usersAsPlainArrays)
|
||||
;
|
||||
$table->render();
|
||||
|
||||
// instead of displaying the table of users, store it in a variable
|
||||
$tableContents = $bufferedOutput->fetch();
|
||||
|
||||
if (null !== $email = $input->getOption('send-to')) {
|
||||
$this->sendReport($tableContents, $email);
|
||||
}
|
||||
|
||||
$output->writeln($tableContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given $contents to the $recipient email address.
|
||||
*
|
||||
* @param string $contents
|
||||
* @param string $recipient
|
||||
*/
|
||||
private function sendReport($contents, $recipient)
|
||||
{
|
||||
// See http://symfony.com/doc/current/cookbook/email/email.html
|
||||
$mailer = $this->getContainer()->get('mailer');
|
||||
|
||||
$message = $mailer->createMessage()
|
||||
->setSubject(sprintf('app:list-users report (%s)', date('Y-m-d H:i:s')))
|
||||
->setFrom($this->getContainer()->getParameter('app.notifications.email_sender'))
|
||||
->setTo($recipient)
|
||||
->setBody($contents, 'text/plain')
|
||||
;
|
||||
|
||||
$mailer->send($message);
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Controller\Admin;
|
||||
|
||||
use AppBundle\Entity\Post;
|
||||
use AppBundle\Form\PostType;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Controller used to manage blog contents in the backend.
|
||||
*
|
||||
* Please note that the application backend is developed manually for learning
|
||||
* purposes. However, in your real Symfony application you should use any of the
|
||||
* existing bundles that let you generate ready-to-use backends without effort.
|
||||
* See http://knpbundles.com/keyword/admin
|
||||
*
|
||||
* @Route("/admin/post")
|
||||
* @Security("has_role('ROLE_ADMIN')")
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class BlogController extends Controller
|
||||
{
|
||||
/**
|
||||
* Lists all Post entities.
|
||||
*
|
||||
* This controller responds to two different routes with the same URL:
|
||||
* * 'admin_post_index' is the route with a name that follows the same
|
||||
* structure as the rest of the controllers of this class.
|
||||
* * 'admin_index' is a nice shortcut to the backend homepage. This allows
|
||||
* to create simpler links in the templates. Moreover, in the future we
|
||||
* could move this annotation to any other controller while maintaining
|
||||
* the route name and therefore, without breaking any existing link.
|
||||
*
|
||||
* @Route("/", name="admin_index")
|
||||
* @Route("/", name="admin_post_index")
|
||||
* @Method("GET")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$posts = $entityManager->getRepository(Post::class)->findAll();
|
||||
|
||||
return $this->render('admin/blog/index.html.twig', ['posts' => $posts]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Post entity.
|
||||
*
|
||||
* @Route("/new", name="admin_post_new")
|
||||
* @Method({"GET", "POST"})
|
||||
*
|
||||
* NOTE: the Method annotation is optional, but it's a recommended practice
|
||||
* to constraint the HTTP methods each controller responds to (by default
|
||||
* it responds to all methods).
|
||||
*/
|
||||
public function newAction(Request $request)
|
||||
{
|
||||
$post = new Post();
|
||||
$post->setAuthorEmail($this->getUser()->getEmail());
|
||||
|
||||
// See http://symfony.com/doc/current/book/forms.html#submitting-forms-with-multiple-buttons
|
||||
$form = $this->createForm(PostType::class, $post)
|
||||
->add('saveAndCreateNew', SubmitType::class);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
// the isSubmitted() method is completely optional because the other
|
||||
// isValid() method already checks whether the form is submitted.
|
||||
// However, we explicitly add it to improve code readability.
|
||||
// See http://symfony.com/doc/current/best_practices/forms.html#handling-form-submits
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$post->setSlug($this->get('slugger')->slugify($post->getTitle()));
|
||||
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($post);
|
||||
$entityManager->flush();
|
||||
|
||||
// Flash messages are used to notify the user about the result of the
|
||||
// actions. They are deleted automatically from the session as soon
|
||||
// as they are accessed.
|
||||
// See http://symfony.com/doc/current/book/controller.html#flash-messages
|
||||
$this->addFlash('success', 'post.created_successfully');
|
||||
|
||||
if ($form->get('saveAndCreateNew')->isClicked()) {
|
||||
return $this->redirectToRoute('admin_post_new');
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('admin_post_index');
|
||||
}
|
||||
|
||||
return $this->render('admin/blog/new.html.twig', [
|
||||
'post' => $post,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and displays a Post entity.
|
||||
*
|
||||
* @Route("/{id}", requirements={"id": "\d+"}, name="admin_post_show")
|
||||
* @Method("GET")
|
||||
*/
|
||||
public function showAction(Post $post)
|
||||
{
|
||||
// This security check can also be performed:
|
||||
// 1. Using an annotation: @Security("post.isAuthor(user)")
|
||||
// 2. Using a "voter" (see http://symfony.com/doc/current/cookbook/security/voters_data_permission.html)
|
||||
if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
|
||||
throw $this->createAccessDeniedException('Posts can only be shown to their authors.');
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($post);
|
||||
|
||||
return $this->render('admin/blog/show.html.twig', [
|
||||
'post' => $post,
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form to edit an existing Post entity.
|
||||
*
|
||||
* @Route("/{id}/edit", requirements={"id": "\d+"}, name="admin_post_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
*/
|
||||
public function editAction(Post $post, Request $request)
|
||||
{
|
||||
if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
|
||||
throw $this->createAccessDeniedException('Posts can only be edited by their authors.');
|
||||
}
|
||||
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
$editForm = $this->createForm(PostType::class, $post);
|
||||
$deleteForm = $this->createDeleteForm($post);
|
||||
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$post->setSlug($this->get('slugger')->slugify($post->getTitle()));
|
||||
$entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'post.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_post_edit', ['id' => $post->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('admin/blog/edit.html.twig', [
|
||||
'post' => $post,
|
||||
'edit_form' => $editForm->createView(),
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a Post entity.
|
||||
*
|
||||
* @Route("/{id}", name="admin_post_delete")
|
||||
* @Method("DELETE")
|
||||
* @Security("post.isAuthor(user)")
|
||||
*
|
||||
* The Security annotation value is an expression (if it evaluates to false,
|
||||
* the authorization mechanism will prevent the user accessing this resource).
|
||||
* The isAuthor() method is defined in the AppBundle\Entity\Post entity.
|
||||
*/
|
||||
public function deleteAction(Request $request, Post $post)
|
||||
{
|
||||
$form = $this->createDeleteForm($post);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
$entityManager->remove($post);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'post.deleted_successfully');
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('admin_post_index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form to delete a Post entity by id.
|
||||
*
|
||||
* This is necessary because browsers don't support HTTP methods different
|
||||
* from GET and POST. Since the controller that removes the blog posts expects
|
||||
* a DELETE method, the trick is to create a simple form that *fakes* the
|
||||
* HTTP DELETE method.
|
||||
* See http://symfony.com/doc/current/cookbook/routing/method_parameters.html.
|
||||
*
|
||||
* @param Post $post The post object
|
||||
*
|
||||
* @return \Symfony\Component\Form\Form The form
|
||||
*/
|
||||
private function createDeleteForm(Post $post)
|
||||
{
|
||||
return $this->createFormBuilder()
|
||||
->setAction($this->generateUrl('admin_post_delete', ['id' => $post->getId()]))
|
||||
->setMethod('DELETE')
|
||||
->getForm()
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use AppBundle\Entity\Comment;
|
||||
use AppBundle\Entity\Post;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
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\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use AppBundle\Form\CommentType;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Controller used to manage blog contents in the public part of the site.
|
||||
*
|
||||
* @Route("/blog")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class BlogController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="blog_index")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="blog_index_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page)
|
||||
{
|
||||
$posts = $this->getDoctrine()->getRepository(Post::class)->findLatest($page);
|
||||
|
||||
return $this->render('blog/index.html.twig', ['posts' => $posts]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/posts/{slug}", name="blog_post")
|
||||
* @Method("GET")
|
||||
*
|
||||
* NOTE: The $post controller argument is automatically injected by Symfony
|
||||
* after performing a database query looking for a Post with the 'slug'
|
||||
* value given in the route.
|
||||
* See http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
|
||||
*/
|
||||
public function postShowAction(Post $post)
|
||||
{
|
||||
// Symfony provides a function called 'dump()' which is an improved version
|
||||
// of the 'var_dump()' function. It's useful to quickly debug the contents
|
||||
// of any variable, but it's not available in the 'prod' environment to
|
||||
// prevent any leak of sensitive information.
|
||||
// This function can be used both in PHP files and Twig templates. The only
|
||||
// requirement is to have enabled the DebugBundle.
|
||||
if ('dev' === $this->getParameter('kernel.environment')) {
|
||||
dump($post, $this->get('security.token_storage')->getToken()->getUser(), new \DateTime());
|
||||
}
|
||||
|
||||
return $this->render('blog/post_show.html.twig', ['post' => $post]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/comment/{postSlug}/new", name="comment_new")
|
||||
* @Method("POST")
|
||||
* @Security("is_granted('IS_AUTHENTICATED_FULLY')")
|
||||
* @ParamConverter("post", options={"mapping": {"postSlug": "slug"}})
|
||||
*
|
||||
* NOTE: The ParamConverter mapping is required because the route parameter
|
||||
* (postSlug) doesn't match any of the Doctrine entity properties (slug).
|
||||
* See http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html#doctrine-converter
|
||||
*/
|
||||
public function commentNewAction(Request $request, Post $post)
|
||||
{
|
||||
$form = $this->createForm(CommentType::class);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var Comment $comment */
|
||||
$comment = $form->getData();
|
||||
$comment->setAuthorEmail($this->getUser()->getEmail());
|
||||
$comment->setPost($post);
|
||||
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($comment);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('blog_post', ['slug' => $post->getSlug()]);
|
||||
}
|
||||
|
||||
return $this->render('blog/comment_form_error.html.twig', [
|
||||
'post' => $post,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This controller is called directly via the render() function in the
|
||||
* blog/post_show.html.twig template. That's why it's not needed to define
|
||||
* a route name for it.
|
||||
*
|
||||
* The "id" of the Post is passed in and then turned into a Post object
|
||||
* automatically by the ParamConverter.
|
||||
*
|
||||
* @param Post $post
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function commentFormAction(Post $post)
|
||||
{
|
||||
$form = $this->createForm(CommentType::class);
|
||||
|
||||
return $this->render('blog/_comment_form.html.twig', [
|
||||
'post' => $post,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
39
src/AppBundle/Controller/DashboardController.php
Normal file
39
src/AppBundle/Controller/DashboardController.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use TimesheetBundle\Entity\Timesheet;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
|
||||
/**
|
||||
* Dashboard controller for the admin area.
|
||||
*
|
||||
* @Route("/dashboard")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/", defaults={}, name="dashboard")
|
||||
* @Method("GET")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
return $this->render('dashboard/index.html.twig', []);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -12,23 +12,15 @@
|
||||
namespace AppBundle\DataFixtures\ORM;
|
||||
|
||||
use AppBundle\Entity\User;
|
||||
use AppBundle\Entity\Post;
|
||||
use AppBundle\Entity\Comment;
|
||||
use Doctrine\Common\DataFixtures\FixtureInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines the sample data to load in the database when running the unit and
|
||||
* functional tests. Execute this command to load the data:
|
||||
* Sample data to load in the database when running tests or for development
|
||||
*
|
||||
* $ php bin/console doctrine:fixtures:load
|
||||
*
|
||||
* See http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class LoadFixtures implements FixtureInterface, ContainerAwareInterface
|
||||
{
|
||||
@@ -40,9 +32,8 @@ class LoadFixtures implements FixtureInterface, ContainerAwareInterface
|
||||
*/
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
// FIXME CAN BE REMOVED
|
||||
$this->loadUsers($manager);
|
||||
$this->loadPosts($manager);
|
||||
//$this->loadPosts($manager);
|
||||
}
|
||||
|
||||
private function loadUsers(ObjectManager $manager)
|
||||
@@ -84,8 +75,19 @@ class LoadFixtures implements FixtureInterface, ContainerAwareInterface
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* @param ObjectManager $manager
|
||||
*/
|
||||
private function loadPosts(ObjectManager $manager)
|
||||
{
|
||||
$authors = [
|
||||
'anna_admin@example.com',
|
||||
'tony_teamlead@example.com',
|
||||
'clara_customer@example.com',
|
||||
'john_user@example.com'
|
||||
];
|
||||
foreach (range(1, 30) as $i) {
|
||||
$post = new Post();
|
||||
|
||||
@@ -93,13 +95,13 @@ class LoadFixtures implements FixtureInterface, ContainerAwareInterface
|
||||
$post->setSummary($this->getRandomPostSummary());
|
||||
$post->setSlug($this->container->get('slugger')->slugify($post->getTitle()));
|
||||
$post->setContent($this->getPostContent());
|
||||
$post->setAuthorEmail(array_rand(['anna_admin@example.com', 'tony_teamlead@example.com'], 1));
|
||||
$post->setAuthorEmail($authors[array_rand($authors, 1)]);
|
||||
$post->setPublishedAt(new \DateTime('now - '.$i.'days'));
|
||||
|
||||
foreach (range(1, 5) as $j) {
|
||||
$comment = new Comment();
|
||||
|
||||
$comment->setAuthorEmail(array_rand(['clara_customer@example.com', 'john_user@example.com'], 1));
|
||||
$comment->setAuthorEmail($authors[array_rand($authors, 1)]);
|
||||
$comment->setPublishedAt(new \DateTime('now + '.($i + $j).'seconds'));
|
||||
$comment->setContent($this->getRandomCommentContent());
|
||||
$comment->setPost($post);
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="demo_comment")
|
||||
*
|
||||
* Defines the properties of the Comment entity to represent the blog comments.
|
||||
* See http://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
|
||||
*
|
||||
* Tip: if you have an existing database, you can generate these entity class automatically.
|
||||
* See http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class Comment
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Post", inversedBy="comments")
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
*/
|
||||
private $post;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
* @Assert\NotBlank(message="comment.blank")
|
||||
* @Assert\Length(
|
||||
* min = "5",
|
||||
* minMessage = "comment.too_short",
|
||||
* max = "10000",
|
||||
* maxMessage = "comment.too_long"
|
||||
* )
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @Assert\Email()
|
||||
*/
|
||||
private $authorEmail;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
* @Assert\DateTime()
|
||||
*/
|
||||
private $publishedAt;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->publishedAt = new \DateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Assert\IsTrue(message = "comment.is_spam")
|
||||
*/
|
||||
public function isLegitComment()
|
||||
{
|
||||
$containsInvalidCharacters = false !== strpos($this->content, '@');
|
||||
|
||||
return !$containsInvalidCharacters;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getAuthorEmail()
|
||||
{
|
||||
return $this->authorEmail;
|
||||
}
|
||||
public function setAuthorEmail($authorEmail)
|
||||
{
|
||||
$this->authorEmail = $authorEmail;
|
||||
}
|
||||
|
||||
public function getPublishedAt()
|
||||
{
|
||||
return $this->publishedAt;
|
||||
}
|
||||
public function setPublishedAt(\DateTime $publishedAt)
|
||||
{
|
||||
$this->publishedAt = $publishedAt;
|
||||
}
|
||||
|
||||
public function getPost()
|
||||
{
|
||||
return $this->post;
|
||||
}
|
||||
public function setPost(Post $post)
|
||||
{
|
||||
$this->post = $post;
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,13 @@ namespace AppBundle\Entity;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiConfiguration
|
||||
* Configuration
|
||||
*
|
||||
* @ORM\Table(name="configuration")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiConfiguration
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="value", type="string", length=255, nullable=false)
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -28,14 +22,19 @@ class KimaiConfiguration
|
||||
*/
|
||||
private $option;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="value", type="string", length=255, nullable=false)
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Set value
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return KimaiConfiguration
|
||||
* @return Configuration
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
@@ -1,345 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiExpenses
|
||||
*
|
||||
* @ORM\Table(name="expenses", indexes={@ORM\Index(name="userID", columns={"userID"}), @ORM\Index(name="projectID", columns={"projectID"})})
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiExpenses
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="timestamp", type="integer", nullable=false)
|
||||
*/
|
||||
private $timestamp = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="userID", type="integer", nullable=false)
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer", nullable=false)
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="designation", type="text", length=65535, nullable=false)
|
||||
*/
|
||||
private $designation;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="comment", type="text", length=65535, nullable=true)
|
||||
*/
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="commentType", type="boolean", nullable=false)
|
||||
*/
|
||||
private $commenttype = '0';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="refundable", type="boolean", nullable=false)
|
||||
*/
|
||||
private $refundable = '0';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="cleared", type="boolean", nullable=false)
|
||||
*/
|
||||
private $cleared = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="multiplier", type="decimal", precision=10, scale=2, nullable=false)
|
||||
*/
|
||||
private $multiplier = '1.00';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="value", type="decimal", precision=10, scale=2, nullable=false)
|
||||
*/
|
||||
private $value = '0.00';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="expenseID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $expenseid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set timestamp
|
||||
*
|
||||
* @param integer $timestamp
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setTimestamp($timestamp)
|
||||
{
|
||||
$this->timestamp = $timestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timestamp
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set userid
|
||||
*
|
||||
* @param integer $userid
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setUserid($userid)
|
||||
{
|
||||
$this->userid = $userid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getUserid()
|
||||
{
|
||||
return $this->userid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set projectid
|
||||
*
|
||||
* @param integer $projectid
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setProjectid($projectid)
|
||||
{
|
||||
$this->projectid = $projectid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectid()
|
||||
{
|
||||
return $this->projectid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set designation
|
||||
*
|
||||
* @param string $designation
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setDesignation($designation)
|
||||
{
|
||||
$this->designation = $designation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get designation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDesignation()
|
||||
{
|
||||
return $this->designation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set comment
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set commenttype
|
||||
*
|
||||
* @param boolean $commenttype
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setCommenttype($commenttype)
|
||||
{
|
||||
$this->commenttype = $commenttype;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get commenttype
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getCommenttype()
|
||||
{
|
||||
return $this->commenttype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set refundable
|
||||
*
|
||||
* @param boolean $refundable
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setRefundable($refundable)
|
||||
{
|
||||
$this->refundable = $refundable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refundable
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getRefundable()
|
||||
{
|
||||
return $this->refundable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cleared
|
||||
*
|
||||
* @param boolean $cleared
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setCleared($cleared)
|
||||
{
|
||||
$this->cleared = $cleared;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cleared
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getCleared()
|
||||
{
|
||||
return $this->cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set multiplier
|
||||
*
|
||||
* @param string $multiplier
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setMultiplier($multiplier)
|
||||
{
|
||||
$this->multiplier = $multiplier;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiplier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMultiplier()
|
||||
{
|
||||
return $this->multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return KimaiExpenses
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get expenseid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getExpenseid()
|
||||
{
|
||||
return $this->expenseid;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiFixedrates
|
||||
*
|
||||
* @ORM\Table(name="fixedRates")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiFixedrates
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="rate", type="decimal", precision=10, scale=2, nullable=false)
|
||||
*/
|
||||
private $rate;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="activityID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $activityid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set rate
|
||||
*
|
||||
* @param string $rate
|
||||
*
|
||||
* @return KimaiFixedrates
|
||||
*/
|
||||
public function setRate($rate)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRate()
|
||||
{
|
||||
return $this->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set projectid
|
||||
*
|
||||
* @param integer $projectid
|
||||
*
|
||||
* @return KimaiFixedrates
|
||||
*/
|
||||
public function setProjectid($projectid)
|
||||
{
|
||||
$this->projectid = $projectid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectid()
|
||||
{
|
||||
return $this->projectid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activityid
|
||||
*
|
||||
* @param integer $activityid
|
||||
*
|
||||
* @return KimaiFixedrates
|
||||
*/
|
||||
public function setActivityid($activityid)
|
||||
{
|
||||
$this->activityid = $activityid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activityid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getActivityid()
|
||||
{
|
||||
return $this->activityid;
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiProjectsActivities
|
||||
*
|
||||
* @ORM\Table(name="projects_activities")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiProjectsActivities
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="budget", type="decimal", precision=10, scale=2, nullable=true)
|
||||
*/
|
||||
private $budget = '0.00';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="effort", type="decimal", precision=10, scale=2, nullable=true)
|
||||
*/
|
||||
private $effort;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="approved", type="decimal", precision=10, scale=2, nullable=true)
|
||||
*/
|
||||
private $approved;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="activityID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $activityid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set budget
|
||||
*
|
||||
* @param string $budget
|
||||
*
|
||||
* @return KimaiProjectsActivities
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get budget
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBudget()
|
||||
{
|
||||
return $this->budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set effort
|
||||
*
|
||||
* @param string $effort
|
||||
*
|
||||
* @return KimaiProjectsActivities
|
||||
*/
|
||||
public function setEffort($effort)
|
||||
{
|
||||
$this->effort = $effort;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get effort
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEffort()
|
||||
{
|
||||
return $this->effort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set approved
|
||||
*
|
||||
* @param string $approved
|
||||
*
|
||||
* @return KimaiProjectsActivities
|
||||
*/
|
||||
public function setApproved($approved)
|
||||
{
|
||||
$this->approved = $approved;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get approved
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApproved()
|
||||
{
|
||||
return $this->approved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set projectid
|
||||
*
|
||||
* @param integer $projectid
|
||||
*
|
||||
* @return KimaiProjectsActivities
|
||||
*/
|
||||
public function setProjectid($projectid)
|
||||
{
|
||||
$this->projectid = $projectid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectid()
|
||||
{
|
||||
return $this->projectid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activityid
|
||||
*
|
||||
* @param integer $activityid
|
||||
*
|
||||
* @return KimaiProjectsActivities
|
||||
*/
|
||||
public function setActivityid($activityid)
|
||||
{
|
||||
$this->activityid = $activityid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activityid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getActivityid()
|
||||
{
|
||||
return $this->activityid;
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiRates
|
||||
*
|
||||
* @ORM\Table(name="rates")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiRates
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="rate", type="decimal", precision=10, scale=2, nullable=false)
|
||||
*/
|
||||
private $rate;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="userID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="activityID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $activityid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set rate
|
||||
*
|
||||
* @param string $rate
|
||||
*
|
||||
* @return KimaiRates
|
||||
*/
|
||||
public function setRate($rate)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRate()
|
||||
{
|
||||
return $this->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set userid
|
||||
*
|
||||
* @param integer $userid
|
||||
*
|
||||
* @return KimaiRates
|
||||
*/
|
||||
public function setUserid($userid)
|
||||
{
|
||||
$this->userid = $userid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getUserid()
|
||||
{
|
||||
return $this->userid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set projectid
|
||||
*
|
||||
* @param integer $projectid
|
||||
*
|
||||
* @return KimaiRates
|
||||
*/
|
||||
public function setProjectid($projectid)
|
||||
{
|
||||
$this->projectid = $projectid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectid()
|
||||
{
|
||||
return $this->projectid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activityid
|
||||
*
|
||||
* @param integer $activityid
|
||||
*
|
||||
* @return KimaiRates
|
||||
*/
|
||||
public function setActivityid($activityid)
|
||||
{
|
||||
$this->activityid = $activityid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activityid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getActivityid()
|
||||
{
|
||||
return $this->activityid;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiStatuses
|
||||
*
|
||||
* @ORM\Table(name="statuses")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiStatuses
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="status", type="string", length=200, nullable=false)
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="statusID", type="boolean")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $statusid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set status
|
||||
*
|
||||
* @param string $status
|
||||
*
|
||||
* @return KimaiStatuses
|
||||
*/
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->status = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statusid
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getStatusid()
|
||||
{
|
||||
return $this->statusid;
|
||||
}
|
||||
}
|
||||
@@ -1,562 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiUsers
|
||||
*
|
||||
* @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="name", columns={"name"}), @ORM\UniqueConstraint(name="apikey", columns={"apikey"})})
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiUsers
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="name", type="string", length=160, nullable=false)
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="alias", type="string", length=160, nullable=true)
|
||||
*/
|
||||
private $alias;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="trash", type="boolean", nullable=false)
|
||||
*/
|
||||
private $trash = '0';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="active", type="boolean", nullable=false)
|
||||
*/
|
||||
private $active = '1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="mail", type="string", length=160, nullable=false)
|
||||
*/
|
||||
private $mail = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="password", type="string", length=254, nullable=true)
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="passwordResetHash", type="string", length=32, nullable=true)
|
||||
*/
|
||||
private $passwordresethash;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="ban", type="integer", nullable=false)
|
||||
*/
|
||||
private $ban = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="banTime", type="integer", nullable=false)
|
||||
*/
|
||||
private $bantime = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="secure", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $secure = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastProject", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastproject = '1';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastActivity", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastactivity = '1';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastRecord", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastrecord = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="timeframeBegin", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $timeframebegin = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="timeframeEnd", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $timeframeend = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="apikey", type="string", length=30, nullable=true)
|
||||
*/
|
||||
private $apikey;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="globalRoleID", type="integer", nullable=false)
|
||||
*/
|
||||
private $globalroleid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="userID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alias
|
||||
*
|
||||
* @param string $alias
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setAlias($alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set trash
|
||||
*
|
||||
* @param boolean $trash
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTrash($trash)
|
||||
{
|
||||
$this->trash = $trash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trash
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getTrash()
|
||||
{
|
||||
return $this->trash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active
|
||||
*
|
||||
* @param boolean $active
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setActive($active)
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getActive()
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mail
|
||||
*
|
||||
* @param string $mail
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setMail($mail)
|
||||
{
|
||||
$this->mail = $mail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mail
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMail()
|
||||
{
|
||||
return $this->mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get password
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set passwordresethash
|
||||
*
|
||||
* @param string $passwordresethash
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setPasswordresethash($passwordresethash)
|
||||
{
|
||||
$this->passwordresethash = $passwordresethash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get passwordresethash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPasswordresethash()
|
||||
{
|
||||
return $this->passwordresethash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ban
|
||||
*
|
||||
* @param integer $ban
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setBan($ban)
|
||||
{
|
||||
$this->ban = $ban;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ban
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getBan()
|
||||
{
|
||||
return $this->ban;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bantime
|
||||
*
|
||||
* @param integer $bantime
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setBantime($bantime)
|
||||
{
|
||||
$this->bantime = $bantime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bantime
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getBantime()
|
||||
{
|
||||
return $this->bantime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set secure
|
||||
*
|
||||
* @param string $secure
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setSecure($secure)
|
||||
{
|
||||
$this->secure = $secure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get secure
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecure()
|
||||
{
|
||||
return $this->secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastproject
|
||||
*
|
||||
* @param integer $lastproject
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastproject($lastproject)
|
||||
{
|
||||
$this->lastproject = $lastproject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastproject
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastproject()
|
||||
{
|
||||
return $this->lastproject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastactivity
|
||||
*
|
||||
* @param integer $lastactivity
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastactivity($lastactivity)
|
||||
{
|
||||
$this->lastactivity = $lastactivity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastactivity
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastactivity()
|
||||
{
|
||||
return $this->lastactivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastrecord
|
||||
*
|
||||
* @param integer $lastrecord
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastrecord($lastrecord)
|
||||
{
|
||||
$this->lastrecord = $lastrecord;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastrecord
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastrecord()
|
||||
{
|
||||
return $this->lastrecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeframebegin
|
||||
*
|
||||
* @param string $timeframebegin
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTimeframebegin($timeframebegin)
|
||||
{
|
||||
$this->timeframebegin = $timeframebegin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timeframebegin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeframebegin()
|
||||
{
|
||||
return $this->timeframebegin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeframeend
|
||||
*
|
||||
* @param string $timeframeend
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTimeframeend($timeframeend)
|
||||
{
|
||||
$this->timeframeend = $timeframeend;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timeframeend
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeframeend()
|
||||
{
|
||||
return $this->timeframeend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set apikey
|
||||
*
|
||||
* @param string $apikey
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setApikey($apikey)
|
||||
{
|
||||
$this->apikey = $apikey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get apikey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApikey()
|
||||
{
|
||||
return $this->apikey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set globalroleid
|
||||
*
|
||||
* @param integer $globalroleid
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setGlobalroleid($globalroleid)
|
||||
{
|
||||
$this->globalroleid = $globalroleid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get globalroleid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getGlobalroleid()
|
||||
{
|
||||
return $this->globalroleid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getUserid()
|
||||
{
|
||||
return $this->userid;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
|
||||
* @ORM\Table(name="demo_post")
|
||||
*
|
||||
* Defines the properties of the Post entity to represent the blog posts.
|
||||
* See http://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
|
||||
*
|
||||
* Tip: if you have an existing database, you can generate these entity class automatically.
|
||||
* See http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class Post
|
||||
{
|
||||
/**
|
||||
* Use constants to define configuration options that rarely change instead
|
||||
* of specifying them in app/config/config.yml.
|
||||
* See http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options
|
||||
*/
|
||||
const NUM_ITEMS = 10;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @Assert\NotBlank(message="post.blank_summary")
|
||||
*/
|
||||
private $summary;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
* @Assert\NotBlank(message="post.blank_content")
|
||||
* @Assert\Length(min = "10", minMessage = "post.too_short_content")
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @Assert\Email()
|
||||
*/
|
||||
private $authorEmail;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
* @Assert\DateTime()
|
||||
*/
|
||||
private $publishedAt;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(
|
||||
* targetEntity="Comment",
|
||||
* mappedBy="post",
|
||||
* orphanRemoval=true
|
||||
* )
|
||||
* @ORM\OrderBy({"publishedAt" = "DESC"})
|
||||
*/
|
||||
private $comments;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->publishedAt = new \DateTime();
|
||||
$this->comments = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getSlug()
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug($slug)
|
||||
{
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getAuthorEmail()
|
||||
{
|
||||
return $this->authorEmail;
|
||||
}
|
||||
|
||||
public function setAuthorEmail($authorEmail)
|
||||
{
|
||||
$this->authorEmail = $authorEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the given User the author of this Post?
|
||||
*
|
||||
* @param User $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAuthor(User $user)
|
||||
{
|
||||
return $user->getEmail() === $this->getAuthorEmail();
|
||||
}
|
||||
|
||||
public function getPublishedAt()
|
||||
{
|
||||
return $this->publishedAt;
|
||||
}
|
||||
|
||||
public function setPublishedAt(\DateTime $publishedAt)
|
||||
{
|
||||
$this->publishedAt = $publishedAt;
|
||||
}
|
||||
|
||||
public function getComments()
|
||||
{
|
||||
return $this->comments;
|
||||
}
|
||||
|
||||
public function addComment(Comment $comment)
|
||||
{
|
||||
$this->comments->add($comment);
|
||||
$comment->setPost($this);
|
||||
}
|
||||
|
||||
public function removeComment(Comment $comment)
|
||||
{
|
||||
$this->comments->removeElement($comment);
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
public function setSummary($summary)
|
||||
{
|
||||
$this->summary = $summary;
|
||||
}
|
||||
}
|
||||
@@ -5,50 +5,499 @@ namespace AppBundle\Entity;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
* KimaiUsers
|
||||
*
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
|
||||
* @ORM\Table(name="demo_user")
|
||||
*
|
||||
* Defines the properties of the User entity to represent the application users.
|
||||
* See http://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
|
||||
*
|
||||
* Tip: if you have an existing database, you can generate these entity class automatically.
|
||||
* See http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
* @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="name", columns={"name"}), @ORM\UniqueConstraint(name="apikey", columns={"apikey"})})
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class User implements UserInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Column(name="userID", type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", unique=true)
|
||||
* @ORM\Column(name="name", type="string", length=160, nullable=false, unique=true)
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", unique=true)
|
||||
* @ORM\Column(name="mail", type="string", length=160, nullable=false, unique=true)
|
||||
*/
|
||||
private $email;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @ORM\Column(name="password", type="string", length=254, nullable=true)
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="alias", type="string", length=160, nullable=true)
|
||||
*/
|
||||
private $alias;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="trash", type="boolean", nullable=false)
|
||||
*/
|
||||
private $trash = '0';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @ORM\Column(name="active", type="boolean", nullable=false)
|
||||
*/
|
||||
private $active = '1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="passwordResetHash", type="string", length=32, nullable=true)
|
||||
*/
|
||||
private $passwordresethash;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="ban", type="integer", nullable=false)
|
||||
*/
|
||||
private $ban = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="banTime", type="integer", nullable=false)
|
||||
*/
|
||||
private $bantime = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="secure", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $secure = '0';
|
||||
|
||||
/**
|
||||
* FIXME
|
||||
*
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastProject", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastproject = '1';
|
||||
|
||||
/**
|
||||
* FIXME
|
||||
*
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastActivity", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastactivity = '1';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="lastRecord", type="integer", nullable=false)
|
||||
*/
|
||||
private $lastrecord = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="timeframeBegin", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $timeframebegin = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="timeframeEnd", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $timeframeend = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="apikey", type="string", length=30, nullable=true)
|
||||
*/
|
||||
private $apikey;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json_array")
|
||||
*/
|
||||
private $roles = [];
|
||||
|
||||
/**
|
||||
* Set alias
|
||||
*
|
||||
* @param string $alias
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setAlias($alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set trash
|
||||
*
|
||||
* @param boolean $trash
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTrash($trash)
|
||||
{
|
||||
$this->trash = $trash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trash
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getTrash()
|
||||
{
|
||||
return $this->trash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active
|
||||
*
|
||||
* @param boolean $active
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setActive($active)
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getActive()
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get password
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set passwordresethash
|
||||
*
|
||||
* @param string $passwordresethash
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setPasswordresethash($passwordresethash)
|
||||
{
|
||||
$this->passwordresethash = $passwordresethash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get passwordresethash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPasswordresethash()
|
||||
{
|
||||
return $this->passwordresethash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ban
|
||||
*
|
||||
* @param integer $ban
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setBan($ban)
|
||||
{
|
||||
$this->ban = $ban;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ban
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getBan()
|
||||
{
|
||||
return $this->ban;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bantime
|
||||
*
|
||||
* @param integer $bantime
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setBantime($bantime)
|
||||
{
|
||||
$this->bantime = $bantime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bantime
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getBantime()
|
||||
{
|
||||
return $this->bantime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set secure
|
||||
*
|
||||
* @param string $secure
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setSecure($secure)
|
||||
{
|
||||
$this->secure = $secure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get secure
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecure()
|
||||
{
|
||||
return $this->secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastproject
|
||||
*
|
||||
* @param integer $lastproject
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastproject($lastproject)
|
||||
{
|
||||
$this->lastproject = $lastproject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastproject
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastproject()
|
||||
{
|
||||
return $this->lastproject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastactivity
|
||||
*
|
||||
* @param integer $lastactivity
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastactivity($lastactivity)
|
||||
{
|
||||
$this->lastactivity = $lastactivity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastactivity
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastactivity()
|
||||
{
|
||||
return $this->lastactivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lastrecord
|
||||
*
|
||||
* @param integer $lastrecord
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setLastrecord($lastrecord)
|
||||
{
|
||||
$this->lastrecord = $lastrecord;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lastrecord
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastrecord()
|
||||
{
|
||||
return $this->lastrecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeframebegin
|
||||
*
|
||||
* @param string $timeframebegin
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTimeframebegin($timeframebegin)
|
||||
{
|
||||
$this->timeframebegin = $timeframebegin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timeframebegin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeframebegin()
|
||||
{
|
||||
return $this->timeframebegin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeframeend
|
||||
*
|
||||
* @param string $timeframeend
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setTimeframeend($timeframeend)
|
||||
{
|
||||
$this->timeframeend = $timeframeend;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timeframeend
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeframeend()
|
||||
{
|
||||
return $this->timeframeend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set apikey
|
||||
*
|
||||
* @param string $apikey
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setApikey($apikey)
|
||||
{
|
||||
$this->apikey = $apikey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get apikey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApikey()
|
||||
{
|
||||
return $this->apikey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set globalroleid
|
||||
*
|
||||
* @param integer $globalroleid
|
||||
*
|
||||
* @return KimaiUsers
|
||||
*/
|
||||
public function setGlobalroleid($globalroleid)
|
||||
{
|
||||
$this->globalroleid = $globalroleid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get globalroleid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getGlobalroleid()
|
||||
{
|
||||
return $this->globalroleid;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
@@ -75,18 +524,6 @@ class User implements UserInterface
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the roles or permissions granted to the user for security.
|
||||
*/
|
||||
@@ -127,4 +564,9 @@ class User implements UserInterface
|
||||
// if you had a plainPassword property, you'd nullify it here
|
||||
// $this->plainPassword = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getUsername();
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,30 @@ namespace AppBundle\Entity;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiPreferences
|
||||
* UserPreference
|
||||
*
|
||||
* @ORM\Table(name="preferences")
|
||||
* @ORM\Table(name="preferences",indexes={@ORM\Index(name="option_idx", columns={"userid", "option"})}))
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class KimaiPreferences
|
||||
class UserPreference
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(name="userID", type="integer")
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="option", type="string", length=255)
|
||||
*/
|
||||
private $option;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@@ -19,32 +36,12 @@ class KimaiPreferences
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="option", type="string", length=255)
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $option;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="userID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set value
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return KimaiPreferences
|
||||
* @return UserPreference
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
@@ -68,7 +65,7 @@ class KimaiPreferences
|
||||
*
|
||||
* @param string $option
|
||||
*
|
||||
* @return KimaiPreferences
|
||||
* @return UserPreference
|
||||
*/
|
||||
public function setOption($option)
|
||||
{
|
||||
@@ -92,7 +89,7 @@ class KimaiPreferences
|
||||
*
|
||||
* @param integer $userid
|
||||
*
|
||||
* @return KimaiPreferences
|
||||
* @return UserPreference
|
||||
*/
|
||||
public function setUserid($userid)
|
||||
{
|
||||
@@ -11,45 +11,26 @@
|
||||
|
||||
namespace AppBundle\Event;
|
||||
|
||||
use Knp\Menu\FactoryInterface;
|
||||
use Knp\Menu\ItemInterface;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Avanzu\AdminThemeBundle\Model\MenuItemModel;
|
||||
|
||||
/**
|
||||
* The ConfigureAdminMenuEvent is used for populating the administration navigation.
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ConfigureAdminMenuEvent extends Event
|
||||
class ConfigureAdminMenuEvent extends ConfigureMenuEvent
|
||||
{
|
||||
const CONFIGURE = 'app.admin_menu_configure';
|
||||
|
||||
private $factory;
|
||||
private $menu;
|
||||
|
||||
/**
|
||||
* @param \Knp\Menu\FactoryInterface $factory
|
||||
* @param \Knp\Menu\ItemInterface $menu
|
||||
* This function will either return a MenuItem or null.
|
||||
*
|
||||
* In case this returns null, the user has not the ROLE_ADMIN.
|
||||
*
|
||||
* @return MenuItemModel|null
|
||||
*/
|
||||
public function __construct(FactoryInterface $factory, ItemInterface $menu)
|
||||
public function getAdminMenu()
|
||||
{
|
||||
$this->factory = $factory;
|
||||
$this->menu = $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Knp\Menu\FactoryInterface
|
||||
*/
|
||||
public function getFactory()
|
||||
{
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Knp\Menu\ItemInterface
|
||||
*/
|
||||
public function getMenu()
|
||||
{
|
||||
return $this->menu;
|
||||
return $this->getMenu()->getRootItem('admin');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,36 +20,7 @@ use Symfony\Component\EventDispatcher\Event;
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ConfigureMainMenuEvent extends Event
|
||||
class ConfigureMainMenuEvent extends ConfigureMenuEvent
|
||||
{
|
||||
const CONFIGURE = 'app.main_menu_configure';
|
||||
|
||||
private $factory;
|
||||
private $menu;
|
||||
|
||||
/**
|
||||
* @param \Knp\Menu\FactoryInterface $factory
|
||||
* @param \Knp\Menu\ItemInterface $menu
|
||||
*/
|
||||
public function __construct(FactoryInterface $factory, ItemInterface $menu)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
$this->menu = $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Knp\Menu\FactoryInterface
|
||||
*/
|
||||
public function getFactory()
|
||||
{
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Knp\Menu\ItemInterface
|
||||
*/
|
||||
public function getMenu()
|
||||
{
|
||||
return $this->menu;
|
||||
}
|
||||
}
|
||||
|
||||
80
src/AppBundle/Event/ConfigureMenuEvent.php
Normal file
80
src/AppBundle/Event/ConfigureMenuEvent.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Event;
|
||||
|
||||
use Avanzu\AdminThemeBundle\Model\MenuItemModel;
|
||||
use Avanzu\AdminThemeBundle\Event\SidebarMenuEvent;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
|
||||
|
||||
/**
|
||||
* The ConfigureMenuEvent is used for populating navigations.
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
abstract class ConfigureMenuEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
/**
|
||||
* @var SidebarMenuEvent
|
||||
*/
|
||||
private $event;
|
||||
/**
|
||||
* @var AuthorizationChecker
|
||||
*/
|
||||
private $auth;
|
||||
|
||||
/**
|
||||
* ConfigureMenuEvent constructor.
|
||||
* @param AuthorizationChecker $auth
|
||||
* @param Request $request
|
||||
* @param MenuItemModel $menuModel
|
||||
*/
|
||||
public function __construct(
|
||||
AuthorizationChecker $auth,
|
||||
Request $request,
|
||||
SidebarMenuEvent $event
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->request = $request;
|
||||
$this->event = $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SidebarMenuEvent
|
||||
*/
|
||||
public function getMenu()
|
||||
{
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AuthorizationChecker
|
||||
*/
|
||||
public function getAuth()
|
||||
{
|
||||
return $this->auth;
|
||||
}
|
||||
}
|
||||
120
src/AppBundle/EventListener/MenuBuilder.php
Normal file
120
src/AppBundle/EventListener/MenuBuilder.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\EventListener;
|
||||
|
||||
use AppBundle\Event\ConfigureMainMenuEvent;
|
||||
use AppBundle\Event\ConfigureAdminMenuEvent;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
|
||||
use Avanzu\AdminThemeBundle\Model\MenuItemModel;
|
||||
use Avanzu\AdminThemeBundle\Event\SidebarMenuEvent;
|
||||
|
||||
/**
|
||||
* Class MenuBuilder configures the main navigation.
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class MenuBuilder
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
/**
|
||||
* @var AuthorizationChecker
|
||||
*/
|
||||
private $security;
|
||||
|
||||
/**
|
||||
* MenuBuilder constructor.
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @param AuthorizationChecker $security
|
||||
*/
|
||||
public function __construct(
|
||||
EventDispatcherInterface $dispatcher,
|
||||
AuthorizationChecker $security
|
||||
)
|
||||
{
|
||||
$this->eventDispatcher = $dispatcher;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the main menu.
|
||||
*
|
||||
* @param SidebarMenuEvent $event
|
||||
*/
|
||||
public function onSetupNavbar(SidebarMenuEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
$isLoggedIn = $this->security->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
$isAdmin = $isLoggedIn && $this->security->isGranted('ROLE_ADMIN');
|
||||
|
||||
$event->addItem(
|
||||
new MenuItemModel('dashboard', 'menu.homepage', 'dashboard', [], 'fa fa-home')
|
||||
);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
ConfigureMainMenuEvent::CONFIGURE,
|
||||
new ConfigureMainMenuEvent(
|
||||
$this->security,
|
||||
$request,
|
||||
$event
|
||||
)
|
||||
);
|
||||
|
||||
if ($isAdmin) {
|
||||
$event->addItem(
|
||||
new MenuItemModel('admin', 'menu.admin_dashboard', '', [], 'fa fa-dashboard')
|
||||
);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
ConfigureAdminMenuEvent::CONFIGURE,
|
||||
new ConfigureAdminMenuEvent(
|
||||
$this->security,
|
||||
$request,
|
||||
$event
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$event->addItem(
|
||||
new MenuItemModel('logout', 'menu.logout', 'security_logout', [], 'fa fa-sign-out')
|
||||
);
|
||||
|
||||
$this->activateByRoute(
|
||||
$event->getRequest()->get('_route'),
|
||||
$event->getItems()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param MenuItemModel[] $items
|
||||
*/
|
||||
protected function activateByRoute($route, $items)
|
||||
{
|
||||
foreach($items as $item) {
|
||||
if($item->hasChildren()) {
|
||||
$this->activateByRoute($route, $item->getChildren());
|
||||
}
|
||||
else {
|
||||
if($item->getRoute() == $route) {
|
||||
$item->setIsActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Form;
|
||||
|
||||
use AppBundle\Entity\Comment;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Defines the form used to create and manipulate blog comments. Although in this
|
||||
* case the form is trivial and we could build it inside the controller, a good
|
||||
* practice is to always define your forms as classes.
|
||||
* See http://symfony.com/doc/current/book/forms.html#creating-form-classes
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class CommentType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
// By default, form fields include the 'required' attribute, which enables
|
||||
// the client-side form validation. This means that you can't test the
|
||||
// server-side validation errors from the browser. To temporarily disable
|
||||
// this validation, set the 'required' attribute to 'false':
|
||||
//
|
||||
// $builder->add('content', null, ['required' => false]);
|
||||
|
||||
$builder
|
||||
->add('content')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Comment::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Form;
|
||||
|
||||
use AppBundle\Entity\Post;
|
||||
use AppBundle\Form\Type\DateTimePickerType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Defines the form used to create and manipulate blog posts.
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class PostType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
// For the full reference of options defined by each form field type
|
||||
// see http://symfony.com/doc/current/reference/forms/types.html
|
||||
|
||||
// By default, form fields include the 'required' attribute, which enables
|
||||
// the client-side form validation. This means that you can't test the
|
||||
// server-side validation errors from the browser. To temporarily disable
|
||||
// this validation, set the 'required' attribute to 'false':
|
||||
//
|
||||
// $builder->add('title', null, ['required' => false, ...]);
|
||||
|
||||
$builder
|
||||
->add('title', null, [
|
||||
'attr' => ['autofocus' => true],
|
||||
'label' => 'label.title',
|
||||
])
|
||||
->add('summary', TextareaType::class, [
|
||||
'label' => 'label.summary',
|
||||
])
|
||||
->add('content', null, [
|
||||
'attr' => ['rows' => 20],
|
||||
'label' => 'label.content',
|
||||
])
|
||||
->add('authorEmail', null, [
|
||||
'label' => 'label.author_email',
|
||||
])
|
||||
->add('publishedAt', DateTimePickerType::class, [
|
||||
'label' => 'label.published_at',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Post::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Menu;
|
||||
|
||||
use Knp\Menu\FactoryInterface;
|
||||
use AppBundle\Event\ConfigureMainMenuEvent;
|
||||
use AppBundle\Event\ConfigureAdminMenuEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
|
||||
|
||||
/**
|
||||
* Class MenuBuilder
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class MenuBuilder
|
||||
{
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $factory;
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
/**
|
||||
* @var AuthorizationChecker
|
||||
*/
|
||||
private $security;
|
||||
|
||||
/**
|
||||
* MenuBuilder constructor.
|
||||
* @param FactoryInterface $factory
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @param AuthorizationChecker $security
|
||||
*/
|
||||
public function __construct(FactoryInterface $factory,
|
||||
EventDispatcherInterface $dispatcher,
|
||||
AuthorizationChecker $security)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
$this->eventDispatcher = $dispatcher;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the main menu.
|
||||
*
|
||||
* @param array $options
|
||||
* @return \Knp\Menu\ItemInterface
|
||||
*/
|
||||
public function createMainMenu(array $options)
|
||||
{
|
||||
$menu = $this->factory->createItem('main');
|
||||
$menu->setChildrenAttribute('class', 'nav navbar-nav navbar-right');
|
||||
|
||||
$isLoggedIn = $this->security->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
$isAdmin = $isLoggedIn && $this->security->isGranted('ROLE_ADMIN');
|
||||
|
||||
if ($isLoggedIn) {
|
||||
$item = $menu->addChild('Homepage', array('route' => 'blog_index'));
|
||||
$item->setLabel('menu.homepage');
|
||||
$item->setChildrenAttribute('icon', 'home');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
ConfigureMainMenuEvent::CONFIGURE,
|
||||
new ConfigureMainMenuEvent($this->factory, $menu)
|
||||
);
|
||||
|
||||
if ($isAdmin) {
|
||||
$item = $menu->addChild('Administration', array('route' => 'admin_post_index'));
|
||||
$item->setLabel('menu.admin');
|
||||
$item->setChildrenAttribute('icon', 'lock');
|
||||
}
|
||||
|
||||
if ($isLoggedIn) {
|
||||
$item = $menu->addChild('Logout', array('route' => 'security_logout'));
|
||||
$item->setLabel('menu.logout');
|
||||
$item->setChildrenAttribute('icon', 'sign-out');
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the admin menu.
|
||||
*
|
||||
* @param array $options
|
||||
* @return \Knp\Menu\ItemInterface
|
||||
*/
|
||||
public function createAdminMenu(array $options)
|
||||
{
|
||||
$menu = $this->factory->createItem('admin');
|
||||
$menu->setChildrenAttribute('class', 'nav navbar-nav navbar-right');
|
||||
|
||||
$isLoggedIn = $this->security->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
$isAdmin = $isLoggedIn && $this->security->isGranted('ROLE_ADMIN');
|
||||
|
||||
// FIXME CAN BE REMOVED
|
||||
if ($isAdmin) {
|
||||
$item = $menu->addChild('Post list', array('route' => 'admin_post_index'));
|
||||
$item->setLabel('menu.post_list');
|
||||
$item->setChildrenAttribute('icon', 'list-alt');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
ConfigureAdminMenuEvent::CONFIGURE,
|
||||
new ConfigureAdminMenuEvent($this->factory, $menu)
|
||||
);
|
||||
|
||||
if ($isLoggedIn) {
|
||||
$item = $menu->addChild('Logout', array('route' => 'security_logout'));
|
||||
$item->setLabel('menu.logout');
|
||||
$item->setChildrenAttribute('icon', 'sign-out');
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
use AppBundle\Entity\Post;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Pagerfanta\Adapter\DoctrineORMAdapter;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* This custom Doctrine repository contains some methods which are useful when
|
||||
* querying for blog post information.
|
||||
* See http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes
|
||||
*
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*/
|
||||
class PostRepository extends EntityRepository
|
||||
{
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function queryLatest()
|
||||
{
|
||||
return $this->getEntityManager()
|
||||
->createQuery('
|
||||
SELECT p
|
||||
FROM AppBundle:Post p
|
||||
WHERE p.publishedAt <= :now
|
||||
ORDER BY p.publishedAt DESC
|
||||
')
|
||||
->setParameter('now', new \DateTime())
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
*
|
||||
* @return Pagerfanta
|
||||
*/
|
||||
public function findLatest($page = 1)
|
||||
{
|
||||
$paginator = new Pagerfanta(new DoctrineORMAdapter($this->queryLatest(), false));
|
||||
$paginator->setMaxPerPage(Post::NUM_ITEMS);
|
||||
$paginator->setCurrentPage($page);
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ namespace AppBundle\Repository;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* This custom Doctrine repository is empty because so far we don't need any custom
|
||||
* method to query for application user information. But it's always a good practice
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Tests\Controller\Admin;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Functional test for the controllers defined inside the BlogController used
|
||||
* for managing the blog in the backend.
|
||||
* See http://symfony.com/doc/current/book/testing.html#functional-tests
|
||||
*
|
||||
* Whenever you test resources protected by a firewall, consider using the
|
||||
* technique explained in:
|
||||
* http://symfony.com/doc/current/cookbook/testing/http_authentication.html
|
||||
*
|
||||
* Execute the application tests using this command (requires PHPUnit to be installed):
|
||||
*
|
||||
* $ cd your-symfony-project/
|
||||
* $ phpunit -c app
|
||||
*
|
||||
*/
|
||||
class BlogControllerTest extends WebTestCase
|
||||
{
|
||||
public function testRegularUsersCannotAccessToTheBackend()
|
||||
{
|
||||
$client = static::createClient([], [
|
||||
'PHP_AUTH_USER' => 'john_user',
|
||||
'PHP_AUTH_PW' => 'kitten',
|
||||
]);
|
||||
|
||||
$client->request('GET', '/en/admin/post/');
|
||||
|
||||
$this->assertEquals(Response::HTTP_FORBIDDEN, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testAdministratorUsersCanAccessToTheBackend()
|
||||
{
|
||||
$client = static::createClient([], [
|
||||
'PHP_AUTH_USER' => 'anna_admin',
|
||||
'PHP_AUTH_PW' => 'kitten',
|
||||
]);
|
||||
|
||||
$client->request('GET', '/en/admin/post/');
|
||||
|
||||
$this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$client = static::createClient([], [
|
||||
'PHP_AUTH_USER' => 'anna_admin',
|
||||
'PHP_AUTH_PW' => 'kitten',
|
||||
]);
|
||||
|
||||
$crawler = $client->request('GET', '/en/admin/post/');
|
||||
|
||||
$this->assertCount(
|
||||
30,
|
||||
$crawler->filter('body#admin_post_index #main tbody tr'),
|
||||
'The backend homepage displays all the available posts.'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AppBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use AppBundle\Entity\Post;
|
||||
|
||||
/**
|
||||
* FIXME CAN BE REMOVED
|
||||
*
|
||||
* Functional test for the controllers defined inside BlogController.
|
||||
* See http://symfony.com/doc/current/book/testing.html#functional-tests
|
||||
*
|
||||
* Execute the application tests using this command (requires PHPUnit to be installed):
|
||||
*
|
||||
* $ cd your-symfony-project/
|
||||
* $ phpunit -c app
|
||||
*
|
||||
*/
|
||||
class BlogControllerTest extends WebTestCase
|
||||
{
|
||||
public function testIndex()
|
||||
{
|
||||
$client = static::createClient();
|
||||
$crawler = $client->request('GET', '/en/blog/');
|
||||
|
||||
$this->assertCount(
|
||||
Post::NUM_ITEMS,
|
||||
$crawler->filter('article.post'),
|
||||
'The homepage displays the right number of posts.'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ class DefaultControllerTest extends WebTestCase
|
||||
*/
|
||||
public function testSecureUrls($url)
|
||||
{
|
||||
$this->markTestSkipped('No admin URLs for testing');
|
||||
$client = self::createClient();
|
||||
$client->request('GET', $url);
|
||||
|
||||
@@ -70,16 +71,11 @@ class DefaultControllerTest extends WebTestCase
|
||||
public function getPublicUrls()
|
||||
{
|
||||
yield ['/'];
|
||||
yield ['/en/blog/'];
|
||||
yield ['/en/blog/posts/morbi-tempus-commodo-mattis'];
|
||||
yield ['/en/login'];
|
||||
}
|
||||
|
||||
public function getSecureUrls()
|
||||
{
|
||||
yield ['/en/admin/post/'];
|
||||
yield ['/en/admin/post/new'];
|
||||
yield ['/en/admin/post/1'];
|
||||
yield ['/en/admin/post/1/edit'];
|
||||
}
|
||||
}
|
||||
|
||||
43
src/TimesheetBundle/Controller/Admin/TimesheetController.php
Normal file
43
src/TimesheetBundle/Controller/Admin/TimesheetController.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace TimesheetBundle\Controller\Admin;
|
||||
|
||||
use TimesheetBundle\Entity\Timesheet;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
|
||||
/**
|
||||
* Controller used for manage timesheet entries in the admin part of the site.
|
||||
*
|
||||
* @Route("/admin/timesheet")
|
||||
* @Security("has_role('ROLE_CUSTOMER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class TimesheetController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_timesheet_index")
|
||||
* @Route("/timesheet/{page}", requirements={"page": "[1-9]\d*"}, name="admin_timesheet_index_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page)
|
||||
{
|
||||
$entries = $this->getDoctrine()->getRepository(Timesheet::class)->findLatest($page);
|
||||
|
||||
return $this->render('TimesheetBundle:timesheet:index.html.twig', ['entries' => $entries]);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,12 @@ class LoadFixtures extends AppBundleLoadFixtures
|
||||
|
||||
private function loadTimesheet(ObjectManager $manager)
|
||||
{
|
||||
$amountUsers = count($manager->getRepository(User::class)->findAll());
|
||||
$allUsers = [];
|
||||
$users = $manager->getRepository(User::class)->findAll();
|
||||
foreach ($users as $user) {
|
||||
$allUsers[$user->getId()] = $user;
|
||||
}
|
||||
$amountUsers = count($allUsers);
|
||||
|
||||
for ($i = 0; $i <= self::AMOUNT_TIMESHEET; $i++) {
|
||||
|
||||
@@ -67,7 +72,7 @@ class LoadFixtures extends AppBundleLoadFixtures
|
||||
$entry->setStart($start->getTimestamp());
|
||||
$entry->setEnd($end->getTimestamp());
|
||||
$entry->setDuration($end->modify('- ' . $start->getTimestamp() . ' seconds')->getTimestamp());
|
||||
$entry->setUserid(rand(1, $amountUsers));
|
||||
$entry->setUser($allUsers[rand(1, $amountUsers)]);
|
||||
//$entry->setApproved(false); // TODO
|
||||
//$entry->setFixedrate(); // TODO
|
||||
//$entry->setRate(); // TODO
|
||||
|
||||
@@ -1,17 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace TimesheetBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiActivities
|
||||
* Activity
|
||||
*
|
||||
* @ORM\Table(name="activities")
|
||||
* @ORM\Entity
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class KimaiActivities
|
||||
class Activity
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="activityID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $activityid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@@ -47,23 +68,12 @@ class KimaiActivities
|
||||
*/
|
||||
private $trash = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="activityID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $activityid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return KimaiActivities
|
||||
* @return Activity
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
@@ -87,7 +97,7 @@ class KimaiActivities
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return KimaiActivities
|
||||
* @return Activity
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
@@ -111,7 +121,7 @@ class KimaiActivities
|
||||
*
|
||||
* @param boolean $visible
|
||||
*
|
||||
* @return KimaiActivities
|
||||
* @return Activity
|
||||
*/
|
||||
public function setVisible($visible)
|
||||
{
|
||||
@@ -135,7 +145,7 @@ class KimaiActivities
|
||||
*
|
||||
* @param boolean $filter
|
||||
*
|
||||
* @return KimaiActivities
|
||||
* @return Activity
|
||||
*/
|
||||
public function setFilter($filter)
|
||||
{
|
||||
@@ -159,7 +169,7 @@ class KimaiActivities
|
||||
*
|
||||
* @param boolean $trash
|
||||
*
|
||||
* @return KimaiActivities
|
||||
* @return Activity
|
||||
*/
|
||||
public function setTrash($trash)
|
||||
{
|
||||
@@ -1,17 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace TimesheetBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiCustomers
|
||||
* Customer
|
||||
*
|
||||
* @ORM\Table(name="customers")
|
||||
* @ORM\Entity
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class KimaiCustomers
|
||||
class Customer
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="customerID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $customerid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@@ -19,27 +40,6 @@ class KimaiCustomers
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="password", type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="passwordResetHash", type="string", length=32, nullable=true)
|
||||
*/
|
||||
private $passwordresethash;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="secure", type="string", length=60, nullable=false)
|
||||
*/
|
||||
private $secure = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@@ -159,23 +159,12 @@ class KimaiCustomers
|
||||
*/
|
||||
private $trash = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="customerID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $customerid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
@@ -199,7 +188,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
@@ -223,7 +212,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $passwordresethash
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setPasswordresethash($passwordresethash)
|
||||
{
|
||||
@@ -247,7 +236,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $secure
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setSecure($secure)
|
||||
{
|
||||
@@ -271,7 +260,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
@@ -295,7 +284,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param boolean $visible
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setVisible($visible)
|
||||
{
|
||||
@@ -319,7 +308,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param boolean $filter
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setFilter($filter)
|
||||
{
|
||||
@@ -343,7 +332,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $company
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setCompany($company)
|
||||
{
|
||||
@@ -367,7 +356,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $vat
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setVat($vat)
|
||||
{
|
||||
@@ -391,7 +380,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $contact
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setContact($contact)
|
||||
{
|
||||
@@ -415,7 +404,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $street
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setStreet($street)
|
||||
{
|
||||
@@ -439,7 +428,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $zipcode
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setZipcode($zipcode)
|
||||
{
|
||||
@@ -463,7 +452,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $city
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setCity($city)
|
||||
{
|
||||
@@ -487,7 +476,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $country
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setCountry($country)
|
||||
{
|
||||
@@ -511,7 +500,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $phone
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setPhone($phone)
|
||||
{
|
||||
@@ -535,7 +524,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $fax
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setFax($fax)
|
||||
{
|
||||
@@ -559,7 +548,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $mobile
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setMobile($mobile)
|
||||
{
|
||||
@@ -583,7 +572,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $mail
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setMail($mail)
|
||||
{
|
||||
@@ -607,7 +596,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $homepage
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setHomepage($homepage)
|
||||
{
|
||||
@@ -631,7 +620,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param string $timezone
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setTimezone($timezone)
|
||||
{
|
||||
@@ -655,7 +644,7 @@ class KimaiCustomers
|
||||
*
|
||||
* @param boolean $trash
|
||||
*
|
||||
* @return KimaiCustomers
|
||||
* @return Customer
|
||||
*/
|
||||
public function setTrash($trash)
|
||||
{
|
||||
@@ -1,17 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace TimesheetBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* KimaiProjects
|
||||
* Project
|
||||
*
|
||||
* @ORM\Table(name="projects", indexes={@ORM\Index(name="customerID", columns={"customerID"})})
|
||||
* @ORM\Entity
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class KimaiProjects
|
||||
class Project
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
@@ -82,17 +103,6 @@ class KimaiProjects
|
||||
*/
|
||||
private $internal = '0';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="projectID", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $projectid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set customerid
|
||||
*
|
||||
@@ -11,13 +11,14 @@
|
||||
|
||||
namespace TimesheetBundle\Entity;
|
||||
|
||||
use AppBundle\Entity\User;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Timesheet entity.
|
||||
*
|
||||
* @ORM\Entity(repositoryClass="TimesheetBundle\Repository\TimesheetRepository")
|
||||
* @ORM\Table(name="timeSheet", indexes={@ORM\Index(name="userID", columns={"userID"}), @ORM\Index(name="projectID", columns={"projectID"}), @ORM\Index(name="activityID", columns={"activityID"})})
|
||||
* @ORM\Table(name="timeSheet", indexes={@ORM\Index(columns={"userID"}), @ORM\Index(columns={"projectID"}), @ORM\Index(name="activityID", columns={"activityID"})})
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
@@ -47,9 +48,10 @@ class Timesheet
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="userID", type="integer", nullable=false)
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
|
||||
* @ORM\JoinColumn(name="userID", referencedColumnName="userID")
|
||||
*/
|
||||
private $userid;
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
@@ -165,7 +167,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $start
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setStart($start)
|
||||
{
|
||||
@@ -189,7 +191,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $end
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setEnd($end)
|
||||
{
|
||||
@@ -213,7 +215,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $duration
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setDuration($duration)
|
||||
{
|
||||
@@ -233,27 +235,27 @@ class Timesheet
|
||||
}
|
||||
|
||||
/**
|
||||
* Set userid
|
||||
* Set user
|
||||
*
|
||||
* @param integer $userid
|
||||
* @param User $user
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setUserid($userid)
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->userid = $userid;
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userid
|
||||
* Get user
|
||||
*
|
||||
* @return integer
|
||||
* @return User
|
||||
*/
|
||||
public function getUserid()
|
||||
public function getUser()
|
||||
{
|
||||
return $this->userid;
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,7 +263,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $projectid
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setProjectid($projectid)
|
||||
{
|
||||
@@ -285,7 +287,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $activityid
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setActivityid($activityid)
|
||||
{
|
||||
@@ -309,7 +311,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $description
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
@@ -333,7 +335,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
@@ -357,7 +359,7 @@ class Timesheet
|
||||
*
|
||||
* @param boolean $commenttype
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setCommenttype($commenttype)
|
||||
{
|
||||
@@ -381,7 +383,7 @@ class Timesheet
|
||||
*
|
||||
* @param boolean $cleared
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setCleared($cleared)
|
||||
{
|
||||
@@ -405,7 +407,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $location
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setLocation($location)
|
||||
{
|
||||
@@ -429,7 +431,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $trackingnumber
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setTrackingnumber($trackingnumber)
|
||||
{
|
||||
@@ -453,7 +455,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $rate
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setRate($rate)
|
||||
{
|
||||
@@ -477,7 +479,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $fixedrate
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setFixedrate($fixedrate)
|
||||
{
|
||||
@@ -501,7 +503,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $budget
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
{
|
||||
@@ -525,7 +527,7 @@ class Timesheet
|
||||
*
|
||||
* @param string $approved
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setApproved($approved)
|
||||
{
|
||||
@@ -549,7 +551,7 @@ class Timesheet
|
||||
*
|
||||
* @param integer $statusid
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setStatusid($statusid)
|
||||
{
|
||||
@@ -573,7 +575,7 @@ class Timesheet
|
||||
*
|
||||
* @param boolean $billable
|
||||
*
|
||||
* @return KimaiTimesheet
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setBillable($billable)
|
||||
{
|
||||
|
||||
@@ -13,9 +13,12 @@ namespace TimesheetBundle\EventListener;
|
||||
|
||||
use AppBundle\Event\ConfigureMainMenuEvent;
|
||||
use AppBundle\Event\ConfigureAdminMenuEvent;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
|
||||
use Avanzu\AdminThemeBundle\Model\MenuItemModel;
|
||||
use Avanzu\AdminThemeBundle\Event\SidebarMenuEvent;
|
||||
|
||||
/**
|
||||
* Class Menu
|
||||
* Menus for timesheet
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
@@ -27,10 +30,18 @@ class Menu
|
||||
public function onMainMenuConfigure(ConfigureMainMenuEvent $event)
|
||||
{
|
||||
$menu = $event->getMenu();
|
||||
$auth = $event->getAuth();
|
||||
|
||||
$item = $menu->addChild('Timesheet', array('route' => 'timesheet'));
|
||||
$item->setLabel('menu.timesheet');
|
||||
$item->setChildrenAttribute('icon', 'clock-o');
|
||||
$isLoggedIn = $auth->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
$isAdmin = $isLoggedIn && $auth->isGranted('ROLE_ADMIN');
|
||||
|
||||
if (!$isLoggedIn) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menu->addItem(
|
||||
new MenuItemModel('timesheet', 'menu.timesheet', 'timesheet', [], 'fa fa-clock-o')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,10 +49,18 @@ class Menu
|
||||
*/
|
||||
public function onAdminMenuConfigure(ConfigureAdminMenuEvent $event)
|
||||
{
|
||||
$menu = $event->getMenu();
|
||||
$menu = $event->getAdminMenu();
|
||||
$auth = $event->getAuth();
|
||||
|
||||
$item = $menu->addChild('TimeAdmin', array('route' => 'timesheet'));
|
||||
//$item->setLabel('menu.admin_timesheet');
|
||||
$item->setChildrenAttribute('icon', 'clock-o');
|
||||
$isLoggedIn = $auth->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
$isAdmin = $isLoggedIn && $auth->isGranted('ROLE_ADMIN');
|
||||
|
||||
if (!$isAdmin) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menu->addChild(
|
||||
new MenuItemModel('timesheet_admin', 'menu.admin_timesheet', 'admin_timesheet_index', [], 'fa fa-clock-o')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'timesheet_index' %}
|
||||
{% block page_title %}Timesheet{% endblock %}
|
||||
{% block page_subtitle %}manage your times{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
{% if entries %}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><i class="fa fa-calendar"></i> {{ 'label.date'|trans }}</th>
|
||||
<th><i class="fa fa-circle-o"></i> {{ 'label.start'|trans }}</th>
|
||||
<th><i class="fa fa-circle"></i> {{ 'label.end'|trans }}</th>
|
||||
<th><i class="fa fa-clock-o"></i> {{ 'label.duration'|trans }}</th>
|
||||
<th><i class="fa fa-user"></i> {{ 'label.user'|trans }}</th>
|
||||
<th>{{ 'label.description'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entry in entries %}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ entry.start|date("m/d/Y") }}</td>
|
||||
<td>{{ entry.start|date("H:i") }}</td>
|
||||
<td>{{ entry.end|date("H:i") }}</td>
|
||||
<td>{{ entry.duration|gmdate }}</td>
|
||||
<td>{{ entry.userid }}</td>
|
||||
<td>{{ entry.description }}</td>
|
||||
<th><i class="fa fa-calendar"></i> {{ 'label.date'|trans }}</th>
|
||||
<th><i class="fa fa-circle-o"></i> {{ 'label.start'|trans }}</th>
|
||||
<th><i class="fa fa-circle"></i> {{ 'label.end'|trans }}</th>
|
||||
<th><i class="fa fa-clock-o"></i> {{ 'label.duration'|trans }}</th>
|
||||
<th><i class="fa fa-user"></i> {{ 'label.user'|trans }}</th>
|
||||
<th>{{ 'label.description'|trans }}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
<td>{{ entry.start|date("m/d/Y") }}</td>
|
||||
<td>{{ entry.start|date("H:i") }}</td>
|
||||
<td>{{ entry.end|date("H:i") }}</td>
|
||||
<td>{{ entry.duration|gmdate }}</td>
|
||||
<td>{{ entry.user.username }}</td>
|
||||
<td>{{ entry.description }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="well">{{ 'post.no_posts_found'|trans }}</div>
|
||||
{% endif %}
|
||||
@@ -37,7 +37,3 @@
|
||||
{{ pagerfanta(entries, 'twitter_bootstrap3_translated', { routeName: 'timesheet_paginated' }) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace TimesheetBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use TimesheetBundle\EventListener\Menu as MenuListener;
|
||||
|
||||
/**
|
||||
* This class defines the Bundle for all Timesheet related topics
|
||||
@@ -20,4 +21,14 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
*/
|
||||
class TimesheetBundle extends Bundle
|
||||
{
|
||||
|
||||
/**
|
||||
* Boots the Bundle.
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$listener = new MenuListener();
|
||||
/* @var $dispatcher \Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher */
|
||||
$dispatcher = $this->container->get('event_dispatcher');
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 26 KiB |
BIN
web/favicon.ico
BIN
web/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user