8 – Get image file values in $form_state in media entity form

I am trying to get the values from an uploaded image inside a media entity during form submit.

Where my approach doesn’t work:

  1. When first uploading an image in the media_image_add_form form.
  2. When editing an existing media entity and removing, then uploading a new image and trying to save.

My validation only works when editing and submitting an existing media entity (without changing the uploaded image file).

Here is my entire code for brevity, though it may be long, MYMODULE.module:

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if ($form_id == 'media_image_add_form' || $form_id == 'media_image_edit_form') {

    if ($form_state->getFormObject()->getEntity()->get("field_media_image")->entity) {

      $form('#validate')() = '_MYMODULE_validate';
    }
  }
}

/**
 * Validates submission values in the FORM_ID() form.
 */
function _MYMODULE_validate(array &$form, FormStateInterface $form_state) {

  // $imageEntity = File::load($form_state->getValues()('field_media_image')(0)('fids')(0)); // Tried File::load here as well.
  $imageField = $form_state->getFormObject()->getEntity()->get("field_media_image");
  $imageEntity = $imageField->entity;
  $imageFileSize = $imageEntity->getSize();
  $imageFileMime = $imageEntity->getMimeType();
  $imageFileName = $imageEntity->getFilename();
  $isIssue = FALSE;
  $showConditionalMessage = FALSE;
  $ciuMessage = "";
  $ignoreWarnings = $form_state->getValues()('field_ignore_warnings')('value'); // Field set on media image entity type.

  // Conditional issue.
  if ($ignoreWarnings === 0 && $imageFileMime === "image/jpeg" && $imageFileSize / 1000 > 150) {
    $isIssue = TRUE;
    $showConditionalMessage = TRUE;
    $ciuMessage .= "<p>Conditional: This JPG file size is larger than 150kb, have you optimized this JPG image?</p>";
  }

  // Conditional issue.
  if ($ignoreWarnings === 0 && $imageFileMime === "image/png" && $imageFileSize / 1000 > 200) {
    $isIssue = TRUE;
    $showConditionalMessage = TRUE;
    $ciuMessage .= "<p>Conditional: This PNG file size is larger than 200kb, have you optimized this PNG image?</p>";
  }

  // Non-conditional issue.
  if (strpos($imageFileName, ' ') !== false) {
    $isIssue = TRUE;
    $ciuMessage .= "<p>Filenames cannot contain spaces.</p>";
  }

  // Non-conditional issue.
  if (strtolower($imageFileName) !== $imageFileName) {
    $isIssue = TRUE;
    $ciuMessage .= "<p>Filenames need to be in all lowercase.</p>";
  }

  if ($isIssue) {
    if ($showConditionalMessage) {
      $ciuMessage .= '<small>To ignore conditional errors, check the "Ignore conditional errors" checkbox below.</small>';
    }
    $form_state->setErrorByName('title', new FormattableMarkup($ciuMessage, ()));
  }
}

One caveat for using hook_form_alter() is that some of the errors are conditional, and I would like to provide a field on the media entity type to allow ignoring some of the errors.

How can I get the uploaded file/values in $form_state when adding an image to a new media entity, or adding a new image to an existing media entity?

entities – Filter by text of a field of an entity displayed in a view

I have following content types: “Person” and “Publication” and I’m showing the publications using a view on a page, showing title, year, venue and authors. The authors in “Publication” are referenced to “Person” via entity reference.

I added filter criteria so the users visiting the page can search publications based on title, author etc. The problem now is, that the field for searching by author only accepts the author’s entity ID. But I want the user to search by a part of the author’s name (either the entity title or a specific field in the “Person” entity).

What would be the best way to do this? I tried different ways via contextual filters, relationships and entity reference on the view, but neither of them worked for me, or I made something wrong. Any help would be appreciated!

entity framework – C# Winforms App ,EF6, DB First with Auto Mapper Generic Repository and UOW context is not updated automatically when database is changed externally

