Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom fields for users - re-targeted against v8 #16100

Open
wants to merge 8 commits into
base: v8
Choose a base branch
from
77 changes: 77 additions & 0 deletions app/Helpers/CustomFieldHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Helpers;

use Illuminate\Support\Facades\Gate;

/*********************
* These two helper methods are more designed for being re-used with the new HasCustomFields Trait
*
* The 'transform' method is designed for BlahTransformer things that need to return custom field values.
*
* The 'present' method is designed for when you're trying to generate fieldlists for use in Bootstrap tables
* - typically the 'dataTableLayout' method
*
*********************/
class CustomFieldHelper {

static function transform($fieldset, $item) {
if ($fieldset && ($fieldset->fields->count() > 0)) {
$fields_array = [];

foreach ($fieldset->fields as $field) {
if ($field->isFieldDecryptable($item->{$field->db_column})) {
$decrypted = Helper::gracefulDecrypt($field, $item->{$field->db_column});
$value = (Gate::allows('assets.view.encrypted_custom_fields')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));

if ($field->format == 'DATE'){
if (Gate::allows('assets.view.encrypted_custom_fields')){
$value = Helper::getFormattedDateObject($value, 'date', false);
} else {
$value = strtoupper(trans('admin/custom_fields/general.encrypted'));
}
}

$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];

} else {
$value = $item->{$field->db_column};

if (($field->format == 'DATE') && (!is_null($value)) && ($value!='')){
$value = Helper::getFormattedDateObject($value, 'date', false);
}

$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];
}

return $fields_array;
}
} else {
return new \stdClass; // HACK to force generation of empty object instead of empty list
}
}

static function present($field) {
return [
'field' => 'custom_fields.'.$field->db_column,
'searchable' => true,
'sortable' => true,
'switchable' => true,
'title' => $field->name,
'formatter'=> 'customFieldsFormatter',
'escape' => true,
'class' => ($field->field_encrypted == '1') ? 'css-padlock' : '',
'visible' => ($field->show_in_listview == '1') ? true : false,
];
}
}
11 changes: 11 additions & 0 deletions app/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,17 @@ public static function customFieldsetList()
return $customfields;
}

/**
* Get all of the different types of custom fields there are
* TODO - how to make this more general? Or more useful? or more dynamic?
* idea - key of classname, *value* of trans? (thus having to make this a method, which is fine)
*/
static $itemtypes_having_custom_fields = [
0 => \App\Models\Asset::class,
1 => \App\Models\User::class,
// 2 => \App\Models\Accessory::class
];

