profile edit WIP

This commit is contained in:
Christine Slotty 2020-07-15 19:01:06 +02:00
parent 08cda3fe3d
commit 163bf8129b
19 changed files with 257 additions and 7914 deletions

3
.gitignore vendored
View File

@ -8,3 +8,6 @@ websrc/node_modules/
websrc/gulpfile.js
websrc/package-lock.json
mithril_client/
webroot/css/grd_styles.css
websrc/src/less-files.css

4562
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -43,4 +43,4 @@ return [
<input type="number" name="amount" required="required" step="0.01" id="amount">
</div>
*/
*/

View File

@ -2,9 +2,16 @@
namespace App\Controller;
use App\Controller\AppController;
use App\Controller\CommunityProfilesController;
use Model\Navigation\NaviHierarchy;
use Model\Navigation\NaviHierarchyEntry;
use Cake\ORM\TableRegistry;
use Cake\Filesystem\File;
use App\Form\ProfileForm;
/**
* Profile Controller
*/
@ -14,7 +21,7 @@ class ProfileController extends AppController
public function initialize()
{
parent::initialize();
$this->Auth->allow(['index']);
$this->Auth->allow(['index', 'edit']);
$this->set(
'naviHierarchy',
(new NaviHierarchy())->
@ -37,8 +44,98 @@ class ProfileController extends AppController
return $result;
}
$user = $session->read('StateUser');
$communityProfile = $session->read('CommunityProfile');
if (!isset($communityProfile)) {
$profilesTable = TableRegistry::getTableLocator()->get('CommunityProfiles');
$communityProfileQuery = $profilesTable
->find('all')
->select(['id', 'profile_img', 'profile_desc'])
->where(['state_user_id' => $user['id']]);
if ($communityProfileQuery->count() != 1) {
$communityProfile = $profilesTable->newEntity();
if ($profilesTable->save($communityProfile)) {
$this->Flash->success(__('Neues Profil erstellt.'));
}
} else {
$communityProfile = $communityProfileQuery->first();
}
$session->write('CommunityProfile', $communityProfile);
}
$this->set('user', $user);
$this->set('communityProfile', $communityProfile);
$this->set('timeUsed', microtime(true) - $startTime);
}
/**
* Edit method
*
* @return \Cake\Http\Response|null
*/
public function edit()
{
$startTime = microtime(true);
$this->viewBuilder()->setLayout('frontend');
$session = $this->getRequest()->getSession();
$user = $session->read('StateUser');
$communityProfile = $session->read('CommunityProfile');
if (!$user) {
$result = $this->requestLogin();
if ($result !== true) {
return $result;
}
$user = $session->read('StateUser');
}
$profileForm = new ProfileForm();
if ($this->request->is('post')) {
$requestData = $this->request->getData();
if ($profileForm->validate($requestData)) {
// Get a list of UploadedFile objects
$file = $requestData['profile_img'];
var_dump($file);
$binaryFileData = null;
// Read the file data.
$type = $file['type'];
$error = $file['error'];
if ($error === 0 && strpos($type, 'image/') === 0) {
$path = new File($file['tmp_name']);
$binaryFileData = $path->read(true, 'r');
}
// Update Profile with Form Data!
$usersTable = TableRegistry::getTableLocator()->get('StateUsers');
$stateUserQuery = $usersTable
->find('all')
->select(['id', 'first_name', 'last_name'])
->where(['id' => $user['id']]);
if ($stateUserQuery->count() == 1) {
$stateUser = $stateUserQuery->first();
$stateUser = $usersTable->patchEntity($stateUser, $requestData);
$profilesTable = TableRegistry::getTableLocator()->get('CommunityProfiles');
$communityProfile = $profilesTable->patchEntity($communityProfile, $requestData);
$communityProfile['state_user_id'] = $user['id'];
if ($binaryFileData !== null) {
echo "schreibe neue daten";
$communityProfile['profile_img'] = $binaryFileData;
}
if ($profilesTable->save($communityProfile) &&
$usersTable->save($stateUser)
) {
$user['first_name'] = $stateUser['first_name'];
$user['last_name'] = $stateUser['last_name'];
$session->write('StateUser.first_name', $stateUser['first_name']);
$session->write('StateUser.last_name', $stateUser['last_name']);
$session->write('CommunityProfile', $communityProfile);
$this->Flash->success(__('Dein Profil wurde aktualisiert!'));
}
} else {
$this->Flash->error(__("Non-recoverable database problem - state_user doesn't exist or not unique!"));
}
} else {
$this->Flash->error(__('Something was invalid, please try again!'));
}
}
$this->set('user', $user);
$this->set('communityProfile', $communityProfile);
$this->set('profileForm', $profileForm);
$this->set('timeUsed', microtime(true) - $startTime);
}
}