I’ve started to work on a single user c# winforms application, with EF6 db first approach, AutoMapper, Generic Repository and UnitOfWork. They have been previously implemented by others former colleagues . I’m not very experienced with those concepts but I have read a lot of links.
The main issue is now that the single user c# app needs to be updated for multiuser environment. Using the current implementation , the external changes(like update operations) performed on database are not visible inside de controller.

I’ve tried using _unitOfWork.Context.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, _tableRepository.FindAllInContext()); to refresh the context but I think this is not a good option, because if I try to update a table column value after refresh, the action will not be saved in database.

 public interface IDbEntity
    {
        int Id { get; set; }
        bool IsDeleted { get; set; }
    }
 
 public interface IRepository<T, T1>
        where T : class, IDbEntity
        where T1 : class, IDbEntity
    {
        int Add(T1 newEntityViewModel);
        void AddRange(List<T1> newEntities);
        void Remove(int id);
        void RemoveFromDb(int id);
        List<T1> Find(Expression<Func<T1, bool>> predicate);
        T1 FindById(int id);
        List<T1> FindAll();
        T FindByIdInContext(int id);
        int GetNextId();
        List<T> FindAllInContext();
    }
    
    internal class DbRepository<T, T1> : IRepository<T, T1>
        where T : class, IDbEntity
        where T1 : class, IDbEntity
    {
        protected ObjectSet<T> _objectSet;
        protected List<T1> _internalList;
        protected ObjectContext _context;

        public DbRepository(ObjectContext context)
        {
            try
            {
                
                _internalList = new List<T1>();
                _objectSet = context.CreateObjectSet<T>();
                _context = context;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                throw;
            }
        }



        public int Add(T1 newEntityViewModel)
        {
            try
            {
                var entityDto = AutoMapperConfiguration.GetMapperConfiguration().Map<T1, T>(newEntityViewModel);
                _objectSet.AddObject(entityDto);

                _context.SaveChanges();
                
                //check id 
                return entityDto.Id;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                throw;
            }
        }


        public List<T1> Find(Expression<Func<T1, bool>> predicate)
        {
            try
            {
                var listT1 = AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(_objectSet.Where(q => !q.IsDeleted));
                var result = listT1.Where(predicate.Compile()).ToList();

                return result;
            }
            catch (Exception ex)
            {
               log.Error(ex.Message);
                throw;
            }
        }

        public List<T1> FindAll()
        {
            try
            {
                var listT1 = AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(_objectSet.Where(q => !q.IsDeleted));
                return listT1;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                throw;
            }
        }

    }
    
    
    public interface IUnitOfWork
    {
        IRepository<User, User_ViewModel> Users { get; }
        IRepository<Type, Type_ViewModel> Types { get; }
        
        /// and a lot more repositories

        ObjectContext Context { get; }
        void Commit();
    }
    
    
    internal class DbUnitOfWork : IUnitOfWork
    {
        private DbRepository<User, User_ViewModel> _users = null;
        private DbRepository<Type, Type_ViewModel> _types = null;
       
       
       
        private readonly ObjectContext _context;
        private readonly EntityConnection _connectionString;

   
        public ObjectContext Context { get { return _context; } }

        public DbUnitOfWork(EntityConnection connectionString)
        {
            try
            {
                _connectionString = connectionString;
                _context = new ObjectContext(connectionString, true);
                _context.ContextOptions.LazyLoadingEnabled = true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                throw;
            }
        }

        public IRepository<User, User_ViewModel> Users
        {
            get
            {
                return _users ?? (_users = new DbRepository<User, User_ViewModel>(_context));
            }
        }


        public IRepository<Type, Type_ViewModel> Types
        {
            get
            {
                return _types ?? (_types = new DbRepository<Type, Type_ViewModel>(_context));
            }
        }



        public void Commit()
        {
            try
            {
               _context.SaveChanges();

            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                throw;
            }
        }

    }
    
    DbController.cs
    public partial class DbController
    {
        protected readonly IUnitOfWork _unitOfWork;
        
        protected readonly IRepository<User, User_ViewModel> _userRepository;
        protected readonly IRepository<Type, Type_ViewModel> _typeRepository;
        
        
        public SafeIOController(IUnitOfWork unitOfWork)
        {
           

            _unitOfWork = unitOfWork;
            
            _userRepository = _unitOfWork.Users;
            _typeRepository = _unitOfWork.Types;
            
        }

        public void Save()
        {
            _unitOfWork.Commit();
        }
    }
    Controller_User.cs
    public partial class DbController
    {
       

        public List<User_ViewModel> GetAllUsers()
        {
            try
            {
                
                return _userRepository.FindAll();

            }
            catch (Exception ex)
            {
                _exHandler.LogErrorMessage(Constants_Exception.DB_EXCEPTION_MSG, ex, _exHandler.GetCurrentMethod());
                throw;
            }
        }


        
    }
    
    and then in winforms app 
    
            _unitOfWork = new DbUnitOfWork(connectionString);
            _controller = new DbController(_unitOfWork);

