mutual_credit-5.0.x-dev/src/Plugin/Murmurations/CommunityCurrency.php
src/Plugin/Murmurations/CommunityCurrency.php
<?php namespace Drupal\mcapi\Plugin\Murmurations; use Drupal\smallads\Entity\SmalladInterface; use Drupal\murmurations\Plugin\Murmurations\PluginBase; use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Markup; /** * Share's the site data as murmurations Organisation schema * * @Murmurations( * id = "community_currency", * label = @Translation("Community Currency"), * schema = "complementary_currencies-v2.0.0", * profile_path = "community-currency.json", * config = "murmurations.currency_profile", * default_aggregator = "https://index.murmurations.network/v2" * ) */ class CommunityCurrency extends PluginBase implements ConfigurableInterface { protected $currencySettings; function __construct($configuration, $plugin_id, $plugin_definition, $config_factory) { parent::__construct($configuration, $plugin_id, $plugin_definition, $config_factory); } function getProfile() : array { global $base_url; $request = \Drupal::request(); $murmurations_settings = $this->configFactory->get('murmurations.settings'); $currency_settings = $this->configFactory->get('murmurations.currency_profile'); $values = [ 'primary_url' => $base_url, 'linked_schemas' => [ $this->getPluginDefinition()['schema'] ], 'location' => [ 'country' => $this->configFactory->get('system.date')->get('country.default') ], 'geolocation' => $this->getCoords(), 'profile_url' => $base_url .'/'. $this->getPublishPath(), ]; if ($r = $murmurations_settings->get('region')) { $values['location']['region'] = $r; } if ($l = $murmurations_settings->get('locality')) { $values['location']['locality'] = $l; } $values += [ 'name' => $this->configFactory->get('system.site')->get('name'), 'description' => $currency_settings->get('description'), 'area_served' => $currency_settings->get('area_served'), 'image' => $request->getSchemeAndHttpHost() . theme_get_setting('logo.url'), //'rss' => $murmurations_settings->get('rss'), 'accounting_tech' => $currency_settings->get('accounting_tech'), 'movement' => $currency_settings->get('movement'), 'convert_to_legal_money' => $currency_settings->get('convert_to_legal_money'), 'cost_recovery' => array_values($currency_settings->get('cost_recovery')), 'launch_year' => (int)$currency_settings->get('launch_year'), 'legal_form' => $currency_settings->get('legal_form'), 'monetary_model' => $currency_settings->get('monetary_model'), 'payment_tech' => array_values($currency_settings->get('payment_tech')), 'unit_of_account_type' => $currency_settings->get('unit_of_account_type'), ]; if ($currency_settings->get('publish_quantified')) { $values['num_transactions_year'] = (int)\Drupal::entityQuery('mcapi_transaction') ->condition('type', 'default') ->condition('created', strtotime('-1 year'), '>') ->noChildren() ->count() ->execute(); $values['num_users_year'] = (int)\Drupal::entityQuery('user') ->condition('access', strtotime('-1 year'), '>') ->count() ->execute(); } return $values; } /** * {@inheritDoc} */ function needed() : string { return ''; } /** * {@inheritDoc} */ function publishable($smallad) : bool { return $smallad->scope->value >= SmalladInterface::SCOPE_NETWORK; } function filterFormAlter(array &$form, FormStateInterface $form_state, array $defaults) { $defaults = array_filter($defaults); $form['#attached']['library'][] = 'smallads_murmurations/filter_form'; //make radio buttons flat $form['item_type'] = [ '#title' => $this->t('Item type'), '#type' => 'radios', '#options' => $this->itemTypes() + ['' => $this->t('Either')], '#default_value' => $defaults['item_type']??'', '#weight' => 3 ]; $form['transaction_type'] = [ '#title' => $this->t('Transaction types'), '#description' => $this->t('Leave empty to choose any type'), '#type' => 'checkboxes', '#options' => $this->transactionTypes(), '#default_value' => $defaults['transaction_type']??[], '#weight' => 4 ]; if (!$this->getExchangeType()) { $form['exchange_type'] = [ '#title' => $this->t('Exchange types'), '#type' => 'radios', '#options' => $this->exchangeTypes(), '#default_value' => $defaults['exchange_type']??[], '#required' => TRUE, '#weight' => 4 ]; } } /** * {@inheritDoc} */ function filterFormValues(array $values) : array { $output['exchange_type'] = $values['exchange_type']??$this->getExchangeType(); if (!empty($values['item_type'])) { $output['item_type'] = $values['item_type']; } if (!empty($values['transaction_type'])) { $output['transaction_type'] = $values['transaction_type']; } return $output; } /** * {@inheritDoc} */ function renderResult(\stdClass $result) : \Drupal\Core\Render\Markup { $transaction_types = explode(',', $result->transaction_type); $markup = $this->itemTypes($result->item_type) . '; '.implode(', ', $this->transactionTypes($transaction_types)); $markup .= '<br />'.$result->description; return Markup::create($markup); } /** * {@inheritDoc} * @see https://github.com/MurmurationsNetwork/MurmurationsLibrary/blob/staging/schemas/complementary_currencies-v2.0.0.json */ function configForm() : array { // could we use the mission statement for this? $form['description'] = [ '#title' => $this->t('Project description'), '#type' => 'textarea', '#default_value' => $this->configuration['description']??'', '#weight' => 2 ]; $form['area_served'] = [ '#title' => $this->t('Area served'), '#type' => 'select', '#options' => [ 'local' => $this->t('Local'), 'regional' => $this->t('Regional'), 'national' => $this->t('National'), 'international' => $this->t('International'), ], '#default_value' => $this->configuration['area_served']??'', '#weight' => 1 ]; $form['movement'] = [ '#title' => $this->t('Movement'), '#description' => $this->t('Choose one of these complementary currency movements.'), '#type' => 'select', '#options' => [ 'none' => $this->t('One-of-a-kind'), 'barter' => $this->t('Reciprocal trade / business barter'), 'timebank' => $this->t('Time bank'), 'lets' => $this->t('Local exchange trading system (LETS)'), 'crypto' => $this->t('Cryptocurrency / blockchain'), 'gre' => $this->t('Grassroots economics'), 'transition' => $this->t('Transition network'), 'other' => $this->t('Something else') ], '#default_value' => $this->configuration['movement']??'', '#weight' => 3 ]; $form['launch_year'] = [ '#title' => $this->t('Launch year'), '#type' => 'number', '#default_value' => $this->configuration['launch_year']??'', '#weight' => 4 ]; $form['legal_form'] = [ '#title' => $this->t('Legal form'), '#type' => 'select', '#options' => [ 'blockchain' => $this->t('Blockchain only'), 'charity' => $this->t('Charity'), 'cic' => $this->t('Community interest company'), 'association' => $this->t('Registered association'), 'corp' => $this->t('Incorporated company'), 'coop' => $this->t('Co-operative'), 'faith' => $this->t('Faith group'), 'housingassoc' => $this->t('Housing association'), 'residentsassoc' => $this->t('Tenants and residents association'), 'trust' => $this->t('Trust'), 'unincorporated' => $this->t('None / Unincorporated association'), 'voluntary' => $this->t('Voluntary organisation'), 'other' => $this->t('Other'), ], '#default_value' => $this->configuration['legal_form']??'unincorporated', '#weight' => 5 ]; $form['cost_recovery'] = [ '#title' => $this->t('Cost recovery'), '#description' => $this->t('Source of income for the organisation'), '#type' => 'checkboxes', '#multiple' => TRUE, '#options' => [ 'membershipFee' => $this->t('Membership fee'), 'transactionFee' => $this->t('Transaction fee'), 'demurrage' => $this->t('Savings tax / Demurrage fee / negative interest'), 'donations' => $this->t('Donations'), 'grants' => $this->t('Grants'), 'inkind' => $this->t('In-kind contributions'), 'volunteers' => $this->t('Volunteers'), ], '#default_value' => $this->configuration['cost_recovery']??[], '#weight' => 6 ]; $form['convert_to_legal_money'] = [ '#title' => $this->t('Conversion to legal tender'), '#description' => $this->t('Whether and how the currency can be exchanged for money'), '#type' => 'select', '#options' => [ 'none' => $this->t('None / unofficial only e.g LETS, timebanks, other non-monetary systems.'), 'market' => $this->t('Market based e.g. via currency markets.'), 'fullReserve' => $this->t('Legal money is 100% held in reserve'), 'fractionalReserve' => $this->t('Redeemable from a fractional reserve, perhaps using a bonding curve.'), 'other' => $this->t('Some other mechanism'), ], '#default_value' => $this->configuration['convert_to_legal_money']??'', '#weight' => 7 ]; $form['accounting_tech'] = [ '#title' => $this->t('Accounting technology'), '#description' => $this->t('N.B. The accounting software may differ from the user interface'), '#type' => 'select', '#options' => [ 'blockchain' => $this->t('Blockchain'), 'cyclos' => $this->t('Cyclos'), 'cms' => $this->t('CMS Plugin'), 'webService' => $this->t('Accounting web service'), 'mesh' => $this->t('Mesh credit (a.k.a Ripple)'), 'app' => $this->t('All in one with the App'), 'p2p' => $this->t('P2P App (e.g. Holochain)'), 'other' => $this->t('Unpublished / proprietary') ], '#default_value' => $this->configuration['accounting_tech']??'other', '#weight' => 8 ]; $form['payment_tech'] = [ '#title' => $this->t('Payment technology'), '#description' => $this->t('How do users make payments and view their accounts?'), '#type' => 'checkboxes', '#multiple' => TRUE, '#options' => [ 'cheque' => $this->t('Cheques'), 'physical' => $this->t('Circulating paper / physical tokens'), 'book' => $this->t('Each member keeps an account book'), 'plastic' => $this->t('Plastic cards with PoS system'), 'web' => $this->t('Web site'), 'app' => $this->t('Mobile app'), 'other' => $this->t('Other') ], '#default_value' => $this->configuration['payment_tech']??[], '#weight' => 9 ]; $form['monetary_model'] = [ '#title' => $this->t('Monetary model'), '#description' => $this->t('The basis of issuance and redemption.'), '#type' => 'select', '#options' => [ 'tokens' => $this->t('Fixed number of tokens e.g. Bitcoin'), 'points' => $this->t('Tokens issued as needed e.g. Time banks, reputation scores'), 'mutual' => $this->t('Mutual credit e.g. Sardex, Wir, business barter, LETS'), 'selfIssued' => $this->t('Self-issued credit e.g. shopping vouchers, deli dollars, self-signed cheques'), 'mesh' => $this->t('Mesh credit (a.k.a Ripple)'), 'hybrid' => $this->t('Hybrid'), 'other' => $this->t('Other') ], '#default_value' => $this->configuration['monetary_model']??'other', '#weight' => 10 ]; $form['unit_of_account_type'] = [ '#title' => $this->t('Unit of account'), '#description' => $this->t('The basis of issuance and redemption.'), '#type' => 'select', '#options' => [ 'time' => $this->t('Time based e.g. hour'), 'legal' => $this->t('Equivalent to national legal unit e.g. US dollar.'), 'market' => $this->t('Pure supply & demand e.g. Bitcoin'), 'index' => $this->t('Indexed to a commodity price or basket e.g. gold, eggs'), 'redeemable' => $this->t('Redeemable for a commodity e.g. vouchers'), 'other' => $this->t('Other e.g. Most LETS create arbitary units') ], '#default_value' => $this->configuration['unit_of_account_type']??'other', '#weight' => 11 ]; $form['publish_quantified'] = [ '#title' => $this->t('Publish transaction summary data'), '#description' => $this->t('No personal information is shared.'), '#type' => 'checkbox', '#default_value' => $this->configuration['publish_quantified']??0, '#weight' => 12 ]; return $form; } }