Skip to content

Commit

Permalink
Merge branch 'craft-4' of https://github.com/verbb/hyper into craft-5
Browse files Browse the repository at this point in the history
# Conflicts:
#	composer.json
#	src/base/Link.php
  • Loading branch information
engram-design committed Mar 4, 2024
2 parents ec35e57 + b4aa8ba commit 42aa585
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 18 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 1.1.21 - 2024-03-04

### Added
- Add the ability to set the column type for Hyper fields.

### Changed
- Embed link types now create `<iframe>` elements when embed responses don’t contain them.

### Fixed
- Fix custom attributes not saving correctly.
- Fix Selectize fields not working properly when re-ordering link blocks which Hyper was contained in a Matrix/Super Table field.

## 1.1.20 - 2024-01-30

### Added
- Add the ability to make the `linkValue` a required field.

### Fixed
- Fix element-based link types not validating correctly when a non-uri element is selected.
- Fix being unable to select User elements for User link type.
- Fix when making changes to a link, switching between link types would not retain any changes.

## 1.1.19 - 2023-12-20

### Added
Expand Down
13 changes: 11 additions & 2 deletions docs/developers/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ The event that is triggered during a migration, when trying to convert the respe

```php
use verbb\hyper\events\ModifyMigrationLinkEvent;
use verbb\hyper\migrations\MigrateLinkit;
use verbb\hyper\migrations\MigrateLinkitContent;
use verbb\hyper\migrations\MigrateLinkitField;
use yii\base\Event;

Event::on(MigrateLinkit::class, MigrateLinkit::EVENT_MODIFY_LINK_TYPE, function(ModifyMigrationLinkEvent $event) {
Event::on(MigrateLinkitContent::class, MigrateLinkitContent::EVENT_MODIFY_LINK_TYPE, function(ModifyMigrationLinkEvent $event) {
$oldClass = $event->oldClass;
$newClass = $event->newClass;
// ...
});

Event::on(MigrateLinkitField::class, MigrateLinkitField::EVENT_MODIFY_LINK_TYPE, function(ModifyMigrationLinkEvent $event) {
$oldClass = $event->oldClass;
$newClass = $event->newClass;
// ...
});
```

Note that because migrations are split between the field and its content, you'll need to register your events for both respective classes.
6 changes: 6 additions & 0 deletions src/base/ElementLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ abstract public static function elementType(): string;
// Public Methods
// =========================================================================

public function count(): int|bool
{
// Override `Link::count` to not rely on a URL, as not all elements have a URL, but still have a value
return $this->linkValue ? true : false;
}

public function setAttributes($values, $safeOnly = true): void
{
// Protect against invalid values for some link types. This can happen due to migrations gone wrong
Expand Down
8 changes: 4 additions & 4 deletions src/links/Embed.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public static function fetchEmbedData(string $url): array
...$image,
]));

// Flag an invalid embed URL - still a response, but no code
// If no embed code, create it
if (!trim($data['code'])) {
throw new Exception('Embed URL invalid.');
$data['code'] = '<iframe src="' . $info->url . '"></iframe>';
}

return $data;
Expand All @@ -101,9 +101,9 @@ public static function fetchEmbedData(string $url): array
'feeds' => $info->feeds,
]));

// Flag an invalid embed URL - still a response, but no code
// If no embed code, create it
if (!trim($data['code'])) {
throw new Exception('Embed URL invalid.');
$data['code'] = '<iframe src="' . $info->url . '"></iframe>';
}

return $data;
Expand Down
5 changes: 5 additions & 0 deletions src/links/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ public static function elementType(): string
{
return UserElement::class;
}

public static function checkElementUri(): bool
{
return false;
}
}
22 changes: 22 additions & 0 deletions src/templates/field/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,25 @@
</ul>
{% endif %}
</div>

<hr>

{% if craft.app.db.isMysql %}
<a class="fieldtoggle" data-target="advanced">{{ 'Advanced' | t('hyper') }}</a>

<div id="advanced" class="hidden">
{{ forms.selectField({
label: 'Column Type' | t('hyper'),
instructions: 'The type of column this field should get in the database.' | t('hyper'),
id: 'column-type',
name: 'columnType',
options: [
{ value: 'text', label: 'text (~64KB)' },
{ value: 'mediumtext', label: 'mediumtext (~16MB)' },
{ value: 'longtext', label: 'longtext (~4GB)' },
],
value: field.columnType,
warning: (field.id ? "Changing this may result in data loss." | t('hyper')),
}) }}
</div>
{% endif %}