How can I properly implement unitOfWork in order to have the latest information from db inside my context?

javascript – How to draw the player standing behind a tree in an Entity Component System?

I’m making a top-down Javascript canvas game using the Entity Component System architecture.

For an entity to be drawn on the screen every frame, it needs a PositionComponent and a SpriteComponent. The rendering system looks like this:

for (let entity of scene.query(CT.Sprite, CT.Position)) {      
  this.drawEntity(entity);
}

This works well, but I’m not sure how to modify this to give the player the ability to hide behind objects. For example, in Stardew Valley, you can stand in front of, and behind, objects, as demonstrated in this screenshot: https://i.imgur.com/B90jGS7.png

How can this be implemented in an ECS? Because currently my rendering system just iterates through every object and draws them.

Also, currently, for drawing the map (scenery and whatnot), it renders the map to a texture and then just redraws that single texture every frame (for performance reasons, instead of redrawing 10,000 tiles every frame). I’d imagine this makes it even more difficult to integrate.

My assumption is that I have to take into account the entity’s position in some way? That is, an entity with { x: 0, y: 400 } will be drawn before an entity with position { x: 0, y: 500 }, but I’m also unsure of how to integrate this with an ECS.

Thanks for reading.

entities – Limited editing of just the order of entity reference field

I would like to give some users the opportunity to edit the ORDER of a field of entity references holding multiple references– but not the references themselves.

One option would be to post process the field and turn off the editability of the form element. But this seems like to create the form element and then disable it.

Is there a better way?

entities – Increase maximum amount of characters for entity reference field (tag style)

I have a Drupal 9 installation running Commerce 2. My products use a taxonomy entity reference field (tag style). There’s one products category, where I need to have more references in the tag input field than currently allowed (1024 characters).

I looked it up and found a similar post where someone suggested to write a module to increase the maximum input value like so:

function MODULE_field_widget_form_alter(&$element, &$form_state, $context) {

  if ($context('widget')->getPluginId() == 'entity_reference_autocomplete') {
    if ($element('target_id')('#maxlength') == 1024) {
      $element('target_id')('#maxlength') = 3072;
    }
  }
}

So I did that, but it still doesn’t let me input more than 1024 characters. Any help would be appreciated. Thank you!

8 – How can I reference an entity field in a template file?

I am trying to theme the node add/edit form for a custom content type (for example, Album). I implemented hook_form_alter() in the theme.

function mytheme_form_alter(&$form, DrupalCoreFormFormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case "node_album_form":
      $form('#theme') = ('node_album_edit_form');
      break;
  }
}

That correctly intercepts the node add/edit form and passes it to my theme hook which also finds the correct template.

function mytheme_theme() {
  return (
    'node_album_form' => (
      'template' => 'node_album_edit_form',
      'path' => Drupal::theme()->getActiveTheme()->getPath() . '/scss/templates/album',
      'render element' => 'form'
    ),
  );
}