/**
* Get the list of custom field formats in an array to make a dropdown menu
*
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Api/AssetModelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function index(Request $request) : JsonResponse | array
'models.deleted_at',
'models.updated_at',
])
->with('category', 'depreciation', 'manufacturer', 'fieldset.fields.defaultValues', 'adminuser')
->with('category', 'depreciation', 'manufacturer', 'adminuser')
->withCount('assets as assets_count');

if ($request->input('status')=='deleted') {
Expand Down
100 changes: 58 additions & 42 deletions app/Http/Controllers/Api/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function index(Request $request, $action = null, $upcoming_status = null)
$filter = json_decode($request->input('filter'), true);
}

$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
$all_custom_fields = CustomField::where('type', Asset::class); //used as a 'cache' of custom fields throughout this page load
foreach ($all_custom_fields as $field) {
$allowed_columns[] = $field->db_column_name();
}
Expand Down Expand Up @@ -618,48 +618,8 @@ public function store(StoreAssetRequest $request): JsonResponse

$asset = $request->handleImages($asset);

// Update custom fields in the database.
$model = AssetModel::find($request->input('model_id'));

// Check that it's an object and not a collection
// (Sometimes people send arrays here and they shouldn't
if (($model) && ($model instanceof AssetModel) && ($model->fieldset)) {
foreach ($model->fieldset->fields as $field) {

// Set the field value based on what was sent in the request
$field_val = $request->input($field->db_column, null);

// If input value is null, use custom field's default value
if ($field_val == null) {
Log::debug('Field value for ' . $field->db_column . ' is null');
$field_val = $field->defaultValue($request->get('model_id'));
Log::debug('Use the default fieldset value of ' . $field->defaultValue($request->get('model_id')));
}

// if the field is set to encrypted, make sure we encrypt the value
if ($field->field_encrypted == '1') {
Log::debug('This model field is encrypted in this fieldset.');

if (Gate::allows('assets.view.encrypted_custom_fields')) {

// If input value is null, use custom field's default value
if (($field_val == null) && ($request->has('model_id') != '')) {
$field_val = Crypt::encrypt($field->defaultValue($request->get('model_id')));
} else {
$field_val = Crypt::encrypt($request->input($field->db_column));
}
}
}
if ($field->element == 'checkbox') {
if (is_array($field_val)) {
$field_val = implode(',', $field_val);
}
}

$asset->customFill($request, Auth::user(), true);

$asset->{$field->db_column} = $field_val;
}
}

if ($asset->save()) {
if ($request->get('assigned_user')) {
Expand Down Expand Up @@ -696,6 +656,7 @@ public function update(UpdateAssetRequest $request, Asset $asset): JsonResponse
{
$asset->fill($request->validated());

<<<<<<< HEAD
if ($request->has('model_id')) {
$asset->model()->associate(AssetModel::find($request->validated()['model_id']));
}
Expand All @@ -707,6 +668,61 @@ public function update(UpdateAssetRequest $request, Asset $asset): JsonResponse
}
if ($request->input('last_audit_date')) {
$asset->last_audit_date = Carbon::parse($request->input('last_audit_date'))->startOfDay()->format('Y-m-d H:i:s');
=======
if ($asset = Asset::find($id)) {
$asset->fill($request->all());

($request->filled('model_id')) ?
$asset->model()->associate(AssetModel::find($request->get('model_id'))) : null;
($request->filled('rtd_location_id')) ?
$asset->location_id = $request->get('rtd_location_id') : '';
($request->filled('company_id')) ?
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : '';

($request->filled('rtd_location_id')) ?
$asset->location_id = $request->get('rtd_location_id') : null;

/**
* this is here just legacy reasons. Api\AssetController
* used image_source once to allow encoded image uploads.
*/
if ($request->has('image_source')) {
$request->offsetSet('image', $request->offsetGet('image_source'));
}

$asset = $request->handleImages($asset);

$problems_updating_encrypted_custom_fields = !$asset->customFill($request, Auth::user());

if ($asset->save()) {
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
$location = $target->location_id;
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) {
$location = $target->location_id;

Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id)
->update(['location_id' => $target->location_id]);
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) {
$location = $target->id;
}

if (isset($target)) {
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
}

if ($asset->image) {
$asset->image = $asset->getImageUrl();
}

if ($problems_updating_encrypted_custom_fields) {
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
} else {
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
}
}

return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
>>>>>>> d2b7828569 (This is a squashed branch of all of the various commits that make up the new HasCustomFields trait.)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Api/CustomFieldsetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class CustomFieldsetsController extends Controller
public function index() : array
{
$this->authorize('index', CustomField::class);
$fieldsets = CustomFieldset::withCount('fields as fields_count', 'models as models_count')->get();
$fieldsets = CustomFieldset::withCount('fields as fields_count')->get();

return (new CustomFieldsetsTransformer)->transformCustomFieldsets($fieldsets, $fieldsets->count());
}
Expand Down Expand Up @@ -119,7 +119,7 @@ public function destroy($id) : JsonResponse
$this->authorize('delete', CustomField::class);
$fieldset = CustomFieldset::findOrFail($id);

$modelsCount = $fieldset->models->count();
$modelsCount = $fieldset->customizables()->count();
$fieldsCount = $fieldset->fields->count();

