diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d5582db --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +# exclude dev directory from container +dev diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..6566ecb --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "root": true, + "parser": "@babel/eslint-parser", + "parserOptions": { + "requireConfigFile": false, + "babelOptions": { + "babelrc": false, + "configFile": false, + "presets": ["@babel/preset-env"] + } + }, + "extends": ["plugin:prettier/recommended"] +} diff --git a/.gitignore b/.gitignore index ce4844d..eb0fb2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *~ .\#* +node_modules +templates_c vendor -templates_c \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..c83793c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,11 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "semi": true, + "useTabs": false, + "parser": "babel", + "bracketSameLine": false +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..31662c0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +# syntax=docker/dockerfile:experimental + +# use wordpress image as the base image +FROM wordpress + +# install unzip for composer +RUN apt-get update && apt-get install apt-utils zip unzip -y + +# Install Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# copy all the files in this folder to plugins directory +COPY . /var/www/html/wp-content/plugins/termination-of-transfer + +# allow root user so composer can install dependencies without having root user error +RUN export COMPOSER_ALLOW_SUPERUSER=1; + +# cd to plugin directory AND install plugin dependencies +RUN cd /var/www/html/wp-content/plugins/termination-of-transfer && composer install diff --git a/assets/js/pdf.js b/assets/js/pdf.js new file mode 100644 index 0000000..323b34e --- /dev/null +++ b/assets/js/pdf.js @@ -0,0 +1,148 @@ +/* + Termination of Transfer - tool to help in returning authors rights. + Copyright (C) 2016 Creative Commons Corporation. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +//////////////////////////////////////////////////////////////////////////////// +// PDF Generation +// (browser-side data preparation and call to server) +//////////////////////////////////////////////////////////////////////////////// + +const TotPdf = {}; + +TotPdf.url = `${jQuery("script[src*='/termination-of-transfer/dist/js/pdf.js']") + .attr("src") + .replace(/dist\/js\/pdf\.js.*$/, "")}pdf-result.php`; + +TotPdf.appendProperty = (details, key, value) => { + const mapping = { key: key, value: value }; + details.push(mapping); +}; + +TotPdf.append203Windows = (details) => { + let notice = ""; + let termination = ""; + + if (TotValues.notice_begin != undefined) { + notice += `${TotValues.notice_begin}-${TotValues.notice_end}`; + termination += `${TotValues.term_begin}-${TotValues.term_end}`; + } + + if (TotValues.p_term_begin != undefined) { + if (notice != "") { + notice += " or "; + termination += " or "; + } + notice += `${TotValues.p_notice_begin}-${TotValues.p_notice_end}`; + termination += `${TotValues.p_term_begin}-${TotValues.p_term_end}`; + } + + TotPdf.appendProperty( + details, + '§ 203 notice window', + notice, + ); + TotPdf.appendProperty( + details, + '§ 203 termination window', + termination, + ); +}; + +TotPdf.append304Windows = (details) => { + TotPdf.appendProperty( + details, + '§ 304(c) notice window begins', + TotValues.notice_begin, + ); + TotPdf.appendProperty( + details, + '§ 304(c) notice window ends', + TotValues.notice_end, + ); + TotPdf.appendProperty( + details, + '§ 304(c) termination window begins', + TotValues.term_begin, + ); + TotPdf.appendProperty( + details, + '§ 304(c) termination window ends', + TotValues.term_end, + ); + if (TotValues.d_notice_begin != undefined) { + TotPdf.appendProperty( + details, + '§ 304(d) notice window begins', + TotValues.d_notice_begin, + ); + TotPdf.appendProperty( + details, + '§ 304(d) notice window ends', + TotValues.d_notice_end, + ); + TotPdf.appendProperty( + details, + '§ 304(d) termination window begins', + TotValues.d_term_begin, + ); + TotPdf.appendProperty( + details, + '§ 304(d) termination window ends', + TotValues.d_term_end, + ); + } +}; + +TotPdf.appendWindows = (details) => { + if (TotRules.is203()) { + TotPdf.append203Windows(details); + } else if (TotRules.is304()) { + TotPdf.append304Windows(details); + } +}; + +TotPdf.details = () => { + let details = []; + Object.getOwnPropertyNames(totVarsToTitles).forEach((key) => { + if (TotValues[key] != undefined && TotValues[key] != "") { + TotPdf.appendProperty(details, totVarsToTitles[key], TotValues[key]); + } + }); + TotPdf.appendWindows(details); + return details; +}; + +TotPdf.request = () => { + const data = { + report_timestamp: TotValues.current_date.getTime() / 1000, + flags: TotValues.flags.sort(), // Sorts inline & returns, so OK here + conclusion: TotValues.conclusion, + details: TotPdf.details(), + }; + const totform = document.createElement("FORM"); + totform.setAttribute("action", TotPdf.url); + totform.setAttribute("method", "post"); + totform.setAttribute("enctype", "multipart/form-data"); + totform.setAttribute("target", "_blank"); + const data_field = document.createElement("INPUT"); + data_field.setAttribute("type", "hidden"); + data_field.setAttribute("name", "data"); + data_field.setAttribute("value", JSON.stringify(data)); + totform.appendChild(data_field); + jQuery("body").append(totform); + totform.submit(); +}; diff --git a/assets/js/questions.js b/assets/js/questions.js new file mode 100644 index 0000000..041ca85 --- /dev/null +++ b/assets/js/questions.js @@ -0,0 +1,516 @@ +/* + Termination of Transfer - tool to help in returning authors rights. + Copyright (C) 2016 Creative Commons Corporation. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +//////////////////////////////////////////////////////////////////////////////// +// Presentation of questions, and main flow of control +// (This is slightly overloaded) +//////////////////////////////////////////////////////////////////////////////// + +const TotQuestions = {}; + +//////////////////////////////////////////////////////////////////////////////// +// Section One +//////////////////////////////////////////////////////////////////////////////// + +// When was the work created? + +TotQuestions.s1q1a = { + section: 1, + question: "When was the work created?", + explanation: + "The year in which a work was created can affect its copyright status and its treatment under U.S. copyright law. Most importantly, the tool is concerned with whether a worked was made before or after January 1, 1978, when the most recent overhaul of U.S. copyright went into effect.", + variable: "creation_year", + input: "year", + pre: () => { + TotNavigation.disablePrevious(); + TotNotifications.displayAnswersHint(); + }, + post: () => { + TotNotifications.removeAnswersHint(); + }, +}; + +// Has the work been published? + +TotQuestions.s1q1b = { + question: "Has the work been published?", + explanation: + 'Whether a work has been published can affect its copyright status and factor into the timing of a termination right. Note that "publication" has a particular meaning in U.S. copyright law, as discussed in our glossary.', + variable: "work_published", + input: "radio", + pre: () => { + TotNavigation.enablePrevious(); + }, +}; + +// When was the work first published? + +TotQuestions.s1q1bi = { + variable: "pub_year", + question: "When was the work first published?", + explanation: + 'When a work was published can affect its copyright status and factor into the timing of a termination right. Note that "publication" has a particular meaning in U.S. copyright law, as discussed in our glossary.', + input: "year", + validate: () => { + return ( + TotValidation.validDate() || + (parseInt(jQuery(".text-question").val()) < TotValues.creation_year + ? "The publication year cannot be earlier than the creation year." + : false) + ); + }, +}; + +// When was the work first published under the grant? + +TotQuestions.s1q1bii = { + section: 1, + question: "When was the work first published under the grant?", + explanation: + 'When a work was first published under the grant (which may be different than the the date the work was published for the first time) can factor into the timing of a termination right. Note that "publication" has a particular meaning in U.S. copyright law, as discussed in our glossary.', + variable: "grant_pub_year", + input: "year", + validate: () => { + let errors = TotValidation.validDate(); + if (errors == false) { + const year = parseInt(jQuery(".text-question").val()); + if (year < TotValues.creation_year) { + errors = + "Year of publication under grant cannot be earlier than year of creation."; + } else if (year < TotValues.pub_year) { + errors = + "Year of publication under grant cannot be earlier than year of initial publication."; + } /* else if (year < TotValues.k_year) { + errors = 'Year of publication under grant cannot be earlier than year of grant.'; + }*/ + } + return errors; + }, +}; + +// Works from 1989 and earlier usually display a copyright notice. Did the work have a copyright notice? + +TotQuestions.s1q1bi2 = { + question: + "Published works from 1989 and earlier usually display a copyright notice. Did the work have a copyright notice?", + explanation: + 'For U.S. works published in certain years, U.S. law required that they feature a "copyright notice" in order to receive federal copyright protection. Whether or not the published version featured a copyright notice can affect the copyright status of these works.', + variable: "copyright_notice", + input: "radio", + values: ["yes", "no", "maybe"], +}; + +// Has the work been registered with the United State Copyright Office? + +TotQuestions.s1q1c = { + question: + "Has the work been registered with the United State Copyright Office?", + explanation: + "Before 1989, registration was one of the ways authors could secure federal copyright in their work. Whether a work was registered can affect copyright status and the timing of termination right.", + variable: "work_registered", + input: "radio", + values: ["yes", "no"], //, "don't know"] GitHub issue #33 +}; + +// When was the work registered with the United States Copyright Office? + +TotQuestions.s1q1ci = { + question: + "When was the work registered with the United States Copyright Office?", + explanation: + "Before 1989, registration was one of the ways authors could secure federal copyright in their work. When a work was registered can affect copyright status and the timing of termination right.", + variable: "reg_year", + input: "year", +}; + +// What is the date of the agreement or transfer? ... + +TotQuestions.s1q1d = { + question: "What is the year of the agreement or transfer?", + explanation: + "When a transfer took place determines the particular set of termination rules that will be applicable. The timing of a transfer is also needed to know when a work's copyright transfer may be eligible for termination.", + variable: "k_year", + input: "year", + validate: () => { + const errors = TotValidation.validDate(); + if (errors == false) { + // Stash the user-entered agreement year + TotValues.user_inputted_k_year = parseInt(jQuery(".text-question").val()); + // If date is before the creation year, use the creation year instead + if (TotValues.user_inputted_k_year < TotValues.creation_year) { + jQuery(".text-question").val(TotValues.creation_year); + } + } + return errors; + }, + answerDisplayValue: () => { + return `Effective: ${TotValues.k_year}
User entered: ${TotValues.user_inputted_k_year}`; + }, +}; + +// Did the agreement or transfer include the right of publication? + +TotQuestions.s1q1f = { + // Last question in section 1, so set this if we've arrived via back button + section: 1, + question: "Did the agreement or transfer include the right of publication?", + explanation: + 'If a transfer from 1978 or later includes the right of publication, there is a different set of rules for determining when the transfer is eligible for termination.', + variable: "pub_right", + input: "radio", + values: ["yes", "no", "maybe"], +}; + +//////////////////////////////////////////////////////////////////////////////// +// Section Two +//////////////////////////////////////////////////////////////////////////////// + +// Is the agreement or transfer you want to terminate part of a last will... + +TotQuestions.s2q2a = { + // First question in section 2 + section: 2, + question: + 'Is the agreement or transfer in question part of a last will and testament?', + variable: "last_will", + input: "radio", +}; + +// Are any of the authors still alive? + +TotQuestions.s2q2bi = { + question: + 'Are any of the authors or artists still alive?', + explanation: + "The copyright term for many works is based on the life of the author.", + variable: "any_authors_alive", + input: "radio", +}; + +// What is the year the last surviving author died? + +TotQuestions.s2q2bi2 = { + question: + 'What is the year the last surviving author or artist died?', + explanation: + "The copyright term for many works is based on the life of the author.", + variable: "death", + input: "year", +}; + +// Was the work created within the scope of the author’s employment? + +TotQuestions.s2q2c = { + question: + 'Was the work created within the scope of the author’s employment?', + variable: "within_scope_of_employment", + input: "radio", +}; + +// Was there an express agreement between the author and the author's employer to not treat the work as a work made for hire? + +TotQuestions.s2q2ci = { + question: + 'Was there an express agreement the author and the author\'s employer to not treat the work as a work for hire?', + variable: "express_agreement", + input: "radio", +}; + +// Was the work created in response to a special order or commission + +TotQuestions.s2q2d = { + question: + 'Was the work created in response to a special order or commission by some other person or company?', + variable: "special_order", + input: "radio", +}; + +// Was there a signed written agreement regarding the special order... + +TotQuestions.s2q2di = { + question: + 'Was there a signed written agreement regarding the special order or commission which explicitly refers to the work as a work for hire?', + variable: "signed_written_agreement", + input: "radio", +}; + +// Was the work created for use as one of the following? ... + +TotQuestions.s2q2dia = { + question: + 'Was the work created for use as one of the following? —