In node_album_edit_form.html.twig, I can confirm that changes there alter only the album add/edit form and that I can remove elements with {{ form|without('advanced', 'footer', 'actions') }}, for example.

What I cannot do is placing the form fields where I want them because I’m not using the right reference to the field.

<div class='myfancydiv album-title-field'>{{ field_album_title }}</div>
<div class='myfancydiv album-artist-field'>{{ field_artist }}</div>

I tried any of the following, but they didn’t work.

  • {{ field_album_title }}
  • {{ form.field_album_title }}
  • {{ album_title }}

How can I reference an entity field in a template file?

architecture – Rendering order in an Entity System

Sort at rendering time if you sort at all. You don’t need to keep the list sorted during every operation; in fact, this may be harmful. What happens if you spawn 20 enemies at once? Sort 20 times? They sorted quality doesn’t matter until rendering, so why ever do it more than once per frame?

Furthermore, with an entity-component system, it can be handy to keep component databases sorted similarly. Despite all the theoretical cruft on the Internet about ECS, you will at times need to update two object lists in parallel or otherwise break out of the single-system ideal. Keeping the entities’ components in these lists consistently ordered will make such updates faster; instead of iterating over one list sequentially and the other in essentially random order, you iterate over both sequentially. Your component databases should intrinsically have this property.

There’s also a strong argument to make for separate object collections. The ComponentSprite component can just be a data record noting what the object wants rendered while a completely separate scene graph manages SceneSprite objects that deal with efficient rendering. Complex game objects might be made out of multiple sprites or so on in ways that are inefficient to handle with game object hierarchies. Your renderer and object systems don’t need to be interdependent. Or they can be. Whichever is easier for your game.

When the renderable list changes, just mark a flag that it’s dirty. Before rendering, check the flag and resort if it’s set (and then unset the flag, of course).

In 3D systems this is more important as the entire sort order is likely to shift and change almost every frame.

Remember that it’s not just layer you might want to sort by. With enough objects on screen – even in 2D – you might need to sort by screen tile, sprite, effect, etc., in addition to or instead of layer/depth.

For many games you can split your renderable object list into a set of layer “buckets.” When an object is create/removed/re-layered, just perform a simple add/remove as necessary to the corresponding bucket(s). No need for explicit sorting steps at all. Many 2D games work with only a few pre-defined layers so they’re simply no need for arbitrary depth/layer values to sort by.

entity system – Ways to persist entities and components in an ECS?

I am working on a small multiplayer game with rpg elements using java and “Artemis ODB”. Most of the logic is already done but one important thing is missing. The persistence.

So i am searching for different ways to persist my game. One thing is important, the world is huge and i cant load in the whole world at once. I already stumbled upon two different ways on my own. Using a relational database or a nosql database. But one thing scares me… entity references.

In my game i have an player entity and item entities. The player entity owns a inventory component which stores a reference to some item entities. In my ecs, each entity reference is an simple integer. So this looks like this…

/**
 * Represents the Inventory of our game, contains references to entities acting as items.
 */
public class Inventory extends HibernateComponent {
    public Set<Integer> itemEntities = new LinkedHashSet<>();
}

Why does this scare me ? Well… Entity references are Integers in my case. They are no real ID and i cant set or change this “ID” of an entity because my framework permits it. This brings us straight to the problem. When i serialize this component or the whole player entity it would look like this.

Inventory{
   itemEntities: (40,2,5,50)
}

So when we save this and load it later on we have no entity with the id 40… and even if we recreate that entity we cant set it to an id of 40, because the frameworks permits it. So how the heck do we save references between entities ? ^^

So all in all… what are common ways to save, load entities from an ecs ? How do you do it ? And what would you recommend ?

Get original entity in a constraint

Is it possible to get the original entity in a constraint?

Use case: create a constraint on which item can be deleted in a multi value field