Commit Graph

322 Commits

Author SHA1 Message Date
Hannah Wolfe
829e8ed010 Expanded requires of lib/common i18n and events
- Having these as destructured from the same package is hindering refactoring now
- Events should really only ever be used server-side
- i18n should be a shared module for now so it can be used everywhere until we figure out something better
- Having them seperate also allows us to lint them properly
2021-05-03 17:14:52 +01:00
Kevin Ansfield
929cb0afe9
🐛 Fixed plaintext and excerpt fallbacks having incorrect URLs after domain change (#12811)
closes https://github.com/TryGhost/Team/issues/571

- `post.plaintext` values were being transformed with the markdown URL transformer but that wasn't picking up the link format used in our plaintext fields resulting in absolute URLs being stored in the database rather than `__GHOST_URL__` URLs
  - meant that if the `url` config is changed then plaintext and other calculated fields that used it would have URLs that referred to the old domain rather than the new one
  - re-saving the posts would have updated it but that's not feasible to do manually for large sites
- bumped `@tryghost/url-utils` to a version that has plaintext transform utils and updated the post model's transform map
2021-03-23 16:56:14 +00:00
Kevin Ansfield
426cbeec0f
🐛 Fixed performance regression introduced in 4.1.0 (#12807)
closes https://github.com/TryGhost/Ghost/issues/12791
closes https://github.com/TryGhost/Team/issues/566

https://github.com/TryGhost/Ghost/pull/12787 introduced a significant performance regression due to a misunderstanding of when Bookshelf calls `.format()` ([related upstream issue](https://github.com/bookshelf/bookshelf/issues/668)). We expected `.format()` to only be called on save but it's also called when Bookshelf performs fetching and eager loading which happens frequently. `.format()` can be a heavy method as it needs to parse and serialize html and markdown so it should be performed as infrequently as possible.

- override `sync()` in the base model so we can call our own `.formatOnWrite()` method to transform attributes on `update` and `insert` operations
  - this was the only feasible location in Bookshelf I could find that is low enough level to not require modifying model instance attributes
  - gives models the option to perform heavy transform operations only when writing to the database compared to the usual `.format()` method that is also called on fetch in many situations
2021-03-23 09:11:24 +00:00
Kevin Ansfield
afbe0c27fb
🐛 Fixed __GHOST_URL__ appearing in sitemaps (#12787)
closes https://github.com/TryGhost/Team/issues/552

Refactors URL transforms so they take place at the model layer rather than the API serializer layer. Continuation of the pattern created for the settings model in https://github.com/TryGhost/Ghost/pull/12738

- Added checks to all front-end tests to ensure output does not contain the magic replacement string
  - includes failing acceptance test for `__GHOST_URL__` appearing in sitemaps
- Removed all transform-ready URL transforms from API serializers
  - input serializers transform image urls relative->absolute to keep absolute-urls as the consistent "outside of the database" format
  - output serializers should not need to perform any URL transforms as that will be done at the model layer
- Added url transforms to models layer
  - removes knowledge from the API serializers which shouldn't need to know how data is stored internally in the database
  - makes absolute urls the consistent "outside of the database" URL format
  - adds transform step to the sitemap generator because the data used for that is fetched directly via knex which will not run through the bookshelf `parse()` methods
2021-03-18 17:16:37 +00:00
Kevin Ansfield
a6f5eb71be
🏗 Changed internal URL storage format to use __GHOST_URL__ (#12731)
closes https://github.com/TryGhost/Team/issues/467

- switches to storing "transform-ready" URLs in the database
- transform-ready URLs contain a `__GHOST_URL__` placeholder that corresponds to the configured url that gives a few benefits
  - much faster and less memory intensive output transformations through not needing to parse html or markdown - the transform can be achieved using a straightforward regex find+replace
  - ability to change to/from or rename subdirectory without any manual updates to the database
- modified existing 4.0 url-transformation migration rather than adding another one and repeating the transformation on posts rows
2021-03-05 13:54:01 +00:00
Hannah Wolfe
d51fcd072e Added new member limit & removed old
refs: https://github.com/TryGhost/Team/issues/510

- The current member limit was implemented as a member-specific concept
- The new limit service is much more generic, here we are swapping old for new
- The updated concept here is blocking all publishing, not just email sending, when a site is over its member limit
- To determine that we are publishing a post, we must be in the model layer. The code has been moved to the permissible function which makes sense as this is a permissions error that we are throwing
- I've left the extra check for email retries in, in case there is some loophole here (but we may wish to change it)
2021-03-04 18:16:34 +00:00
Kevin Ansfield
2c96df42ac
Added paywall card to mark end of free content preview (#12663)
closes https://github.com/TryGhost/Team/issues/466

- upgraded kg-default-cards to include paywall card
- extracted `htmlToPlaintext` from post model to shared util for re-use
- updated post-gating to set html+plaintext to the free preview if a paywall card has been used
  - re-generates plaintext from the truncated html using `htmlToPlaintext` util
- display free content in the `{{content}}` helper via the default CTA template
2021-02-17 23:00:26 +00:00
Fabien 'egg' O'Carroll
73f6fd8c51
Enabled Members for all sites (#12582)
no-issue

This removes all references to the members labs setting, any code that was run conditionally behind this flag now runs unconditionally. 

* Removed usage of Members labs flag
* Removed tests for Members disabled
* Added dynamic keypair generation for when setting is missing
2021-02-02 16:12:53 +00:00
Aileen Nowak
c9d1fa0b96 Updated links to ghost.org sites
no issue

Follow-up task of the updated Ghost Docs structure. Updated links reflecting the new structure to prevent unnecessary 404s and redirects.
2021-01-20 09:59:45 +13:00
Kevin Ansfield
7c57ffd6a6 Fixed posts without open rate being ordered in reverse
refs https://github.com/TryGhost/Ghost/issues/12420

- adds additional sorting by post creation date so that posts below those with an open rate appear in a more useful order
2020-12-04 13:12:14 +00:00
Kevin Ansfield
9ff7423b2b
Added email.open_rate order option to posts api (#12439)
refs https://github.com/TryGhost/Ghost/issues/12420

- updated `order` bookshelf plugin's `parseOrderOption()` method to return multiple order-related properties
  - `order` same as before, a key-value object of property-direction
  - `orderRaw` new property that is a raw SQL order string generated from `orderRawQuery()` method in models
  - `eagerLoad` new property that is an array of properties the `eagerLoad` plugin should use to join across
- updated `pagination.fetchAll()` to apply normal order + raw order if both are available and to handle eager loading / joins when `options.eagerLoad` is populated
- updated post model to include details for email relationship and to add `orderRawQuery()` that allows `email.open_rate` to be used as an order option
2020-12-03 20:13:37 +00:00
Fabien 'egg' O'Carroll
bfc152bede
Fixed handling of email_recipient_filter option (#12369)
no-issue

This logic would assume that the option was always passed at the point
of publishing the post, which is not the case for scheduled posts.

Instead of setting the property to 'none' when the option is not
present, we take the approach of ONLY setting the propery when
1. It is present and not 'none'
2. The post is being published or scheduled

This means that scheduled posts will have the property set correctly,
and any future publishing will leave the it in the original state
2020-11-17 11:00:03 +00:00
Fabien 'egg' O'Carroll
4604ba1587
Fixed backward compatibility for send_email_when_published (#12357)
no-issue

* Handled send_email_when_published in Posts API

This restores backwards compatibility of the Posts API allowing existing
clients to continue to use the `send_email_when_published` flag. This
change uses two edits, which is unfortunate. The reason being is that
this is an API compatibility issue, not a model issue, so we shouldn't
introduce code to the model layer to handle it. The visibility property
of the model is used to determine how to fall back, and because it can
be left out of the API request, and relies on a default in the settings,
we require that the model decide on the `visibility` before we run our
fallback logic (or we duplicate the `visibility` default at the cost of
maintenance in the future)

* Dropped send_email_when_published column from posts

Since this column is not used any more, we can drop it from the table.
We include an extra migration to repopulate the column in the event of
a rollback

* Updated importer to handle send_email_when_published

Because we currently export this value from Ghost, we should correctly
import it. This follows the same logic as the migrations for this value.

* Included send_email_when_published in API response

As our v3 API documentation includes `send_email_when_published` we must
retain backward compatibility by calculating the property.

* Fixed fields filter with send_email_when_published

* Added safety checks to frame properties

Some parts of the code pass a manually created "frame" which is missing
lots of properties, so we check for the existence of all of them before
using them.

* Fixed 3.1 migration to include columnDefinition

We require that migrations have all the information they need contained
within them as they run in an unknown state of the codebase, which could
be from the commit they are introduced, to any future commit. In this
case the column definition is removed from the schema in 3.38 and the
migration would fail when run in this version or later.
2020-11-11 13:03:41 +00:00
Fabien 'egg' O'Carroll
6140a98351
Updated newsletter functionality to use email_recipient_filter (#12343)
no-issue

* Used email_recipient_filter in MEGA

This officially decouples the newsletter recipients from the post
visibility allowing us to send emails to free members only

* Supported enum for send_email_when_published in model

This allows us to migrate from the previously used boolean to an enum
when we eventually rename the email_recipient_filter column to
send_email_when_published

* Updated the posts API to handle email_recipient_filter

We now no longer rely on the send_email_when_published property to send
newsletters, meaning we can remove the column and start cleaning up the
new columns name

* Handled draft status changes when emails not sent

We want to reset any concept of sending an email when a post is
transition to the draft status, if and only if, and email has not
already been sent. If an email has been sent, we should leave the email
related fields as they were.

* Removed send_email_when_published from add method

This is not supported at the model layer

* Removed email_recipient_filter from v2&Content API

This should not be exposed on previous api versions, or publicly

* Removed reference to send_email_when_published

This allows us to move completely to the email_recipient_filter
property, keeping the code clean and allowing us to delete the
send_email_when_published column in the database. We plan to then
migrate _back_ to the send_email_when_published name at both the
database and api level.
2020-11-06 17:32:23 +00:00
Fabien O'Carroll
3b0a84b33b Added email_recipient_filter column to posts table
no-issue

This column will allow us to decouple the recipients of newsletter from
the `visibility` of a post, allowing us to send emails to specifically
free members, or to send paid posts as newsletters to all members.
2020-11-04 16:29:54 +00:00
naz
a2bfef53de
🐛 Fixed post resource filtering by posts_meta table fields (#12307)
refs #11572

- Filtering by fields coming from posts_meta table did not work for post resources. This was due to lack of support for these types of operations on NQL layer. The approach taken here is using same way filtering was done for many:many relations and generates a `WHERE IN` filtering clause. In the future we could look into adding preloading of 1:1 relations which should allow getting rid of `WHERE IN` in favor of `JOIN` and filtering directly by field names. 
- Changed structure of `EXPANSIONS` filter configuration. Current approach was based on "bag of all the things". Such structure will become problematic as more fields are added. For example, adding all the fields from 1:1 relation posts:posts_meta might collide with any other relations that would have similar naming like meta_description from tags table (if it were was added).
- Bumped nql version to 0.5.0. This adds filtering support to 1:1 relations
- Added filter expansions which can be unique per model Previous approach with single global expansions lookup wasn't working in case different models would need to declare expansion for same field names. Having a `filterExpansion` method per model works in a similar convention other filter related model methods do (e.g. enforcedFilters, defaultFilters)
2020-11-02 12:53:57 +13:00
naz
bbcc83dadb
Added support for ordering Post API resources by fields coming form posts_meta table (#12226)
refs #11729

- When ordering is done by fields from a relation (like post's `meta_title` that comes form `posts_meta` table), Bookshelf does not include those relations in the original query which caused errors. To support this usecase added a mechanism to detect fields from a relation and load those relations into query. 
- Extended ordering to include table name in ordered field name.  The information about the table name is needed to avoid using `tableName` within pagination plugin and gives path to having other than original table ordering fields (e.g. order by posts_meta table fields)
- Added test case to check ordering on posts_meta fields
- Added support for "eager loading" relations. Allows to extend query builder object with joins to related tables,
which could be used in ordering (possibly in filtering later). Bookshelf does not support ordering/filtering by proprieties coming from relations, that's why this kind of plugin and query expansion is needed
- Added note about lack of support for child relations with same property names.
2020-09-24 13:32:40 +12:00
Daniel Lockyer
5b471e1bbe Extracted promise libs and history into @tryghost/promise
- deleted files under `core/server/lib/promise` and related test files
- added `@tryghost/promise` as a dependency
- fixed all local requires to point to the new package
2020-08-11 18:44:21 +01:00
Nazar Gargol
ced3e28d60 🐛 Fixed cache invalidation for published posts with no content
closes #12015
refs 95880dddeb

- The bug was caused by falsy plaintext field assignment to empty string `''` when the html content was `null`. Because of the `setEmptyValuesToNull` function (referenced commit), there is no sense to assign empty string value to plaintext property, because it would still end up being `null`
- The `''` -> `null` conversion was confusing the model layer to think that some fields were changed, where in reality none did. This in turn lead to a bug with falsy cache invalidation
2020-07-15 17:41:24 +12:00
Nazar Gargol
a75e1e27db 🐛 Fixed cache invalidation when editing post_meta fields
closes #12016

- The change detection didn't work when editing post_meta fileds because we only check current model's `_changed` fields when performing `wasChanged()` check
- A solution was adding change tracking of post_meta relation to currently edited post model and overloading `wasChanged` method to check these fields as well
2020-07-14 23:48:36 +12:00
Kevin Ansfield
4fb39f29cc Fixed population of image sizes when forcing re-render of posts
no issue

- fixed incorrect method name when calling
- fixed problem with setting post.mobiledoc to a promise rather than waiting for the size population to finish and setting it to a mobiledoc string
2020-06-18 14:02:53 +01:00
Kevin Ansfield
f27282bc3f
Added mobiledoc transform to populate missing image sizes on forced re-render (#11924)
no issue

- adds `populateImageSizes()` to our mobiledoc lib module
  - uses `image-size` lib to speed up reading of image dimensions
  - for local images, use storage adapter with same guards as used by `handle-image-sizes` middleware so that we don't insert srcsets for images that aren't transformable
  - for unsplash images, remove any width and crop params from the url so it points to the full-size image
- use `populateImageSizes(mobiledoc)` to modify post model's mobiledoc when re-rendering
2020-06-17 13:12:32 +01:00
Kevin Ansfield
008f86fc29 Added ?force_rerender=true param to posts edit endpoint
no issue

- there are various situations where we adapt/fix/improve our mobiledoc->html output over time but we didn't have a way of updating old content without manually editing the mobiledoc and saving, or running an expensive migration to re-render all old content
- this adds a `?force_rerender=true` query param to the `PUT .../admin/posts/:id/` endpoint that allows the `html` field to be re-generated without modifying the `mobiledoc` field contents
2020-06-12 18:05:57 +01:00
Kevin Ansfield
5d0d0b397e Fixed no-shadow linting warnings in models/post.js 2020-06-12 17:55:40 +01:00
Vikas Potluri
1bd8c18a16
Moved core/server/lib/url-utils to core/shared/url-utils (#11856)
* moved url-utils from server to shared
* updated imports of url-utils
2020-05-28 11:57:02 +01:00
Vikas Potluri
15d9a77092
Moved config from server to shared (#11850)
* moved `server/config` to `shared/config`
* updated config import paths in server to use shared
* updated config import paths in frontend to use shared
* updated config import paths in test to use shared
* updated config import paths in root to use shared
* trigger regression tests
* of course the rebase broke tests
2020-05-27 18:47:53 +01:00
Vikas Potluri
4ac88dce10
Refactored common lib import to use destructuring (#11835)
* refactored `core/frontend/apps` to destructure common imports
* refactored `core/frontend/services/{apps, redirects, routing}` to destructure common imports
* refactored `core/frontend/services/settings` to destructure common imports
* refactored remaining `core/frontend/services` to destructure common imports
* refactored `core/server/adapters` to destructure common imports
* refactored `core/server/data/{db, exporter, schema, validation}` to destructure common imports
* refactored `core/server/data/importer` to destructure common imports
* refactored `core/server/models/{base, plugins, relations}` to destructure common imports
* refactored remaining `core/server/models` to destructure common imports
* refactored `core/server/api/canary/utils/serializers/output` to destructure common imports
* refactored remaining `core/server/api/canary/utils` to destructure common imports
* refactored remaining `core/server/api/canary` to destructure common imports
* refactored `core/server/api/shared` to destructure common imports
* refactored `core/server/api/v2/utils` to destructure common imports
* refactored remaining `core/server/api/v2` to destructure common imports
* refactored `core/frontend/meta` to destructure common imports
* fixed some tests referencing `common.errors` instead of `@tryghost/errors`
   - Not all of them need to be updated; only updating the ones that are
causing failures
* fixed errors import being shadowed by local scope
2020-05-22 19:22:20 +01:00
Nazar Gargol
2d41e5cc88 🐛 Fixed permission for "Administrator" to be able to edit post visibility
closes #11825

- The initial implementation had a typo in a role name which didn't allow "Administrator" to edit post's "visibility" attribute
- Added unit tests to check administrator specific role and visibility attribute permission
2020-05-20 17:47:27 +12:00
Hannah Wolfe
22e13acd65 Updated var declarations to const/let and no lists
- All var declarations are now const or let as per ES6
- All comma-separated lists / chained declarations are now one declaration per line
- This is for clarity/readability but also made running the var-to-const/let switch smoother
- ESLint rules updated to match

How this was done:

- npm install -g jscodeshift
- git clone https://github.com/cpojer/js-codemod.git
- git clone git@github.com:TryGhost/Ghost.git shallow-ghost
- cd shallow-ghost
- jscodeshift -t ../js-codemod/transforms/unchain-variables.js . -v=2
- jscodeshift -t ../js-codemod/transforms/no-vars.js . -v=2
- yarn
- yarn test
- yarn lint / fix various lint errors (almost all indent) by opening files and saving in vscode
- grunt test-regression
- sorted!
2020-04-29 16:51:13 +01:00
Kevin Ansfield
b37ac8ef1f Switched to extracted @tryghost/mobiledoc-dom-renderer package
no issue

- moved `mobiledoc.renderers.mobiledocHtmlRenderer` to `mobiledoc.mobiledocHtmlRenderer` so that it's easier for the getter to access the parent objects getters
- removed all tests and dependencies that now live in @tryghost/mobiledoc-dom-renderer
  - kept the `mobiledocHtmlRenderer` test because that's testing that we've correctly wired up our cards and atoms and the output is what we expect
2020-04-08 18:27:12 +01:00
Kevin Ansfield
5b96c82627 Moved blank mobiledoc document out of mobiledocHtmlRenderer
no issue

- the blank document we use in Ghost is not specific to the html renderer
- renamed from `structure` to `document` to better represent its intent
- allows for easier extraction of `mobiledocHtmlRenderer`
2020-04-08 16:43:05 +01:00
Hannah Wolfe
8c1a0b8d0c Remove External Apps
- Apps are marked as removed in 3.0, never officially launched and have been deprecated for at least 2 years.
- We've slowly removed bits that got in our way or were insecure over time meaning they mostly didn't work
- This cleans up the remainder of the logic
- The tables should be cleaned up in a future major
2020-03-20 10:40:22 +00:00
Hannah Wolfe
bc7906a7b2 Revert "Remove Apps"
This reverts commit cbb59a57db.
2020-03-20 08:58:26 +00:00
Hannah Wolfe
cbb59a57db Remove Apps
- Apps are marked as removed in 3.0, never officially launched and have been deprecated for at least 2 years.
- We've slowly removed bits that got in our way or were insecure over time meaning they mostly didn't work
- This cleans up the remainder of the logic
- The tables should be cleaned up in a future major
2020-03-19 19:06:17 +00:00
Kevin Ansfield
4949ad9214 Renamed mobiledoc converters to renderers
no issue

- matches naming with `mobiledoc-kit` nomenclature
- better matches intent for future additions of mobiledoc rendering to email/plaintext/etc
2020-03-18 18:13:25 +00:00
Naz Gargol
c701293514
Optimized posts_meta table join when meta columns are not requested (#11300)
no issue

- This change speeds up qery execution ommiting a join with posts_meta
table when there is no need to fetch meta columns
2020-01-06 15:38:40 +01:00
Kevin Ansfield
0a20243540 Fixed knex connection pool errors when saving posts with sqlite
no issue

- sub query within the `Post.onSaving` method was not passing through the transaction options which was locking up sqlite
2019-11-15 15:11:55 +00:00
Kevin Ansfield
5fd2b7fed1 Added send_email_when_published query param to posts endpoint
no issue

- having a `send_email_when_published` property on the Post resource that only has an effect at certain times was confusing and was causing issues with clients that needed to know details of how that toggle worked
- makes `post.send_email_when_published` a fully read-only property in the API
- adds support for `?send_email_when_published=true` query param that can be passed in POST/PUT requests to the posts endpoint when scheduling or publishing a post - this is the only way to set `post.send_email_when_published` to `true`
- adds handling to ensure that `post.send_email_when_published` is always reset to `false` when reverting a post back to a draft _unless_ an email has already been sent
2019-11-14 17:29:03 +00:00
Rish
7e0da18f85 Fixed typo on email relation in model 2019-11-07 15:52:01 +07:00
Nazar Gargol
4e1caa8b08 Added email relation to post and allowed include for /posts endpoint 2019-11-07 11:47:15 +07:00
Fabien O'Carroll
c64be968c1 Updated default values for post model
no-issue
2019-11-06 17:32:14 +07:00
Kevin Ansfield
587bd8accb Merge branch 'master' into v3 2019-10-09 15:04:09 +01:00
Naz Gargol
daa77c5c00
Permission restrictions for post.visibility modifications (#11213)
no issue

- Limited posts visibility field permissions to Editor-Up + Admin Integrations
- We don't want contributors or other roles lower than Editor to be able to modify content gating attribute
2019-10-08 15:44:27 +02:00
Kevin Ansfield
6028fde666 Merge branch 'master' into v3 2019-10-08 13:58:08 +01:00
Kevin Ansfield
32f3f9d2c3 🐛 Fixed "unsaved changes" modal displaying when post has been saved
refs https://github.com/TryGhost/Ghost/issues/10477

The unsaved changes modal is displaying even when the post has been saved if images have been uploaded because the server is transforming absolute image urls to relative during input of the `mobiledoc` field but not transforming them back to absolute during output. The editor then thinks it's out of sync and shows the warning when trying to leave.

- `@tryghost/url-utils` has been updated with new methods for transforming URLs in mobiledoc content
- moves absolute->relative transformation from the API input serializers into the Post model
- transforms URLs in more fields for a more comprehensive transformation and fewer issues when re-configuring a site's domain
  - previously there could be problems with internal links between posts not being transformed so you could change the url config to newdomain.com but links in post content would still be pointing to olddomain.com
- updates the API post output serializers to transform all modified fields
- drops the `?absolute_urls=true` param switch from the `canary` API post output serializer so that all URLs are output as absolute
  - we're transforming more urls to relative when saving so this is necessary to ensure the unsaved changes modal is not triggered
  - the query param isn't documented and will disappear in v3
2019-10-07 22:59:19 +01:00
Naz Gargol
e214838039
Improve visibility's default handling (#11183)
no issue

- Moved default_content_visibility out of labs as we should be extra careful with what is exposed in the labs + it doesn't really belong there.
2019-10-02 11:08:10 +02:00
Naz Gargol
80f7e0b19e
Added default_content_visibility flag for content gating (#11163)
no issue

- Added 'labs' flag settings test
- Added test for default_content_visibility flag
- Default post's visibility takes into account values set in default_content_visibility setting
2019-09-26 15:40:24 +02:00
Naz Gargol
a2ebee3f4e
🔥 Removed 'staticPages' filter (#11135)
refs #5151
refs #10737

- Removed all uses/references to post's "staticPages" filter
- It was only a feature specific to API v0.1 which doesn't have to take space in the codebase anymore
2019-09-17 14:12:25 +02:00
Kevin Ansfield
e57e19ec31
🏗 Migrated posts.page column to posts.type (#11111)
refs https://github.com/TryGhost/Ghost/issues/10922

- adds migrations to...
  1. add `post.type` column
  2. populate `post.type` column based on `post.page` value
  3. drop `post.page` column
- updates all code paths to work with `post.type` in place of `post.page`
- adds `nql-map-key-values` transformer for mapping `page`->`type` in `filter` params when using the v2 API
- modifies importer to handle `post.page`->`post.type` transformation when importing older export files
2019-09-16 11:51:54 +01:00
Rishabh Garg
8ec12d9eee
🏗 Extracted post metadata in new post_meta table (#11102)
NOTE: The post metadata table split is purely an internal optimization for v3 and doesn't require or expect any external actions including related API usage in v3

We keep running into issues adding new fields to the post table because there are too many fields making the post table "too wide". We have also hit MySQL limitations in how many bytes can be in a row (64kb) with post table.

In v3, we decided to split the 8 post fields (meta, twitter and og) used for meta data into a posts_meta table as these 8 fields are all "problem" `varchar` fields and make sense logically grouped together. The API layer is unaffected by the split as input/output serializers ensure the data flow works the same way as it was in v2. Only thing to note is json export in v3 will have slightly different structure with posts meta fields as separate.

- Creates new post_meta schema/table with 8 fields (2 meta_* , 3 twitter_* and 3 og_*)
- Update relations between post and post_meta table
- Update input/output serializers to keep existing API behavior
- Avoids new entry in post_meta table for post where all meta fields are null
- Keeps the current fields API param behavior
- Handles migration of existing posts to new table structure
- Updates importer/exporter to work seamlessly with table changes
2019-09-16 14:15:55 +05:30