52
src/Form/ProfileForm.php Normal file
View File

@ -0,0 +1,52 @@
<?php
// in src/Form/ProfileForm.php
namespace App\Form;
use Cake\Form\Form;
use Cake\Form\Schema;
use Cake\Validation\Validator;
class ProfileForm extends Form
{
protected function _buildSchema(Schema $schema)
{
return $schema
->addField('first_name', ['type' => 'string'])
->addField('last_name', ['type' => 'string'])
->addField('profile_img', ['type' => 'string'])
->addField('profile_desc', ['type' =>'text', 'default' => '', 'rows' => 10, 'maxlength' => 2000]);
}
function validationDefault(Validator $validator)
{
$validator->setProvider('generic', 'App\Model\Validation\GenericValidation');
$validator->add('first_name', 'length', [
'rule' => ['maxLength', 255],
'message' => __('The first name should contain max 255 characters')
])
->add('last_name', 'length', [
'rule' => ['maxLength', 255],
'message' => __('The last name should contain max 255 characters')
])
->add('profile_desc', 'length', [
'rule' => ['maxLength', 2000],
'message' => __('The description should contain max 2000 characters')
])
->add('profile_desc', 'generic', [
'rule' => 'alphaNumeric',
'provider' => 'generic',
'message' => __('No HTML Tags like &gt; or &lt; please.')
])
->allowEmptyString('profile_img', null, 'create')
->allowEmptyString('profile_desc', null, 'create')
;
return $validator;
}
protected function _execute(array $data)
{
// Send an email. (??? xxx)
return true;
}
}

View File

@ -7,6 +7,7 @@ use Cake\ORM\Entity;
* CommunityProfile Entity
*
* @property int $id
* @property int $state_user_id
* @property string|resource|null $profile_img
* @property string|null $profile_desc
*/
@ -22,6 +23,7 @@ class CommunityProfile extends Entity
* @var array
*/
protected $_accessible = [
'state_user_id' => true,
'profile_img' => true,
'profile_desc' => true,
];

View File

