Commit 1a1ef1a6 authored by vlad.dancer's avatar vlad.dancer
Browse files

Revert "Release of initial 8.x-2.x version"

This reverts commit 451cd05d.
parent 451cd05d
## Media
## Roadmap
after release
- @todo: prefix file name with our prefix to track later this files
- @todo: refactor assets, models to the typed data.
- @todo: add custom entity type to use inside custom field based formatter
- @todo: add extensions/alterations points: like events, hooks, etc
- @q: suggest to implement oEmbed support on api side
- @q: how about provide some file ids to allow later sync with drupal?
Same as acquia
- @q: how about to provide file id to dissallow create more than one
local copy
add fileuuid into textarea and where to store it in media?
- @q: do we need "back", "forward" functionality.
## Issues
Related issue to the error "not allowed media type"
https://www.drupal.org/project/entity_browser/issues/2822354
## Property testing
https://github.com/steos/php-quickcheck
https://gist.github.com/amitsaha/8a8c5e3540f81dd22c80
https://stackoverflow.com/questions/6028249/property-based-testing-in-php
https://github.com/JetBrains/intellij-community/blob/282e4ff321a0d0014e977c5602f1baee80a148f1/java/java-tests/testSrc/com/intellij/java/propertyBased/UnivocityTest.java
http://www.giorgiosironi.com/2015/06/property-based-testing-primer.html
https://eax.me/tag/testirovanie/
## Integrations
WP http://plugins.svn.wordpress.org/intelligencebank-connector/trunk/inc/app.php
https://wordpress.org/plugins/intelligencebank-connector/
## Resources
https://intelligencebank.atlassian.net/wiki/spaces/APIDOC/overview
https://www.drupal.org/node/2444549
https://www.drupal.org/project/entity_browser_enhanced
https://dri.es/an-update-on-the-media-initiative-for-drupal-8-4-8-5
## CS
`vendor/bin/phpcs --exclude=Drupal.Formatting.MultipleStatementAlignment --standard=Drupal ib_dam`
`vendor/bin/phpcs --standard=Security ib_dam`
`vendor/bin/phpcs --standard=DrupalPractice ib_dam`
`CMD + K`
# IntelligenceBank DAM Integration
## Introduction
This modules suite integrates IntelliganceBank DAM for an importing,
or embedding Assets from the service.
Currently, there are two ways to import/embed assets from DAM:
* using **IB: Media integration** module,
based on core Media module and [Entity Browser](https://www.drupal.org/project/entity_browser)
* using **IB: CKEditor WYSIWYG integration**
------
*Which one should I use?*
Use **IB: Media integration** if your asset workflow based on Media module.
In other case use WYSIWYG integration.
## Requirements
For the **ib_dam_media**:
* core Media (>= 8.5)
* [Entity Browser](https://www.drupal.org/project/entity_browser) (>= 2)
For the **ib_dam_wysiwyg**
* core modules: Field, Filter, CKEditor.
## Installation
Modules can be installed via the
[standard Drupal installation process](http://drupal.org/node/895232).
## Configuration
**Media integration**
[Documentation](https://legacy.gitbook.com/book/drupal-media/drupal8-guide/details) about Media module can be found here
Quick configuration steps:
1. Install and enable [Entity_Browser](https://www.drupal.org/project/entity_browser) module.
2. Enable core Media module.
3. Ensure that you have a couple of Media Types in your system.
4. Install and enable **IB: Media integration** module.
5. Go to the *IntelligenceBank Media Configuration* page `admin/config/services/ib_dam/media`
* Map each source asset type with the corresponding media type.
* Map **Embed type** with **IntelligenceBank DAM Embed** media type,
in order to allow embedding assets from DAM without downloading them locally.
6. Create a new Entity Browser ([documentation](https://drupal-media.gitbooks.io/drupal8-guide/content/modules/entity_browser/creating_browser_through_ui.html)),
or use your existing one.
* Add **IntelligenceBank Asset Browser** widget to the list on Widgets page,
`Edit Entity browser > General information > Display > Widget selector > Selection display > Widgets`.
You can also change there upload directory setting.
7. Create or use existing Entity reference field of the Media type. For example:
* Go to the Article content type structure page `admin/structure/types/manage/article/fields`
* Add new Media Reference field type: Add a new field > Reference > Media
* On the field settings page select all media types that you want to use.
(This is a list of Media types which are allowed to insert).
* Next, you need to set Widget for the newly created field from the steps above:
Administration > Structure > Content types > Article >
Manage form display > Your field > Widget: Entity browser,
and select entity browser from steps above
8. Now you are ready to use **IntelligenceBank DAM Media integration**.
For example go to the Article node edit page and open the entity browser.
**WYSIWYG integration**
The one is based on the CKEditor module to show Asset Browser,
and on the custom Text filter to render assets.
Quick configuration steps:
1. Enable core CKEditor module.
2. Install and enable **IB: CKEditor WYSIWYG integration** module.
3. Go to the "Text formats and editors" configuration page: `/admin/config/content/formats`,
and for each text format/editor combo where you want to use assets from DAM,
do the following:
* Enable the **IntelligenceBank DAM WYSIWYG** filter,
in the "Enabled filters" section.
* Drag and drop the ![](http://www.intelligencebank.com/themes/pnc/favicon.ico) button into the Active toolbar.
* In the "CKEditor plugin settings" section configure such options,
like: *Upload location*, *Allowed file extensions list*, *Allow public assets*
* In the "Filter processing order" section ensure that the "IntelligenceBank DAM WYSIWYG" filter **comes after** "Restrict images to this site" (if you using this filter), [related information](https://www.drupal.org/project/entity_embed/issues/2752253)
4. Don't forget to enable permissions to use text filter for specific roles,
on the user permissions page.
----
## Usage
General Asset Browser [documentation](https://help.intelligencebank.com/hc/en-us/articles/115001513243-About-the-IntelligenceBank-Universal-Connector)
**Media integration**
1. Open the Entity Browser on content editing page,
select newly created upload widget.
2. Use the modal dialog to browse and get assets.
3. Assets will be automatically fetched to Drupal after you click on download buttons in asset browser.
**WYSIWYG integration**
1. For example, create the new *Article* content.
2. Click on the ![](http://www.intelligencebank.com/themes/pnc/favicon.ico) button in the text editor,
you will get modal dialog with the asset browser.
3. Login in to DAM using your credentials.
4. Browse the assets and click either the "Download" or the "Public" button on a certain Asset
* in case of "Download" button, Drupal will download the asset file locally
* in case of "Public" button, Drupal will get an link to the remote asset,
and create an embedded asset in the editor.
5. After the asset selection, you can change asset display options at the next step.
6. Save the content and check the uploaded Assets.
## Limitations
Currently, there is no support for [Entity Embed](https://www.drupal.org/project/entity_embed) module to embed media within the content.
IntelligenceBank Dam
{
"name": "drupal/ib_dam",
"type": "drupal-module",
"description": "Proof of concept integration with intelligencebank.com service",
"keywords": ["Drupal"],
"license": "GPL-2.0+",
"homepage": "http://www.intelligencebank.com",
"minimum-stability": "dev",
"authors": [
{
"name": "Vladyslav Moyseenko (vladdancer)",
"homepage": "https://www.drupal.org/u/vladdancer",
"role": "Maintainer"
}
],
"support": {
"issues": "https://www.drupal.org/project/issues/ib_dam",
"source": "http://cgit.drupalcode.org/ib_dam"
}
}
ib_dam.settings:
type: config_object
label: 'IntelligenceBank DAM configuration'
mapping:
debug:
type: boolean
label: 'Enable debug mode'
.ib-dam-app-wrapper {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
}
.ib-dam-app-browser {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ib-dam-browser__widget-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
opacity: 0.7;
filter: alpha(Opacity=70);
}
name: 'IntelligenceBank DAM'
type: module
description: 'The bridge between IntelligenceBank DAM & Drupal'
core: 8.x
package: 'IntelligenceBank DAM'
libraries.pnotify:
remote: github.com/sciactive/pnotify
version: '3.2.1'
license:
name: 'Apache License 2.0'
url: https://github.com/sciactive/pnotify/blob/v3.2/LICENSE
gpl-compatible: true
css:
component:
https://cdnjs.cloudflare.com/ajax/libs/pnotify/3.2.1/pnotify.css: {type: external, minified: true}
theme:
https://cdnjs.cloudflare.com/ajax/libs/pnotify/3.2.1/pnotify.brighttheme.css: {type: external, minified: true}
js:
https://cdnjs.cloudflare.com/ajax/libs/pnotify/3.2.1/pnotify.js: { type: external, minified: true, weight: -1}
common:
version: VERSION
js:
js/ib_dam.common.js: {}
browser:
version: VERSION
css:
theme:
css/ib_dam.iframe_browser.css: {}
js:
js/ib_dam.iframe_browser.js: {}
dependencies:
- core/jquery
- core/drupal
- ib_dam/libraries.pnotify
- ib_dam/common
- core/underscore
ib_dam.settings_form:
title: 'IntelligenceBank DAM'
route_name: ib_dam.settings_form
parent: system.admin_config_services
description: 'IntelligenceBank global settings.'
ib_dam.settings_form:
title: 'Global settings'
route_name: ib_dam.settings_form
base_route: ib_dam.settings_form
<?php
/**
* @file
* Intelligence DAM primary module file.
*/
/**
* Implements hook_theme().
*/
function ib_dam_theme() {
return [
'ib_dam_embed_playable_resource' => [
'variables' => [
'resource_type' => NULL,
'url' => NULL,
'title' => NULL,
'mimetype' => NULL,
'attributes' => NULL,
],
],
];
}
administer intelligencebank configuration:
title: 'Administer IntelligenceBank configuration'
description: 'This permission gives user ability to set up additional options for IntelligenceBank Digital Asset Management service.'
ib_dam.settings_form:
path: '/admin/config/services/ib_dam'
defaults:
_form: '\Drupal\ib_dam\Form\IbSettingsForm'
_title: 'IntelligenceBank Settings'
requirements:
_permission: 'administer intelligencebank configuration'
services:
logger.channel.ib_dam:
class: Drupal\Core\Logger\LoggerChannel
factory: logger.factory:get
arguments: ['ib_dam']
ib_dam.api:
class: Drupal\ib_dam\IbDamApi
arguments: ['@http_client', '@logger.channel.ib_dam']
ib_dam.downloader:
class: Drupal\ib_dam\Downloader
arguments:
- '@ib_dam.api'
- '@config.factory'
- '@logger.channel.ib_dam'
- '@file_system'
- '@uuid'
plugin.manager.ib_dam.asset_validation:
class: Drupal\ib_dam\AssetValidation\AssetValidationManager
parent: default_plugin_manager
var ibDam = function () {
const IB_DAM_ALLOWED_EMBED_HOSTS = [
'public2.intelligencebank.com',
'apius.intelligencebank.com',
'apiau.intelligencebank.com',
'apieu.intelligencebank.com',
];
const EMBED_TYPE = 'embed';
const LOCAL_TYPE = 'local';
function getHost(url) {
var l = document.createElement('a');
l.href = url;
return l.hostname;
}
function isEmpty(obj) {
if (obj === null || obj === undefined) {
return true;
}
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return obj == '' ? true : false;
}
function flattenProperties(item) {
return Object.keys(item).map(function (k) { return k + ': ' + item[k] })
.join(", ");
}
function isValidHost(url) {
if (url === undefined) {
return false;
}
return IB_DAM_ALLOWED_EMBED_HOSTS.indexOf(getHost(url)) !== -1
}
return {
allowedHosts: IB_DAM_ALLOWED_EMBED_HOSTS,
isValidHost: isValidHost,
isEmpty: isEmpty,
flattenProperties: flattenProperties,
sourceTypes : {
embed : EMBED_TYPE,
local : LOCAL_TYPE,
}
};
}();
/**
* @file
*
* IntelligenceBank Iframe Asset Browser.
*/
(function (window, $, _, Drupal, _ib) {
'use strict';
const DOWNLOAD_TYPE = 'resource_download';
const EMBED_TYPE = 'resource_link';
const ASSET_SELECTED = 'ib_dam_browser:set_data';
var stack_modal = {
"dir1": "down",
"dir2": "left",
"push": "top",
};
// Global id of the current asset browser instance.
// It is used to fire an unique "asset selected" event,
// only one instance subscribed to this event should save asset data.
window.top.ibDamAppId = '';
Drupal.behaviors.ibDamIfraneBrowserWidget = {
attach: function (context, settings) {
var appSettings = settings.ib_dam.browser,
$searchFrame = $('.ib-dam-app-browser', context);
if (!$searchFrame.length) {
return false;
}
$searchFrame.once('ibDamIframeBrowserWidget').each(function () {
attachApp(appSettings, $(this));
});
var assetEventListener = function(e) {
var asset = getAppResponse(e.data, appSettings.allowedTypesList);
var appId = _ib.isEmpty(window.top) || _ib.isEmpty(window.top.ibDamAppId)
? false
: window.top.ibDamAppId;
if (!appId || !asset || !isOriginalHost(e.origin, appSettings.host)) {
return;
}
$.event.trigger(ASSET_SELECTED + ':' + appId, {
appId: appId,
asset: asset,
settings: appSettings
});
};
// Add global subscriber to route asset data to current active asset browser.
window.top.addEventListener('message', assetEventListener, false);
}
};
function attachApp(appSettings, appEl) {
var uuid = 'ib-dam-' + generateGuid(),
$throbber = Drupal.theme('ajaxProgressIndicator');
appEl.attr('id', uuid);
var $submit = $('form:has(#'+uuid+')')
.first()
.find(appSettings.submitSelector)
.hide();
appEl.before($throbber)
.attr('src', appSettings.appUrl)
.on('load', function () {
appEl.focus();
$throbber.remove();
window.top.ibDamAppId = uuid;
});
// @todo: PRE maybe we need also mouseout when deals with only modals.
// This handler used to track current active asset browser,
// because only mouse* events are fired on iframe elements.
appEl.get(0).addEventListener('mouseover', function (e) {
window.top.ibDamAppId = $(event.target).attr('id');
}, true);
// Subscribe each instance only to unique, per instance,
// "asset selected" event.
$(window).on(ASSET_SELECTED + ':' + uuid, function (e, data) {
saveAssetsData(data.appId, data.asset, data.settings);
});
}
/**
* Save asset handler.
*
* Used to set value of hidden form element to pass asset data to backend.
* Prepare data, set element value, UI interactions, show/hide info messages.
*/
function saveAssetsData(appId, asset, settings) {
var $appEl = $('#'+ appId),
$wrapper = $appEl.parent('.ib-dam-app-wrapper'),
$submit = $('form:has(#'+appId+')').first().find(settings.submitSelector),
$overlay = Drupal.theme('ajaxOverlay', {idx: 100}),
$throbber = Drupal.theme('ajaxProgressIndicator');
if (settings.debug === true) {
console.log(asset);
}
if ((isEmbedType(asset) && settings.allowEmbed)
|| (isValidFileType(settings.fileExtensions, asset.filetype) && !isEmbedType(asset))
) {
$wrapper.siblings('input[name="ib_dam_app[response_items]"]')
.val(JSON.stringify(asset));
$submit
.after($throbber)
.trigger('click');
$wrapper.append($overlay);
closeAllWarnings();
}
else {
isEmbedType(asset)
? showWarning(settings.messages, 'embed')
: showWarning(settings.messages, 'local')
}
}
/**
* Theme function for ajax progress Indicator.
*
* @return {object}
* This function returns a jQuery object.
*/
Drupal.theme.ajaxProgressIndicator = function () {
return $('<div class="ajax-progress-fullscreen"></div>');
};
/**
* Theme function for ajax overlay element.
*
* @return {object}
* This function returns a jQuery object.
*/
Drupal.theme.ajaxOverlay = function (settings) {
return $('<div class="ib-dam-browser__widget-overlay"></div>').css('z-index', settings.idx);
};
function getHost(url) {
var l = document.createElement('a');
l.href = url;
return l.hostname;
}
function isOriginalHost(source, expected) {
return getHost(source) === expected;
}
function getAppResponse(dataString) {
var data = JSON.parse(dataString);
if (data.action === undefined) {
return false;
}
return [EMBED_TYPE, DOWNLOAD_TYPE].indexOf(data.action) !== -1
? data
: false
}
function isEmbedType(item) {
return item.action === EMBED_TYPE;
}
function isValidFileType(allowedList, type) {
if (!allowedList.length) {
return false;
}
return allowedList.indexOf(type.toLowerCase()) !== -1
}
function closeAllWarnings() {
PNotify.removeStack(stack_modal);
}
function showWarning(messages, message_id) {
var message = _.findWhere(messages ,{id: message_id});
if (message.notification !== undefined && message.once === true) {
message.notification.open();
return;
}
message.notification = createNotification(message.title, message.text);
handleNotificationClick(message.notification);
}
function handleNotificationClick(notification) {
notification.get().click(function() {
notification.remove();
});
}
function createNotification(title, text) {
return new PNotify({
title: title,
text: text,
cornerclass: '',
type: 'notice',
stack: stack_modal,
remove: true,
hide: true,
delay: 18000
});
}
function generateGuid() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
})(window, jQuery, _, Drupal, ibDam);
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_media_ib_dam_embed
- media.type.ib_dam_embed
module:
- link