Large diffs are not rendered by default.

Binary file not shown.

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion src/web/assets/field/dist/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"src": "field/src/js/hyper.css"
},
"field/src/js/hyper.js": {
"file": "assets/hyper-bfcf4f03.js",
"file": "assets/hyper-a52b64cc.js",
"src": "field/src/js/hyper.js",
"isEntry": true,
"css": [
Expand Down
4 changes: 2 additions & 2 deletions src/web/assets/field/src/js/components/HyperInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export default {
// component once it's been moved. We need to do this for all link blocks in the field because of how
// the re-render process works (other blocks other than the one moved will update).
Object.values(this.$refs).forEach((linkComponent) => {
if (linkComponent[0]) {
if (linkComponent && linkComponent[0]) {
linkComponent[0].cacheHtml();
}
});
Expand All @@ -275,7 +275,7 @@ export default {
Object.values(this.$refs).forEach((linkComponent) => {
// Slight delay required to ensure that the DOM has caught up
setTimeout(() => {
if (linkComponent[0]) {
if (linkComponent && linkComponent[0]) {
linkComponent[0].updateHtml();
linkComponent[0].updateJs();
}
Expand Down
25 changes: 19 additions & 6 deletions src/web/assets/field/src/js/components/LinkBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ export default {
watch: {
'link.handle': function(newValue, oldValue) {
if (oldValue) {
// If we're switching link types, ensure that we cache the old field data before switching.
// Switching back would show us outdated content for fields (the original content on page load).
// Be sure to use the old cache key as well.
this.cacheHtml(`${this.link.id}-${oldValue}`);
}
// Because the link handle is changed in `created()` this alao fires immediately.
this.updateHtml();
this.updateJs();
Expand All @@ -151,13 +158,14 @@ export default {
// Some important type-casting, where things can get messed up where fields are stored in a non-numerical-keyed array,
// which isn't something I thought possible! This causes incorrect behvaiour when sending the values to element-slideout.
// Using `set()` or `setWith()` won't change the property type from Array to Object.
// Using `set()` or `setWith()` won't change the property type from Array to Object. This is only an issue for empty arrays.
// Because the link data is represented by JSON, it assumes things are an array, but they need to be an object.
// https://github.com/verbb/hyper/issues/97
if (this.link.fields && Array.isArray(this.link.fields)) {
if (this.link.fields === []) {
this.link.fields = {};
}
if (this.link.customAttributes && Array.isArray(this.link.customAttributes)) {
if (this.link.customAttributes === []) {
this.link.customAttributes = {};
}
},
Expand Down Expand Up @@ -207,7 +215,7 @@ export default {
this.fieldsHtml = this.getParsedLinkTypeHtml(this.hyperField.getCachedFieldHtml(this.cacheKey));
},
cacheHtml() {
cacheHtml(cacheKey = this.cacheKey) {
// Before dragging this block, save a copy of the current DOM to the cache. We ue this to restore back
// when finished moving. This is because Vue's rendering will not retain any edited non-Vue HTML.
if (this.$refs.fields) {
Expand Down Expand Up @@ -237,11 +245,16 @@ export default {
const $newHtml = $(this.linkType.html).find(`[data-layout-element="${fieldUid}"] .selectize`);
if ($newHtml.length) {
// IDs and names will include placholders for Vizy, but if in a Matrix/Super Table field, will contain those
// which can't be easily replaced like Vizy placeholders can. So be sure to swap them back to what they were
$newHtml.find('select').attr('id', $(element).find('select').attr('id'));
$newHtml.find('select').attr('name', $(element).find('select').attr('name'));
// Restore any selected elements
$newHtml.find('select').val($(element).find('select').val());
// Replace the HTML with the altered original template
element.innerHTML = $newHtml.htmlize();
element.outerHTML = $newHtml.htmlize();
}
}
});
Expand All @@ -268,7 +281,7 @@ export default {
fieldsHtml = fieldsHtml.replace(new RegExp(escapeRegExp(currentId), 'g'), idPlaceholder);
fieldsHtml = fieldsHtml.replace(new RegExp(escapeRegExp(currentName), 'g'), namePlaceholder);
this.hyperField.setCachedFieldHtml(this.cacheKey, fieldsHtml);
this.hyperField.setCachedFieldHtml(cacheKey, fieldsHtml);
}
},
Expand Down

0 comments on commit 42aa585

Please sign in to comment.