@ -9,6 +9,8 @@ use Cake\Validation\Validator;
/**
* CommunityProfiles Model
*
* @property &\Cake\ORM\Association\BelongsTo $StateUsers
*
* @method \App\Model\Entity\CommunityProfile get($primaryKey, $options = [])
* @method \App\Model\Entity\CommunityProfile newEntity($data = null, array $options = [])
* @method \App\Model\Entity\CommunityProfile[] newEntities(array $data, array $options = [])
@ -33,6 +35,11 @@ class CommunityProfilesTable extends Table
$this->setTable('community_profiles');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->belongsTo('StateUsers', [
'foreignKey' => 'state_user_id',
'joinType' => 'INNER',
]);
}
/**
@ -57,4 +64,18 @@ class CommunityProfilesTable extends Table
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['state_user_id'], 'StateUsers'));
return $rules;
}
}

View File

@ -15,6 +15,7 @@
<fieldset>
<legend><?= __('Add Community Profile') ?></legend>
<?php
echo $this->Form->control('state_user_id');
echo $this->Form->control('profile_desc');
?>
</fieldset>

View File

@ -21,6 +21,7 @@
<fieldset>
<legend><?= __('Edit Community Profile') ?></legend>
<?php
echo $this->Form->control('state_user_id');
echo $this->Form->control('profile_desc');
?>
</fieldset>

View File

@ -16,6 +16,7 @@
<thead>
<tr>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('state_user_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('profile_desc') ?></th>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
@ -24,6 +25,7 @@
<?php foreach ($communityProfiles as $communityProfile): ?>
<tr>
<td><?= $this->Number->format($communityProfile->id) ?></td>
<td><?= $this->Number->format($communityProfile->state_user_id) ?></td>
<td><?= h($communityProfile->profile_desc) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $communityProfile->id]) ?>

View File

@ -24,5 +24,9 @@
<th scope="row"><?= __('Id') ?></th>
<td><?= $this->Number->format($communityProfile->id) ?></td>
</tr>
<tr>
<th scope="row"><?= __('State User Id') ?></th>
<td><?= $this->Number->format($communityProfile->state_user_id) ?></td>
</tr>
</table>
</div>

View File

@ -0,0 +1,37 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$this->assign('title', __('Profil ändern'));
// In a View class
$this->loadHelper('Form', [
'templates' => 'horizontal_form',
]);
?>
<div class="action-form">
<div class="form-body">
<?= $this->Form->create($profileForm, ['enctype' => 'multipart/form-data']) ?>
<?= $this->Form->control('first_name', ['label' => __('Vorname'), 'placeholder' => 'Vorname', 'value' => $user['first_name']]) ?>
<?= $this->Form->control('last_name', ['label' => __('Nachname'), 'placeholder' => 'Nachname', 'value' => $user['last_name']]) ?>
<?= $this->Form->control('profile_img', ['type' => 'file', 'accept' => 'image/*', 'label' => __('Profilbild')]) ?>
<?= $this->Form->control('profile_desc', ['label' => __('Beschreibung'), 'rows' => 4, 'placeholder' => 'Beschreibung', 'value' => $communityProfile['profile_desc']]) ?>
<?= $this->Form->button(__('Daten speichern'), ['name' => 'submit', 'class' => 'form-button']) ?>
<?= $this->Form->end() ?>
</div>
</div>
<?php // adding scripts vendor and core from ripple ui for validation effect ?>
<?= $this->Html->script(['core', 'vendor.addons']); ?>
<script type="text/javascript">
(function ($) {
'use strict';
$('textarea').maxlength({
alwaysShow: true,
warningClass: "badge badge-warning",
limitReachedClass: "badge badge-error"
});
})(jQuery);
</script>

View File

@ -5,10 +5,6 @@ use Cake\Routing\Router;
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
if(isset($user)) {
//var_dump($user);
}
$this->assign('title', __('Mein Profil'));
$this->assign(
'header',
@ -23,7 +19,7 @@ $this->assign(
<i class="material-icons-outlined user-info">assignment_ind</i>
Meine Daten
</h3>
<div class="content-collection"><!-- xxx make form with email disabled / oder "ändern" button und extraseite -->
<div class="content-collection">
<ul class="fact-list">
<li class="fact">
<span class="fact label">E-Mail Adresse:</span>
@ -31,11 +27,21 @@ $this->assign(
</li>
<li class="fact">
<span class="fact label">Vorname:</span>
<span class="fact"><?=$user['first_name']?></span><!-- xxx editable -->
<span class="fact"><?=$user['first_name']?></span>
</li>
<li class="fact">
<span class="fact label">Nachname:</span>
<span class="fact"><?=$user['last_name']?></span><!-- xxx editable -->
<span class="fact"><?=$user['last_name']?></span>
</li>
<li class="fact">
<span class="fact label">Beschreibung:</span>
<span class="fact"><?=$communityProfile['profile_desc']?></span>
</li>
<li class="fact">
<span class="fact label"></span>
<span class="fact">
<a class="link-button action-link-button" href="/profile/edit">Meine Daten ändern</a>
</span>
</li>
</ul>
</div>
@ -64,7 +70,7 @@ $this->assign(
<li class="fact">
<span class="fact label">Passwort ändern:</span>
<span class="fact">
<a href="/account/updateUserPassword" target="_blank">zum Ändern anklicken! (öffnet in neuem Tab)</a>
<a class="action-link" href="/account/updateUserPassword" target="_blank">zum Ändern anklicken! (öffnet in neuem Tab)</a>
</span>
</li>
</ul>

View File

@ -16,10 +16,15 @@ class CommunityProfilesFixture extends TestFixture
// @codingStandardsIgnoreStart
public $fields = [
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
'state_user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'profile_img' => ['type' => 'binary', 'length' => 4294967295, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
'profile_desc' => ['type' => 'string', 'length' => 2000, 'null' => true, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
'_indexes' => [
'state_user_id' => ['type' => 'index', 'columns' => ['state_user_id'], 'length' => []],
],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
'community_profiles_ibfk_1' => ['type' => 'foreign', 'columns' => ['state_user_id'], 'references' => ['state_users', 'id'], 'update' => 'restrict', 'delete' => 'restrict', 'length' => []],
],
'_options' => [
'engine' => 'InnoDB',
@ -37,6 +42,7 @@ class CommunityProfilesFixture extends TestFixture
$this->records = [
[
'id' => 1,
'state_user_id' => 1,
'profile_img' => 'Lorem ipsum dolor sit amet',
'profile_desc' => 'Lorem ipsum dolor sit amet',
],

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@
/* CONTENT */
@container-background: #fff;
@container-text: #212529;
@container-header: #21252969;
@container-shadow: rgba(183, 192, 206, .2);
@container-border: rgba(238, 238, 238, .75);

View File

@ -145,6 +145,9 @@
}
/* Generic Content */
.content-region h3 {
color: @container-header;
}
.content-region {
border-bottom: 1px dashed @light;
padding: 0 25px;

View File

@ -143,6 +143,17 @@ and open the template in the editor.
vertical-align: middle;
}
.action-link {
color: @action-button-background1 !important;
}
.action-link-button {
background-color: @action-button-background1 !important;
color: @action-button-text !important;
margin-top: 1em;
padding: .5em 1em;
}
/* CENTER FORM SPECIFICS */
.form-body form {
display: grid;