if (($modelsCount > 0) || ($fieldsCount > 0)) {
Expand Down
20 changes: 17 additions & 3 deletions app/Http/Controllers/Api/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use App\Models\Accessory;
use App\Models\Company;
use App\Models\Consumable;
use App\Models\CustomField;
use App\Models\License;
use App\Models\User;
use App\Notifications\CurrentInventory;
Expand All @@ -42,7 +43,7 @@ public function index(Request $request) : array
{
$this->authorize('view', User::class);

$users = User::select([
$allowed_columns = [
'users.activated',
'users.address',
'users.avatar',
Expand Down Expand Up @@ -80,7 +81,12 @@ public function index(Request $request) : array
'users.autoassign_licenses',
'users.website',

])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations')
];

foreach (CustomField::where('type', User::class)->get() as $field) {
$allowed_columns[] = $field->db_column_name();
}
$users = User::select($allowed_columns)->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations')
->withCount([
'assets as assets_count' => function(Builder $query) {
$query->withoutTrashed();
Expand Down Expand Up @@ -404,7 +410,9 @@ public function store(SaveUserRequest $request) : JsonResponse
}

app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');


$user->customFill($request,Auth::user());

if ($user->save()) {
if ($request->filled('groups')) {
$user->groups()->sync($request->input('groups'));
Expand Down Expand Up @@ -477,6 +485,12 @@ public function update(SaveUserRequest $request, User $user): JsonResponse
$user->password = bcrypt($request->input('password'));
}

app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');

$user->customFill($request,Auth::user());

if ($user->save()) {

// We need to use has() instead of filled()
// here because we need to overwrite permissions
// if someone needs to null them out
Expand Down
13 changes: 8 additions & 5 deletions app/Http/Controllers/AssetModelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\StoreAssetModelRequest;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\CustomField;
use App\Models\SnipeModel;
use App\Models\User;
use App\Models\DefaultValuesForCustomFields;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
Expand Down Expand Up @@ -153,6 +155,8 @@ public function update(StoreAssetModelRequest $request, $modelId) : RedirectResp
$model->notes = $request->input('notes');
$model->requestable = $request->input('requestable', '0');

DefaultValuesForCustomFields::forPivot($model, Asset::class)->delete();

$model->fieldset_id = $request->input('fieldset_id');

if ($model->save()) {
Expand Down Expand Up @@ -456,7 +460,7 @@ private function shouldAddDefaultValues(array $input) : bool
}

/**
* Adds default values to a model (as long as they are truthy)
* Adds default values to a model (as long as they are truthy) (does this mean I cannot set a default value of 0?)
*
* @param AssetModel $model
* @param array $defaultValues
Expand Down Expand Up @@ -496,11 +500,10 @@ private function assignCustomFieldsDefaultValues(AssetModel|SnipeModel $model, a
}

foreach ($defaultValues as $customFieldId => $defaultValue) {
if(is_array($defaultValue)){
$model->defaultValues()->attach($customFieldId, ['default_value' => implode(', ', $defaultValue)]);
}elseif ($defaultValue) {
$model->defaultValues()->attach($customFieldId, ['default_value' => $defaultValue]);
if (is_array($defaultValue)) {
$defaultValue = implode(', ', $defaultValue);
}
DefaultValuesForCustomFields::updateOrCreate(['custom_field_id' => $customFieldId, 'item_pivot_id' => $model->id], ['default_value' => $defaultValue]);
}
return true;
}
Expand Down
24 changes: 1 addition & 23 deletions app/Http/Controllers/Assets/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,29 +160,7 @@ public function store(ImageUploadRequest $request) : RedirectResponse
$asset = $request->handleImages($asset);
}

// Update custom fields in the database.
// Validation for these fields is handled through the AssetRequest form request
$model = AssetModel::find($request->get('model_id'));

if (($model) && ($model->fieldset)) {
foreach ($model->fieldset->fields as $field) {
if ($field->field_encrypted == '1') {
if (Gate::allows('assets.view.encrypted_custom_fields')) {
if (is_array($request->input($field->db_column))) {
$asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column)));
} else {
$asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column));
}
}
} else {
if (is_array($request->input($field->db_column))) {
$asset->{$field->db_column} = implode(', ', $request->input($field->db_column));
} else {
$asset->{$field->db_column} = $request->input($field->db_column);
}
}
}
}
$asset->customFill($request, Auth::user()); // Update custom fields in the database.

// Validate the asset before saving
if ($asset->isValid() && $asset->save()) {
Expand Down
Loading
Loading