</entry>
</map>
</option>
- <option name="mySupportsUserInfoFilter" value="true" />
</component>
</project>
\ No newline at end of file
</component>
<component name="ChangeListManager">
<list default="true" readonly="true" id="f146bc67-2578-4de3-9db2-94d2d43e9e83" name="Default" comment="">
- <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
+ <change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
</list>
<ignored path="fwstk.iws" />
<ignored path=".idea/workspace.xml" />
<file leaf-file-name="Word.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Word.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="739">
- <caret line="56" column="145" lean-forward="false" selection-start-line="56" selection-start-column="145" selection-end-line="56" selection-end-column="145" />
+ <state relative-caret-position="323">
+ <caret line="24" column="97" selection-start-line="24" selection-start-column="97" selection-end-line="24" selection-end-column="97" />
<folding>
<element signature="imports" expanded="true" />
</folding>
</provider>
</entry>
</file>
- <file leaf-file-name="fwstk.iml" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/fwstk.iml">
+ <file leaf-file-name="LayoutStripper.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/LayoutStripper.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="425">
- <caret line="25" column="43" lean-forward="false" selection-start-line="25" selection-start-column="43" selection-end-line="25" selection-end-column="43" />
- <folding />
+ <state relative-caret-position="850">
+ <caret line="64" column="23" selection-start-line="64" selection-start-column="23" selection-end-line="64" selection-end-column="23" />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="fwstk_jar.xml" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/.idea/artifacts/fwstk_jar.xml">
+ <file leaf-file-name="Main.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="187">
- <caret line="11" column="68" lean-forward="false" selection-start-line="11" selection-start-column="68" selection-end-line="11" selection-end-column="68" />
- <folding />
+ <state relative-caret-position="678">
+ <caret line="250" column="32" selection-start-line="250" selection-start-column="32" selection-end-line="250" selection-end-column="32" />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="commons_lang3_3_7.xml" pinned="false" current-in-tab="true">
- <entry file="file://$PROJECT_DIR$/.idea/libraries/commons_lang3_3_7.xml">
+ <file leaf-file-name="Page.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Page.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
+ <state relative-caret-position="364">
+ <caret line="88" column="39" selection-start-line="88" selection-start-column="39" selection-end-line="88" selection-end-column="39" />
+ <folding>
+ <element signature="e#2787#2795#0" expanded="true" />
+ </folding>
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="Letter.java" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Letter.java">
+ <file leaf-file-name="fwstk.iml" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/fwstk.iml">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="374">
- <caret line="25" column="47" lean-forward="false" selection-start-line="25" selection-start-column="47" selection-end-line="25" selection-end-column="47" />
- <folding>
- <element signature="e#729#730#0" expanded="true" />
- <element signature="e#752#753#0" expanded="true" />
- </folding>
+ <state relative-caret-position="425">
+ <caret line="25" column="43" selection-start-line="25" selection-start-column="43" selection-end-line="25" selection-end-column="43" />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="Separator.java" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Separator.java">
+ <file leaf-file-name="fwstk_jar.xml" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/.idea/artifacts/fwstk_jar.xml">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="102">
- <caret line="9" column="20" lean-forward="false" selection-start-line="9" selection-start-column="20" selection-end-line="9" selection-end-column="20" />
- <folding />
+ <state relative-caret-position="187">
+ <caret line="11" column="68" selection-start-line="11" selection-start-column="68" selection-end-line="11" selection-end-column="68" />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="Space.java" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Space.java">
+ <file leaf-file-name="commons_lang3_3_7.xml" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/.idea/libraries/commons_lang3_3_7.xml">
+ <provider selected="true" editor-type-id="text-editor" />
+ </entry>
+ </file>
+ <file leaf-file-name="CustomStripper.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/CustomStripper.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="153">
- <caret line="12" column="17" lean-forward="false" selection-start-line="12" selection-start-column="17" selection-end-line="12" selection-end-column="17" />
- <folding />
+ <state relative-caret-position="21">
+ <caret line="11" column="42" selection-start-line="11" selection-start-column="42" selection-end-line="11" selection-end-column="42" />
</state>
</provider>
</entry>
<file leaf-file-name="Line.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Line.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="535">
- <caret line="52" column="16" lean-forward="false" selection-start-line="52" selection-start-column="15" selection-end-line="52" selection-end-column="16" />
+ <state relative-caret-position="637">
+ <caret line="61" column="34" selection-start-line="61" selection-start-column="34" selection-end-line="61" selection-end-column="34" />
<folding>
<element signature="imports" expanded="true" />
</folding>
</provider>
</entry>
</file>
- <file leaf-file-name="StringUtil.java" pinned="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/cube/util/StringUtil.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="1071">
- <caret line="73" column="25" lean-forward="false" selection-start-line="73" selection-start-column="25" selection-end-line="73" selection-end-column="25" />
- <folding>
- <element signature="e#1761#1762#0" expanded="true" />
- <element signature="e#1785#1786#0" expanded="true" />
- </folding>
- </state>
- </provider>
- </entry>
- </file>
- <file leaf-file-name="Group.java" pinned="false" current-in-tab="false">
+ <file leaf-file-name="Group.java" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Group.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="515">
- <caret line="138" column="56" lean-forward="false" selection-start-line="138" selection-start-column="56" selection-end-line="139" selection-end-column="56" />
- <folding />
+ <caret line="41" column="97" selection-start-line="41" selection-start-column="97" selection-end-line="41" selection-end-column="97" />
</state>
</provider>
</entry>
<entry key="H:/Phonegap/Projects/com/promotal/catalogues/platforms/android" value="5864669409639" />
</map>
</option>
- <option name="externalProjectsViewState">
- <projects_view />
- </option>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Letter.java" />
<option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Separator.java" />
<option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Space.java" />
- <option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Group.java" />
- <option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Word.java" />
<option value="$PROJECT_DIR$/fwstk.iml" />
<option value="$PROJECT_DIR$/.idea/artifacts/fwstk_jar.xml" />
+ <option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Word.java" />
+ <option value="$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Group.java" />
</list>
</option>
</component>
<component name="PhpServers">
<servers />
</component>
- <component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" />
<component name="ProjectFrameBounds" extendedState="6">
- <option name="x" value="-10" />
- <option name="width" value="1938" />
- <option name="height" value="1056" />
+ <option name="x" value="-8" />
+ <option name="y" value="-8" />
+ <option name="width" value="1936" />
+ <option name="height" value="1176" />
</component>
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="1" id="Add" />
</component>
<component name="ProjectView">
- <navigator currentView="ProjectPane" proportions="" version="1">
- <flattenPackages />
- <showMembers />
- <showModules />
- <showLibraryContents />
- <hideEmptyPackages />
- <abbreviatePackageNames />
- <autoscrollToSource />
- <autoscrollFromSource />
- <sortByType />
- <manualOrder />
+ <navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
- <pane id="Scope" />
- <pane id="Scratches" />
<pane id="ProjectPane">
<subPane>
<expand>
</pane>
<pane id="AndroidView" />
<pane id="PackagesPane" />
+ <pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
- <property name="settings.editor.selected.configurable" value="configurable.group.language" />
- <property name="last_opened_file_path" value="$PROJECT_DIR$/lib/commons-lang3-3.7.jar!/" />
- <property name="aspect.path.notification.shown" value="true" />
+ <property name="AnalyzeApkAction.lastApkPath" value="$PROJECT_DIR$/out/artifacts/fwstk_jar" />
<property name="WebServerToolWindowFactoryState" value="true" />
+ <property name="WebServerToolWindowPanel.toolwindow.highlight.mappings" value="true" />
+ <property name="WebServerToolWindowPanel.toolwindow.highlight.symlinks" value="true" />
+ <property name="WebServerToolWindowPanel.toolwindow.show.date" value="false" />
+ <property name="WebServerToolWindowPanel.toolwindow.show.permissions" value="false" />
+ <property name="WebServerToolWindowPanel.toolwindow.show.size" value="false" />
+ <property name="aspect.path.notification.shown" value="true" />
<property name="js-jscs-nodeInterpreter" value="C:\Program Files\nodejs\node.exe" />
+ <property name="js.eslint.eslintPackage" value="" />
+ <property name="last_opened_file_path" value="$PROJECT_DIR$/lib/commons-lang3-3.7.jar!/" />
+ <property name="nodejs_interpreter_path" value="C:/Program Files/nodejs/node" />
<property name="project.structure.last.edited" value="Project" />
<property name="project.structure.proportion" value="0.15193799" />
<property name="project.structure.side.proportion" value="0.2" />
- <property name="nodejs_interpreter_path" value="C:/Program Files/nodejs/node" />
- <property name="js.eslint.eslintPackage" value="" />
- <property name="WebServerToolWindowPanel.toolwindow.show.size" value="false" />
- <property name="WebServerToolWindowPanel.toolwindow.show.date" value="false" />
- <property name="WebServerToolWindowPanel.toolwindow.show.permissions" value="false" />
- <property name="WebServerToolWindowPanel.toolwindow.highlight.symlinks" value="true" />
- <property name="WebServerToolWindowPanel.toolwindow.highlight.mappings" value="true" />
- <property name="AnalyzeApkAction.lastApkPath" value="$PROJECT_DIR$/out/artifacts/fwstk_jar" />
+ <property name="settings.editor.selected.configurable" value="configurable.group.language" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
</component>
<component name="RunManager" selected="Application.extract layout">
<configuration default="true" type="Applet" factoryName="Applet">
- <module />
- <option name="HTML_USED" value="false" />
- <option name="WIDTH" value="400" />
- <option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
</configuration>
- <configuration default="true" type="Application" factoryName="Application">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
- <option name="MAIN_CLASS_NAME" value="" />
- <option name="VM_PARAMETERS" value="" />
- <option name="PROGRAM_PARAMETERS" value="" />
- <option name="WORKING_DIRECTORY" value="" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="" />
- <envs />
- </configuration>
<configuration name="extract layout" type="Application" factoryName="Application">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.fluidbook.fwstk.Main" />
- <option name="VM_PARAMETERS" value="" />
+ <module name="fwstk" />
<option name="PROGRAM_PARAMETERS" value="--input C:\Users\Vincent\Desktop\original.pdf --layout C:\Users\Vincent\Desktop\loutres\p%d.fby --threads 1" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="fwstk" />
- <envs />
</configuration>
<configuration name="extract links" type="Application" factoryName="Application">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.fluidbook.fwstk.Main" />
- <option name="VM_PARAMETERS" value="" />
+ <module name="fwstk" />
<option name="PROGRAM_PARAMETERS" value="--input C:\Users\Vincent\Desktop\document_002.pdf --extractLinks C:\Users\Vincent\Desktop\document_002.txt" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="fwstk" />
- <envs />
</configuration>
<configuration name="extract texts" type="Application" factoryName="Application">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.fluidbook.fwstk.Main" />
- <option name="VM_PARAMETERS" value="" />
+ <module name="fwstk" />
<option name="PROGRAM_PARAMETERS" value="--input C:\Users\Vincent\Desktop\original.pdf --extractTextsMethod fluidbook --extractTexts C:\Users\Vincent\Desktop\loutres\%s%d.txt --threads 1" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="fwstk" />
- <envs />
</configuration>
<configuration default="true" type="ArquillianJUnit" factoryName="">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
- <module name="" />
<option name="arquillianRunConfiguration">
<value>
<option name="containerStateName" value="" />
<option name="VM_PARAMETERS" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" />
- <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
- <envs />
<patterns />
</configuration>
+ <configuration default="true" type="ArquillianTestNG" factoryName="">
+ <option name="arquillianRunConfiguration">
+ <value>
+ <option name="containerStateName" value="" />
+ </value>
+ </option>
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="SUITE_NAME" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="GROUP_NAME" />
+ <option name="TEST_OBJECT" value="CLASS" />
+ <option name="VM_PARAMETERS" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" />
+ <option name="OUTPUT_DIRECTORY" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="singleModule" />
+ </option>
+ <option name="USE_DEFAULT_REPORTERS" value="false" />
+ <option name="PROPERTIES_FILE" />
+ <properties />
+ <listeners />
+ </configuration>
<configuration default="true" type="GrailsRunConfigurationType" factoryName="Grails">
<setting name="vmparams" value="" />
<setting name="cmdLine" value="run-app" />
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
- <module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
- <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
- <envs />
<patterns />
</configuration>
<configuration default="true" type="JarApplication" factoryName="JAR Application">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="1.8" />
- <envs />
- </configuration>
- <configuration default="true" type="Remote" factoryName="Remote">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="false" />
- <option name="SHMEM_ADDRESS" value="javadebug" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5005" />
</configuration>
<configuration default="true" type="TestNG" factoryName="TestNG">
- <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
- <module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="SUITE_NAME" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<option name="OUTPUT_DIRECTORY" />
- <option name="ANNOTATION_TYPE" />
- <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<option name="USE_DEFAULT_REPORTERS" value="false" />
<option name="PROPERTIES_FILE" />
- <envs />
<properties />
<listeners />
</configuration>
- <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
- <module name="" />
- <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
- <option name="PROGRAM_PARAMETERS" />
- <predefined_log_file id="idea.log" enabled="true" />
- </configuration>
<configuration default="true" type="AndroidRunConfigurationType" factoryName="Android App">
<module name="" />
<option name="DEPLOY" value="true" />
</Profilers>
<method />
</configuration>
- <configuration default="true" type="ArquillianTestNG" factoryName="">
+ <configuration default="true" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
- <module name="" />
- <option name="arquillianRunConfiguration">
- <value>
- <option name="containerStateName" value="" />
- </value>
- </option>
+ <option name="MAIN_CLASS_NAME" value="" />
+ <option name="VM_PARAMETERS" value="" />
+ <option name="PROGRAM_PARAMETERS" value="" />
+ <option name="WORKING_DIRECTORY" value="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
- <option name="SUITE_NAME" />
- <option name="PACKAGE_NAME" />
- <option name="MAIN_CLASS_NAME" />
- <option name="METHOD_NAME" />
- <option name="GROUP_NAME" />
- <option name="TEST_OBJECT" value="CLASS" />
- <option name="VM_PARAMETERS" />
- <option name="PARAMETERS" />
- <option name="WORKING_DIRECTORY" />
- <option name="OUTPUT_DIRECTORY" />
- <option name="ANNOTATION_TYPE" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
- <option name="TEST_SEARCH_SCOPE">
- <value defaultName="singleModule" />
- </option>
- <option name="USE_DEFAULT_REPORTERS" value="false" />
- <option name="PROPERTIES_FILE" />
+ <module name="" />
<envs />
- <properties />
- <listeners />
- <method />
</configuration>
<configuration default="true" type="BashConfigurationType" factoryName="Bash">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ </configuration>
<configuration default="true" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="" />
<option name="initCode" value="" />
<method />
</configuration>
+ <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
+ <module name="" />
+ <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+ <option name="PROGRAM_PARAMETERS" />
+ <predefined_log_file id="idea.log" enabled="true" />
+ </configuration>
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
<command value="run" />
<scripts />
<envs />
</configuration>
<configuration default="true" type="tests" factoryName="Nosetests">
+ <module name="fwstk" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
- <envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
- <module name="fwstk" />
- <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_regexPattern" value="""" />
<option name="_new_additionalArguments" value="""" />
<option name="_new_target" value=""."" />
<option name="_new_targetType" value=""PATH"" />
</configuration>
<configuration default="true" type="tests" factoryName="Unittests">
+ <module name="fwstk" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
- <envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
- <module name="fwstk" />
- <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="""" />
<option name="_new_target" value=""."" />
<option name="_new_targetType" value=""PATH"" />
</configuration>
<configuration default="true" type="tests" factoryName="py.test">
+ <module name="fwstk" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
- <envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
- <module name="fwstk" />
- <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_keywords" value="""" />
<option name="_new_additionalArguments" value="""" />
<option name="_new_target" value=""."" />
<option name="_new_targetType" value=""PATH"" />
</configuration>
- <list size="3">
- <item index="0" class="java.lang.String" itemvalue="Application.extract links" />
- <item index="1" class="java.lang.String" itemvalue="Application.extract texts" />
- <item index="2" class="java.lang.String" itemvalue="Application.extract layout" />
+ <list>
+ <item itemvalue="Application.extract links" />
+ <item itemvalue="Application.extract texts" />
+ <item itemvalue="Application.extract layout" />
</list>
</component>
- <component name="ShelveChangesManager" show_recycled="false">
- <option name="remove_strategy" value="false" />
- </component>
<component name="SvnConfiguration" cleanupOnStartRun="true">
<configuration>C:\Users\Vincent\AppData\Roaming\Subversion</configuration>
<supportedVersion>125</supportedVersion>
<workItem from="1506413845063" duration="663000" />
<workItem from="1515419571657" duration="12314000" />
<workItem from="1515494590332" duration="6979000" />
+ <workItem from="1522337389921" duration="861000" />
</task>
<task id="LOCAL-00001" summary="wip #1111 @0.5">
<created>1487172253077</created>
<servers />
</component>
<component name="TimeTrackingManager">
- <option name="totallyTimeSpent" value="74425000" />
+ <option name="totallyTimeSpent" value="75286000" />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
</todo-panel>
</component>
<component name="ToolWindowManager">
- <frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
+ <frame x="-8" y="-8" width="1936" height="1176" extended-state="6" />
+ <editor active="true" />
<layout>
- <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
- <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
- <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32826087" sideWeight="0.48720682" order="10" side_tool="false" content_ui="tabs" />
- <window_info id="Palette	" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
- <window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
- <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
- <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.52132195" order="7" side_tool="true" content_ui="tabs" />
- <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
- <window_info id="File Transfer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
- <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
- <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.47867805" order="2" side_tool="false" content_ui="tabs" />
- <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
- <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
- <window_info id="Remote Host" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32995737" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
- <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
- <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.15938166" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
- <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
- <window_info id="SciView" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
- <window_info id="Structure" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="13" side_tool="false" content_ui="tabs" />
- <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
- <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
- <window_info id="Theme Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
- <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="true" content_ui="tabs" />
- <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
- <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
- <window_info id="Nl-Palette" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
- <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
- <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
- <window_info id="Properties" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
- <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
- <window_info id="Data View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="12" side_tool="false" content_ui="tabs" />
- <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
- <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32934782" sideWeight="0.49573562" order="1" side_tool="false" content_ui="tabs" />
+ <window_info anchor="right" id="Palette" order="4" />
+ <window_info anchor="bottom" id="TODO" order="6" weight="0.32934782" />
+ <window_info id="Palette	" order="1" />
+ <window_info id="Image Layers" order="2" />
+ <window_info anchor="right" id="Capture Analysis" order="5" />
+ <window_info anchor="bottom" id="Event Log" order="7" sideWeight="0.52132195" side_tool="true" weight="0.32934782" />
+ <window_info anchor="right" id="Maven Projects" order="6" />
+ <window_info anchor="bottom" id="Database Changes" show_stripe_button="false" />
+ <window_info anchor="bottom" id="Run" order="2" sideWeight="0.47867805" weight="0.32934782" />
+ <window_info anchor="bottom" id="Version Control" order="8" weight="0.32934782" />
+ <window_info anchor="bottom" id="Terminal" order="9" weight="0.32934782" />
+ <window_info id="Capture Tool" order="3" />
+ <window_info anchor="right" id="Remote Host" order="7" visible="true" weight="0.32995737" />
+ <window_info anchor="right" id="Designer" order="8" />
+ <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.1609808" />
+ <window_info anchor="right" id="Database" order="9" />
+ <window_info anchor="right" id="SciView" order="0" />
+ <window_info anchor="right" id="Structure" order="13" side_tool="true" weight="0.25" />
+ <window_info anchor="right" id="Ant Build" order="2" weight="0.25" />
+ <window_info id="UI Designer" order="4" />
+ <window_info anchor="right" id="Theme Preview" order="10" />
+ <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
+ <window_info id="Favorites" order="5" side_tool="true" />
+ <window_info anchor="bottom" id="Messages" order="10" sideWeight="0.48720682" weight="0.32826087" />
+ <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
+ <window_info anchor="right" id="Commander" internal_type="SLIDING" order="1" type="SLIDING" weight="0.4" />
+ <window_info anchor="bottom" id="Find" order="1" sideWeight="0.49573562" weight="0.32934782" />
+ <window_info id="Nl-Palette" order="6" />
+ <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
+ <window_info anchor="right" id="Properties" order="11" />
+ <window_info anchor="bottom" id="Message" order="0" />
+ <window_info anchor="right" content_ui="combo" id="Hierarchy" order="3" weight="0.25" />
+ <window_info anchor="right" id="Data View" order="12" />
+ <window_info anchor="bottom" id="File Transfer" order="11" weight="0.32934782" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
</breakpoints>
<option name="time" value="2" />
</breakpoint-manager>
- <watches-manager />
</component>
<component name="antWorkspaceConfiguration">
<option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/pdfbox-1.6.0/pdfbox/src/main/java/org/apache/pdfbox/util/ICU4JImpl.java" />
<entry file="file://$PROJECT_DIR$/../../../../Java/org/jdom/xpath/JaxenXPath.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
- <caret line="62" column="24" lean-forward="false" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
+ <caret line="62" column="24" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Link.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
- <caret line="6" column="13" lean-forward="false" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/pdfbox-1.6.0/pdfbox/src/main/java/org/apache/pdfbox/util/ICU4JImpl.java" />
<entry file="file://$PROJECT_DIR$/../../../../Java/org/jdom/xpath/JaxenXPath.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
- <caret line="62" column="24" lean-forward="false" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
+ <caret line="62" column="24" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Link.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
- <caret line="6" column="13" lean-forward="false" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/pdfbox-1.6.0/pdfbox/src/main/java/org/apache/pdfbox/util/ICU4JImpl.java" />
<entry file="file://$PROJECT_DIR$/../../../../Java/org/jdom/xpath/JaxenXPath.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
- <caret line="62" column="24" lean-forward="false" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
+ <caret line="62" column="24" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Link.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
- <caret line="6" column="13" lean-forward="false" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/pdfbox-1.6.0/pdfbox/src/main/java/org/apache/pdfbox/util/ICU4JImpl.java" />
<entry file="file://$PROJECT_DIR$/../../../../Java/org/jdom/xpath/JaxenXPath.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
- <caret line="62" column="24" lean-forward="false" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
+ <caret line="62" column="24" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/cube/util/StringUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
- <caret line="2" column="13" lean-forward="false" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
+ <caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/com/fluidbook/fwstk/TextsThread.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="214">
- <caret line="19" column="82" lean-forward="false" selection-start-line="19" selection-start-column="82" selection-end-line="19" selection-end-column="82" />
+ <caret line="19" column="82" selection-start-line="19" selection-start-column="82" selection-end-line="19" selection-end-column="82" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../../../../Java/org/jdom/xpath/JaxenXPath.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
- <caret line="62" column="24" lean-forward="false" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
+ <caret line="62" column="24" selection-start-line="62" selection-start-column="24" selection-end-line="62" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Link.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1275">
- <caret line="80" column="18" lean-forward="false" selection-start-line="80" selection-start-column="18" selection-end-line="80" selection-end-column="18" />
+ <caret line="80" column="18" selection-start-line="80" selection-start-column="18" selection-end-line="80" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="jar://$USER_HOME$/.ideaLibSources/pdfbox-1.8.13-sources.jar!/org/apache/pdfbox/util/PDFStreamEngine.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="59">
- <caret line="522" column="0" lean-forward="true" selection-start-line="315" selection-start-column="4" selection-end-line="522" selection-end-column="0" />
+ <caret line="522" lean-forward="true" selection-start-line="315" selection-start-column="4" selection-end-line="522" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.idea/libraries/pdfbox_1_8_13.xml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
- <caret line="10" column="12" lean-forward="false" selection-start-line="10" selection-start-column="12" selection-end-line="10" selection-end-column="12" />
+ <caret line="10" column="12" selection-start-line="10" selection-start-column="12" selection-end-line="10" selection-end-column="12" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.idea/libraries/fontbox_1_8_13.xml">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/project_resources/com/adobe/icc/cmyk/USWebCoatedSWOP.icc">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/out/artifacts/fwstk_jar/org/apache/pdfbox/resources/LayoutStripper.properties">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- </state>
- </provider>
+ <provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/geom/CubeMatrix.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="235">
- <caret line="33" column="17" lean-forward="false" selection-start-line="33" selection-start-column="17" selection-end-line="33" selection-end-column="17" />
+ <caret line="33" column="17" selection-start-line="33" selection-start-column="17" selection-end-line="33" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="jar://C:/Program Files/Java/jdk1.8.0_152/src.zip!/java/util/LinkedList.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197">
- <caret line="253" column="13" lean-forward="false" selection-start-line="253" selection-start-column="13" selection-end-line="253" selection-end-column="13" />
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/CustomStripper.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="68">
- <caret line="11" column="42" lean-forward="false" selection-start-line="11" selection-start-column="42" selection-end-line="11" selection-end-column="42" />
- <folding />
+ <caret line="253" column="13" selection-start-line="253" selection-start-column="13" selection-end-line="253" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="jar://$USER_HOME$/.ideaLibSources/pdfbox-1.8.13-sources.jar!/org/apache/pdfbox/util/PDFTextStripper.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="468" column="13" lean-forward="false" selection-start-line="468" selection-start-column="13" selection-end-line="468" selection-end-column="13" />
+ <state>
+ <caret line="468" column="13" selection-start-line="468" selection-start-column="13" selection-end-line="468" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="jar://C:/Program Files/Java/jdk1.8.0_152/src.zip!/java/util/ArrayList.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="7140">
- <caret line="460" column="19" lean-forward="false" selection-start-line="460" selection-start-column="19" selection-end-line="460" selection-end-column="19" />
- <folding />
+ <caret line="460" column="19" selection-start-line="460" selection-start-column="19" selection-end-line="460" selection-end-column="19" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/MANIFEST.MF">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102">
- <caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/LayoutStripper.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="586">
- <caret line="64" column="23" lean-forward="false" selection-start-line="64" selection-start-column="23" selection-end-line="64" selection-end-column="23" />
- <folding />
+ <caret line="6" selection-start-line="6" selection-end-line="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/LayoutElement.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="238">
- <caret line="18" column="25" lean-forward="false" selection-start-line="18" selection-start-column="25" selection-end-line="18" selection-end-column="25" />
- <folding />
+ <caret line="18" column="25" selection-start-line="18" selection-start-column="25" selection-end-line="18" selection-end-column="25" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/TextsThread.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="121">
- <caret line="183" column="52" lean-forward="false" selection-start-line="183" selection-start-column="52" selection-end-line="183" selection-end-column="52" />
+ <caret line="183" column="52" selection-start-line="183" selection-start-column="52" selection-end-line="183" selection-end-column="52" />
<folding>
- <element signature="e#6626#6627#0" expanded="false" />
- <element signature="e#6671#6672#0" expanded="false" />
+ <element signature="e#6626#6627#0" />
+ <element signature="e#6671#6672#0" />
</folding>
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="384">
- <caret line="250" column="32" lean-forward="false" selection-start-line="250" selection-start-column="32" selection-end-line="250" selection-end-column="32" />
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Page.java">
- <provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="274">
- <caret line="88" column="38" lean-forward="false" selection-start-line="88" selection-start-column="38" selection-end-line="88" selection-end-column="38" />
- <folding />
- </state>
- </provider>
- </entry>
<entry file="jar://C:/Program Files/Java/jdk1.8.0_152/src.zip!/java/lang/Object.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197">
- <caret line="147" column="19" lean-forward="false" selection-start-line="147" selection-start-column="19" selection-end-line="147" selection-end-column="19" />
+ <caret line="147" column="19" selection-start-line="147" selection-start-column="19" selection-end-line="147" selection-end-column="19" />
<folding>
- <element signature="e#5748#5749#0" expanded="false" />
- <element signature="e#5784#5785#0" expanded="false" />
+ <element signature="e#5748#5749#0" />
+ <element signature="e#5784#5785#0" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cube/util/StringUtil.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="1071">
- <caret line="73" column="25" lean-forward="false" selection-start-line="73" selection-start-column="25" selection-end-line="73" selection-end-column="25" />
+ <state relative-caret-position="1054">
+ <caret line="73" column="25" selection-start-line="73" selection-start-column="25" selection-end-line="73" selection-end-column="25" />
<folding>
<element signature="e#1761#1762#0" expanded="true" />
<element signature="e#1785#1786#0" expanded="true" />
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Letter.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="374">
- <caret line="25" column="47" lean-forward="false" selection-start-line="25" selection-start-column="47" selection-end-line="25" selection-end-column="47" />
+ <caret line="25" column="47" selection-start-line="25" selection-start-column="47" selection-end-line="25" selection-end-column="47" />
<folding>
<element signature="e#729#730#0" expanded="true" />
<element signature="e#752#753#0" expanded="true" />
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Separator.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102">
- <caret line="9" column="20" lean-forward="false" selection-start-line="9" selection-start-column="20" selection-end-line="9" selection-end-column="20" />
- <folding />
+ <caret line="9" column="20" selection-start-line="9" selection-start-column="20" selection-end-line="9" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Space.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
- <caret line="12" column="17" lean-forward="false" selection-start-line="12" selection-start-column="17" selection-end-line="12" selection-end-column="17" />
- <folding />
+ <caret line="12" column="17" selection-start-line="12" selection-start-column="17" selection-end-line="12" selection-end-column="17" />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Group.java">
+ <entry file="file://$PROJECT_DIR$/fwstk.iml">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="515">
- <caret line="138" column="56" lean-forward="false" selection-start-line="138" selection-start-column="56" selection-end-line="139" selection-end-column="56" />
- <folding />
+ <state relative-caret-position="425">
+ <caret line="25" column="43" selection-start-line="25" selection-start-column="43" selection-end-line="25" selection-end-column="43" />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Line.java">
+ <entry file="file://$PROJECT_DIR$/.idea/artifacts/fwstk_jar.xml">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="187">
+ <caret line="11" column="68" selection-start-line="11" selection-start-column="68" selection-end-line="11" selection-end-column="68" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/.idea/libraries/commons_lang3_3_7.xml">
+ <provider selected="true" editor-type-id="text-editor" />
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/CustomStripper.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="21">
+ <caret line="11" column="42" selection-start-line="11" selection-start-column="42" selection-end-line="11" selection-end-column="42" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/Main.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="678">
+ <caret line="250" column="32" selection-start-line="250" selection-start-column="32" selection-end-line="250" selection-end-column="32" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Page.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="535">
- <caret line="52" column="16" lean-forward="false" selection-start-line="52" selection-start-column="15" selection-end-line="52" selection-end-column="16" />
+ <state relative-caret-position="364">
+ <caret line="88" column="39" selection-start-line="88" selection-start-column="39" selection-end-line="88" selection-end-column="39" />
<folding>
- <element signature="imports" expanded="true" />
+ <element signature="e#2787#2795#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Word.java">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Line.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="739">
- <caret line="56" column="145" lean-forward="false" selection-start-line="56" selection-start-column="145" selection-end-line="56" selection-end-column="145" />
+ <state relative-caret-position="637">
+ <caret line="61" column="34" selection-start-line="61" selection-start-column="34" selection-end-line="61" selection-end-column="34" />
<folding>
<element signature="imports" expanded="true" />
</folding>
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/fwstk.iml">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Word.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="425">
- <caret line="25" column="43" lean-forward="false" selection-start-line="25" selection-start-column="43" selection-end-line="25" selection-end-column="43" />
- <folding />
+ <state relative-caret-position="323">
+ <caret line="24" column="97" selection-start-line="24" selection-start-column="97" selection-end-line="24" selection-end-column="97" />
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/.idea/artifacts/fwstk_jar.xml">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/LayoutStripper.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="187">
- <caret line="11" column="68" lean-forward="false" selection-start-line="11" selection-start-column="68" selection-end-line="11" selection-end-column="68" />
- <folding />
+ <state relative-caret-position="850">
+ <caret line="64" column="23" selection-start-line="64" selection-start-column="23" selection-end-line="64" selection-end-column="23" />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/.idea/libraries/commons_lang3_3_7.xml">
+ <entry file="file://$PROJECT_DIR$/src/com/fluidbook/fwstk/layout/Group.java">
<provider selected="true" editor-type-id="text-editor">
- <state relative-caret-position="0">
- <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
- <folding />
+ <state relative-caret-position="515">
+ <caret line="41" column="97" selection-start-line="41" selection-start-column="97" selection-end-line="41" selection-end-column="97" />
</state>
</provider>
</entry>
<?php
-class wsDAOBook extends commonDAO {
-
- public static $pagesOfBookCache = array();
-
- /**
- * wsDAOBook::singleton()
- *
- * @param mixed $r
- * @return
- */
- protected function singleton($r) {
- $book = new wsBook();
- $book->book_id = $r->book_id;
- $book->cid = $r->cid;
- $book->nom = $r->nom;
- $book->lang = $r->lang;
- $book->theme = $r->theme;
- $book->proprietaire = $r->proprietaire_nom;
- $book->proprietaire_id = $r->proprietaire_id;
- $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;
- $book->hash = $r->hash;
- $book->compteur_visites = $r->compteur_visites;
- $book->status = $r->status;
- $book->date_status = $r->date_status;
- $book->date = $r->date;
- $book->pages = array();
- $book->chapters = $r->chapters;
- $book->traductions = $r->traductions;
- $book->specialLinks = $r->specialLinks;
- $book->specialRulers = $r->specialRulers;
- $book->parametres = $r->parametres;
- $book->extras = $r->extras;
- $book->numerotation = $r->numerotation;
- $book->changedate = $r->changedate;
- $book->compiledate = $r->compiledate;
- $book->compile1date = $r->compile1date;
- $book->compilehtml5date = $r->compilehtml5date;
- $book->facturable = $r->facturable;
- $book->facturable_id = $r->facturable_id;
- $book->tache = $r->tache;
- if (isset($r->projet)) {
- $book->projet = $r->projet;
- }
- $book->version = $r->version;
- $book->composition_update = $r->composition_update;
- $book->dir_references = $r->dir_references;
- $book->dir_hosting = $r->dir_hosting;
- $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;
- $book->dir_phonegap_android = $r->dir_phonegap_android;
- $book->dir_external = $r->dir_external;
- $book->demo_counter = $r->demo_counter;
- $book->exportdatas = $r->exportdatas;
-
- return $book;
- }
-
- protected function cree($r) {
- $book = new wsBook();
- $book->book_id = 'new';
- $book->nom = '';
- $book->cid = null;
- $book->lang = 'fr';
- $book->theme = 1;
- $book->proprietaire = '';
- $book->proprietaire_id = 0;
- $book->hash = '';
- $book->compteur_visites = 20;
- $book->status = 0;
- $book->date_status = TIME;
- $book->date = TIME;
- $book->composition_update = TIME;
- $book->chapters = json_encode(array());
- $book->parametres = new wsBookParametres();
- $book->tache = 0;
- $book->pages = array();
- $book->version = 2;
- return $book;
- }
-
- protected function getNextId() {
- $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');
- if ($r->book_id < 10000) {
- return 10000;
- }
- return $r->book_id + 1;
- }
-
- public function saveExportDatas($book_id, $datas) {
- $c = $this->con->openCursor('books');
- $c->exportdatas = json_encode($datas);
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function addDemoCount($book_id) {
-
- $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');
- $m = 20;
- if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {
- $mail = new cubeMail();
- $mail->charset = 'UTF-8';
- $mail->from = 'contact@fluidbook.com';
- $mail->to = 'tech@fluidbook.com';
- $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';
- $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .
- 'Fluidbook # ' . $book_id . ' - ' . $r->nom;
- $mail->send();
- }
-
- $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');
- }
-
- public function selectByIds($book_ids = array(), $simple = false) {
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $ids = array();
- foreach ($book_ids as $bid) {
- fb($bid);
- if (intval($bid) > 0) {
- $ids[] = $bid;
- }
- }
-
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $ids) . ')';
- $books = $this->factory($this->con->select($sql));
- $res = array();
- foreach ($books as $book) {
- $res[$book->book_id] = $book;
- }
- return $res;
- }
-
- public function selectById($book_id = null, $simple = false) {
- if (is_null($book_id)) {
- return $this->cree();
- }
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
- $sql = 'SELECT * FROM ' . $table . ' WHERE book_id=\'' . $this->con->escape($book_id) . '\' LIMIT 1';
- $r = $this->con->select($sql);
- return $this->singleton($r);
- }
-
- public function selectByCid($cid = null, $simple = false) {
- if ($simple) {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $sql = 'SELECT * FROM ' . $table . ' WHERE cid LIKE BINARY \'' . $this->con->escape($cid) . '\' LIMIT 1';
- $r = $this->con->select($sql);
- return $this->singleton($r);
- }
-
- public function selectLuceneToDo() {
- $sql = 'SELECT * FROM books_vue WHERE lucene_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- public function selectLuceneTimeNotSet() {
- $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- /**
- * wsDAOBook::sauve()
- *
- * @param mixed $createur
- * @param mixed $data
- * @return
- */
- public function sauve($createur, $data) {
- $c = $this->con->openCursor('books');
- if (isset($data['nom'])) {
- $c->nom = $data['nom'];
- }
- if (isset($data['lang'])) {
- $c->lang = $data['lang'];
- }
- if (isset($data['theme'])) {
- $c->theme = $data['theme'];
- }
- if (isset($data['proprietaire'])) {
- $c->proprietaire = $data['proprietaire'];
- }
-
- if ($data['book_id'] == 'new' || $data['book_id'] == '') {
- $c->date = TIME;
- $c->hash = md5(rand(0, 123456789365469));
- $c->compteur_visites = 20;
- $c->parametres = serialize(new wsParametres());
- $c->changedate = TIME;
- $book_id = $c->book_id = $this->getNextId();
-
- $c->insert();
- } else {
- $c->changedate = TIME;
- $book_id = $data['book_id'];
- $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');
- }
-
- if (isset(self::$pagesOfBookCache[$book_id])) {
- unset(self::$pagesOfBookCache[$book_id]);
- }
-
- return $this->selectById($book_id);
- }
-
- public function duplicate($book_id, $createur, $nom, $pages = false) {
- $r = $this->con->select('SELECT * FROM books_vue WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $old_id = $book_id;
-
- $parametres = unserialize($r->parametres);
- $parametres->setParent($this);
- $parametres->title = $nom;
- $parametres->pdfReplace = '';
-
- $c = $this->con->openCursor('books');
- $c->proprietaire = $createur;
- $c->date = TIME;
- $c->hash = md5(rand(0, 1234567893));
- $c->cid = $this->generateCID();
- $c->compteur_visites = 20;
- $c->status = -1;
- $c->date_status = TIME;
- $c->lang = $r->lang;
- $c->parametres = serialize($parametres);
- $c->nom = $nom;
- $c->theme = $r->theme;
- $c->changedate = TIME;
- $c->compiledate = 0;
- $c->version = 2;
- $c->traductions = $r->traductions;
- $c->specialLinks = $r->specialLinks;
- $c->specialRulers = $r->specialRulers;
- $c->composition_update = TIME;
- $book_id = $c->book_id = $this->getNextId();
- if ($pages) {
- $c->numerotation = $r->numerotation;
- $c->chapters = $r->chapters;
- $this->con->execute('INSERT INTO book_pages SELECT ' . $book_id . ' AS book_id,book_page,document_id,document_page FROM book_pages WHERE book_id=' . $old_id);
- }
- $c->insert();
- $this->saveCompositionVersion($book_id);
-
- return $this->selectById($book_id);
- }
-
- public function creeEmpty($createur, $lang, $nom) {
- $c = $this->con->openCursor('books');
-
- $parametres = new wsBookParametres($this);
- $parametres->title = $nom;
-
- $c->proprietaire = $createur;
- $c->cid = $this->generateCID();
- $c->nom = $nom;
- $c->date = TIME;
- $c->hash = md5(rand(0, 1234567893));
- $c->compteur_visites = 20;
- $c->status = -1;
- $c->date_status = TIME;
- $c->parametres = serialize($parametres);
-
- $c->theme = 1;
- $c->lang = $lang;
- $c->changedate = TIME;
- $c->compiledate = 0;
- $c->version = 2;
- $c->composition_update = TIME;
- $book_id = $c->book_id = $this->getNextId();
- $c->insert();
- return $this->selectById($book_id);
- }
-
- public function supprime($book_id) {
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- return $this->con->execute('DELETE FROM books WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function count($limitedToUserRights = false) {
- $filters = $this->makeWhereFromFiltres();
- if ($filters == '1=1') {
- $table = 'books';
- } else {
- $table = 'books_vue';
- }
-
- $where = '(' . $filters . ')';
- $where .= $this->limitToUserRights($limitedToUserRights);
- $r = $this->con->select('SELECT COUNT(*) AS nb FROM ' . $table . ' WHERE ' . $where);
- return $r->nb;
- }
-
- public function getPagesOfBookAt($book_id, $time) {
- $r = $this->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY `update` ASC');
- if (!$r->count()) {
- return $this->getPagesOfBook($book_id);
- }
- if ($r->count() == 1) {
- $pages = unserialize($r->composition);
- if (null === $pages || !count($pages)) {
- return $this->getPagesOfBook($book_id);
- }
- return $pages;
- }
-
- $pages = null;
- while ($r->fetch()) {
- if ($r->update > $time) {
-
- if (is_null($pages)) {
- return $this->getPagesOfBook($book_id);
- }
- $res = unserialize($pages);
- if (null === $res || !count($res)) {
- return $this->getPagesOfBook($book_id);
- }
- return $res;
- }
- if (!count(unserialize($r->composition))) {
- continue;
- }
- $pages = $r->composition;
- }
-
- $res = unserialize($pages);
- if (null === $res || !count($res)) {
- return $this->getPagesOfBook($book_id);
- }
- return $res;
- }
-
- public function getDocumentsToUpdate($book_id) {
- $res = array();
- $r = $this->con->select('SELECT DISTINCT d.document_id FROM book_pages b,documents d WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' AND d.version=1 AND b.document_id=d.document_id');
- while ($r->fetch()) {
- $res[] = $r->document_id;
- }
- return $res;
- }
-
- public function getPagesOfBook($book_id, $conversion = true) {
- if (!isset(self::$pagesOfBookCache[$book_id])) {
- $pages = array();
-
- $sql = 'SELECT b.*,d.numberSections AS num,d.conversionInfos AS conversion,d.pages AS doc_pages,d.version AS version FROM book_pages b JOIN documents d ON d.document_id=b.document_id WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY book_page';
-
- $r = $this->con->select($sql);
- while ($r->fetch()) {
- $n = explode(',', $r->num);
-
- if (isset($n[$r->document_page - 1])) {
- $num = $n[$r->document_page - 1];
- } else {
- $num = '';
- }
- $pages[$r->book_page] = array('document_id' => $r->document_id,
- 'document_page' => $r->document_page,
- 'version' => $r->version,
- 'defaultNum' => $num,
- 'nb_pages' => $r->doc_pages
- );
-
- if ($conversion) {
- if ($r->conversion != '') {
- $c = unserialize($r->conversion);
- $c = $c->pages[$r->document_page];
- }
- $qp = array('resolution', 'method', 'quality', 'objects');
- foreach ($qp as $p) {
- if (isset($c) && isset($c->$p)) {
- $pages[$r->book_page][$p] = $c->$p;
- }
- }
- }
- }
-
- self::$pagesOfBookCache[$book_id] = $pages;
- }
- return self::$pagesOfBookCache[$book_id];
- }
-
- public function appendDocument($book_id, $document_id) {
- $r = $this->con->select('SELECT MAX(book_page) AS book_page FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- $lastPage = is_null($r->book_page) ? 0 : $r->book_page;
- $this->insertDocument($book_id, $lastPage, $document_id);
- }
-
- public function removePage($book_id, $book_page) {
- // Supprime la page
- $this->con->execute('DELETE FROM book_pages WHERE book_page=\'' . $this->con->escape($book_page) . '\' AND book_id=\'' . $this->con->escape($book_id) . '\'');
- // Décale les pages suivantes vers le haut
- $this->decalePages($book_id, $book_page, -1);
- }
-
- public function insertPage($book_id, $after_page, $document_id, $document_page) {
- // Décale les pages vers le bas
- $this->decalePages($book_id, $after_page, 1);
- // Insère la page
- $c = $this->con->openCursor('book_pages');
- $c->book_id = $book_id;
- $c->book_page = $after_page + 1;
- $c->document_id = $document_id;
- $c->document_page = $document_page;
- $c->insert();
- }
-
- public function insertDocument($book_id, $after_page, $document_id) {
- // Obtiens le book
- $book = $this->selectById($book_id);
- $num = explode(',', $book->numerotation);
- // Obtiens le nombre de pages
- $r = $this->con->select('SELECT pages,numberSections FROM documents WHERE document_id=\'' . $this->con->escape($document_id) . '\'');
- // Décale les pages vers le bas
- if ($after_page > 0) {
- $this->decalePages($book_id, $after_page, $r->pages);
- }
- // Insère les pages
- $c = $this->con->openCursor('book_pages');
- $c->book_id = $book_id;
- $c->document_id = $document_id;
- for ($i = 1; $i <= $r->pages; $i++) {
- $c->document_page = $i;
- $c->book_page = $after_page + $i;
- $c->insert();
- }
- // Mets à jour la liste des numéros des pages
- $before = array_slice($num, 0, $after_page);
- $after = array_slice($num, $after_page, count($num) - $after_page);
-
- $newnum = $r->numberSections;
- if (trim($newnum, ',') == '') {
- // If no number detected, we create a numeric list from 1
- $between = range(1, $r->pages);
- } else {
- // Else, we use numbers detected at conversion
- $between = explode(',', $r->numberSections);
- }
- $num = array_merge($before, $between, $after);
- // Mets à jour la numerotation de la publication
- $c = $this->con->openCursor('books');
- $c->numerotation = implode(',', $num);
- $c->composition_update = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $this->saveCompositionVersion($book_id);
- }
-
- protected function decalePages($book_id, $after_page, $decalage) {
- $decalage = ($decalage >= 0) ? '+' . $decalage : $decalage;
- $this->con->execute('UPDATE book_pages SET book_page=book_page' . $decalage . ' WHERE book_page>' . $this->con->escape($after_page) . ' AND book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function getListe($orderby = null, $sens = null, $limit = null, $limitedToUserRights = false) {
- if (!is_null($this->q)) {
- $where = '(';
- if ($this->search_id) {
- $where .= ' book_id=\'' . $this->con->escape($this->q) . '\' OR ';
- }
-
- if (!cubeMath::is_int($this->q)) {
- $where .= 'nom LIKE \'%' . $this->con->escape($this->q) . '%\'';
- $daoClient = new commonDAOClient($this->con);
- $where .= ' OR proprietaire_id IN(' . $daoClient->querySearchByName($this->q) . ') OR ';
- }
- $limit = null;
- $where .= '1=2)';
- } else {
- $where = '(' . $this->makeWhereFromFiltres() . ')';
- }
- $where .= $this->limitToUserRights($limitedToUserRights);
-
- $orderby = is_null($orderby) ? 'book_id' : $orderby;
- $sens = is_null($sens) ? 'DESC' : $sens;
- $limit = is_null($limit) ? '' : $this->con->limit($limit);
-
- $sql = 'SELECT * FROM books_vue WHERE ' . $where . ' ORDER BY ' . $orderby . ' ' . $sens . ' ' . $limit;
- $r = $this->con->select($sql);
- return $this->factory($r);
- }
-
- protected function limitToUserRights($utilisateur) {
- if ($utilisateur) {
- if (wsDroits::admin()) {
- return '';
- }
- return ' AND proprietaire IN (' . $utilisateur->ws_rights . ')';
- }
- return '';
- }
-
- protected function makeWhereFromFiltres() {
- if (!is_null($this->filtres)) {
- $w = array('1=1');
- if (commonFiltre::test('admin_book', $this->filtres)) {
- $w[] = 'super_admin IN (' . implode(',', array_keys($this->filtres['admin_book'])) . ')';
- }
- if (commonFiltre::test('status_book', $this->filtres)) {
- $w[] = 'status IN(' . implode(',', array_keys($this->filtres['status_book'])) . ')';
- }
- if (commonFiltre::test('revendeur_book', $this->filtres)) {
- $v = array_keys($this->filtres['revendeur_book']);
- $values = array();
- foreach ($v as $r) {
- $values[] = $this->con->escape($r);
- }
-
-
- $w[] = 'facturable IN(\'' . implode('\',\'', $values) . '\')';
- }
- return implode(' AND ', $w);
- } else {
- return '1=1';
- }
- }
-
- public function setChapters($book_id, $json) {
- $chapters = json_decode($json, true);
- $res = array();
-
- foreach ($chapters as $c) {
- $c['label'] = trim($c['label']);
- $n = (string)$c['page'];
- $c['label'] = trim(preg_replace('|\s+' . $n . '$|iu', '', $c['label']));
- $res[] = $c;
- }
-
- $json_chapters = json_encode($res);
-
- $c = $this->con->openCursor('books');
- $c->chapters = $json_chapters;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- if ($json_chapters && $json_chapters != '[]') {
- if (count($res) == 1) {
- if ($res[0]['label'] == '' && $res[0]['page'] == '') {
- return;
- }
- }
- $c = $this->con->openCursor('books_chapters_versions');
- $c->book_id = $book_id;
- $c->chapters = $json_chapters;
- $c->time = TIME;
- $c->insert();
- }
- }
-
- public function setSpecialLinksAndRulers($book_id, $links, $rulers) {
- $c1 = $this->con->openCursor('special_links_versions');
- $c = $this->con->openCursor('books');
-
- if (is_string($links)) {
- $links = json_encode(json_decode($links, false));
- }
- if (is_string($rulers)) {
- $rulers = json_encode(json_decode($rulers, false));
- }
-
- if (is_array($links)) {
- $links = json_encode($links);
- }
- if (is_array($rulers)) {
- $rulers = json_encode($rulers);
- }
-
-
- $c1->links = $c->specialLinks = $links;
- $c1->rulers = $c->specialRulers = $rulers;
- $c1->update = $c->changedate = TIME;
- $c1->book_id = $book_id;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- try {
- $c1->insert();
- } catch (Exception $e) {
- $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME);
- }
- }
-
- public function setTheme($book_id, $theme) {
- $c = $this->con->openCursor('books');
- $c->theme = $theme;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setStatus($book_id, $status) {
- $c = $this->con->openCursor('books');
- if ($status < 2) {
- $c->tache = 0;
- }
- $c->status = $status;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- return $this->selectById($book_id);
- }
-
- public function setChaptersFromOldFluidbook($book_id) {
- $book = $this->selectById($book_id);
- $n = explode(',', $book->numerotation);
-
- $xml = simplexml_load_file('https://ws.fluidbook.com/books/' . $book_id . '/data/links.xml');
- $res = array();
- $chapters = $xml->xpath('//chapters');
- foreach ($chapters as $ch) {
- $c = array();
- $c['label'] = (string)$ch->txt;
-
- $p = intval((string)$ch->page);
- if ($p <= 0) {
- continue;
- }
- $c['page'] = $n[$p];
- $c['level'] = intval((string)$ch->level);
- $res[] = $c;
- }
-
- $c = $this->con->openCursor('books');
- $c->chapters = json_encode($res);
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function saveCompositionVersion($book_id, $time = null) {
- $time = is_null($time) ? TIME : $time;
-
- $pages = $this->getPagesOfBook($book_id);
-
- $c = $this->con->openCursor('book_pages_versions');
- $c->update = $time;
- $c->book_id = $book_id;
- $c->composition = serialize($pages);
- $c->insert();
- }
-
- public function setLang($book_id, $base, $traductions) {
- // Cleanup user translations
- $traductions = json_decode($traductions, true);
- foreach ($traductions as $k => $v) {
- $traductions[$k] = $v;
- }
-
- $daoLang = new wsDAOLang($this->con);
- $lang = $daoLang->selectById($base);
- // Cleanup base translations
- $baseTraductions = $lang->traductions;
- foreach ($baseTraductions as $k => $v) {
- $baseTraductions[$k] = $v;
- }
- // Then compare them. If there is no differences, we don't save translations in the book
- if ($traductions == $baseTraductions) {
- $t = '';
- } else {
- $t = json_encode($traductions);
- }
-
- $c = $this->con->openCursor('books');
- $c->lang = $base;
- $c->traductions = $t;
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setSettings($book_id, $settings) {
- $book = $this->selectById($book_id);
- $parametres = $book->parametres;
- $new = $settings;
- foreach ($new as $k => $v) {
- if ($k == '_empty_') {
- continue;
- }
- $parametres->$k = $v;
- }
-
- $ip = array();
- if (isset($parametres->stats_exclude_ip) && trim($parametres->stats_exclude_ip) != '') {
- $list = $parametres->stats_exclude_ip;
- $list = str_replace("\r", "\n", $list);
- $e = explode("\n", $list);
- foreach ($e as $i) {
- $i = trim($i);
- if ($i == '') {
- continue;
- }
- $long = ip2long($i);
- if ($long !== false) {
- $ip[] = $long;
- }
- }
- }
-
- $file = '/home/stats/www/exclude/' . $book_id;
-
- if (count($ip)) {
- file_put_contents($file, implode(',', $ip));
- chmod($file, 0777);
- chown($file, 'stats');
- } else if (file_exists($file)) {
- unlink($file);
- }
-
- $c = $this->con->openCursor('books');
- $c->nom = $parametres->title;
- $c->parametres = serialize($parametres);
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setProprietaire($book_id, $proprietaire_id) {
- $c = $this->con->openCursor('books');
- $c->proprietaire = $proprietaire_id;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setTache($book_id, $tache) {
- $c = $this->con->openCursor('books');
- $c->tache = $tache;
- $c->status = 2;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setVersion($book_id, $version) {
- $c = $this->con->openCursor('books');
- $c->version = $version;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function touch($book_id) {
- $c = $this->con->openCursor('books');
- $c->changedate = TIME;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function touchCompile($book_id, $version = 'all') {
- $c = $this->con->openCursor('books');
- if ($version == '2') {
- $c->compiledate = TIME;
- } elseif ($version == '1') {
- $c->compile1date = TIME;
- } elseif ($version == 'html5') {
- $c->compilehtml5date = TIME;
- } else {
- $c->compiledate = TIME;
- $c->compile1date = TIME;
- $c->compilehtml5date = TIME;
- }
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function isUpToDate($book, $version) {
- $version = (string)$version;
- if ($version == '2') {
- if (!file_exists(WS_BOOKS . '/final/' . $book->book_id)) {
- return false;
- }
- if ($book->compiledate < $book->changedate) {
- return false;
- }
- } else if ($version == '1') {
- // V1
- if (!file_exists(WS_BOOKS . '/finalv1/' . $book->book_id . '/index.swf')) {
- return false;
- }
- if ($book->compile1date < $book->changedate) {
- return false;
- }
- } else if ($version == 'html5') {
- return false;
- // HTML5
- $checks = array($book->changedate, cubeFiles::filemtimeRecursive(WS_BOOKS . '/working/' . $book->book_id), cubeFiles::filemtimeRecursive(WS_COMPILE_ASSETS . '/_html5'), cubeFiles::filemtimeRecursive(ROOT . '/inc/ws/Util/html5'));
- foreach ($checks as $check) {
- if ($check > $book->compilehtml5date) {
- return false;
- }
- }
- }
- return true;
- }
-
- public function setComposition($book_id, $pages) {
- $numerotation = array();
- $nb_pages = 0;
- foreach ($pages as $p) {
- $numerotation[] = $p->virtual;
- $nb_pages++;
- }
-
- $book = $this->selectById($book_id);
- $parametres = $book->parametres;
- $parametres->pages = $nb_pages;
-
- $c = $this->con->openCursor('books');
- $c->parametres = serialize($parametres);
- $c->numerotation = implode(',', $numerotation);
- $c->changedate = TIME;
-
- // Check if composition need to be updated
- $r = $this->con->select('SELECT * FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- $tab = array();
- $now = array();
- $ref = array();
- while ($r->fetch()) {
- $ref[$r->book_page] = array((int)$r->document_id, (int)$r->document_page);
- }
- $i = 1;
- foreach ($pages as $p) {
- $now[$i] = array((int)$p->document_id, (int)$p->document_page);
- $i++;
- }
- if ($now != $ref) {
- $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
-
- $c1 = $this->con->openCursor('book_pages');
- $c1->book_id = $book_id;
- $i = 1;
- foreach ($pages as $p) {
- $c1->document_id = $p->document_id;
- $c1->document_page = $p->document_page;
- $c1->book_page = $i;
- $c1->insert();
- $i++;
- }
- $c->composition_update = TIME;
- $this->saveCompositionVersion($book_id);
- }
-
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function setInstallDir($book_id, $dir, $server) {
- $col = 'dir_' . $server;
-
- $c = $this->con->openCursor('books');
- $c->$col = $dir;
- $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
- }
-
- public function makeTextsIndexes($book, $pages, &$index, &$textes, $simple = false) {
- global $core;
- $prefix = '';
- if ($book->parametres->textExtraction == 'poppler') {
- $prefix = 'p';
- } else if ($book->parametres->textExtraction == 'fluidbook') {
- $prefix = 'f';
- }
-
- $dir = WS_BOOKS . '/index/' . $book->book_id;
- if ($book->parametres->ignoreSearchSeparators != '') {
- $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
- }
- if (!file_exists($dir)) {
- mkdir($dir, 0777, true);
- }
-
- if ($simple) {
- $ifilec = $dir . '/' . $prefix . 'sindex.json';
- } else {
- $ifilec = $dir . '/' . $prefix . 'index.json';
- }
- $tfilec = $dir . '/' . $prefix . 'textes.json';
-
- if (CubeIT_Util_Gzip::file_exists($ifilec) && CubeIT_Util_Gzip::file_exists($tfilec) && (min(CubeIT_Util_Gzip::filemtime($ifilec), CubeIT_Util_Gzip::filemtime($tfilec)) >= max($book->composition_update, filemtime(__FILE__), filemtime(WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar')))) {
- $index = CubeIT_Util_Gzip::file_get_contents($ifilec);
- $textes = CubeIT_Util_Gzip::file_get_contents($tfilec);
- return;
- }
-
- if ($book->parametres->ignoreSearchSeparators != "") {
- $docs = array();
- foreach ($pages as $p => $i) {
- $docs[] = $i['document_id'];
- }
- $docs = array_unique($docs);
-
- foreach ($docs as $doc) {
- $out = wsDocument::getDir($doc);
-
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $out . '/crop.pdf');
- $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
- $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
- $fwstk->setArg('--threads 1');
- $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
- $fwstk->execute();
- }
- }
-
- $index = array();
- $textes = array();
- foreach ($pages as $book_page => $infos) {
- $tfile = wsDocument::getDir($infos['document_id']) . $prefix . 'p' . $infos['document_page'] . '.txt';
- $ifile = wsDocument::getDir($infos['document_id']) . $prefix . 'i' . $infos['document_page'] . '.txt';
-
- if (!file_exists($tfile) || !file_exists($ifile)) {
- $daoDoc = new wsDAODocument($core->con);
- $out = wsDocument::getDir($infos['document_id']);
-
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $out . '/crop.pdf');
- $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
- $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
- if ($book->parametres->ignoreSearchSeparators != '') {
- $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
- }
- $fwstk->setArg('--threads 1');
- $fwstk->execute();
- }
-
- CubeIT_Util_Gzip::compressIfNotCompressed($tfile);
- CubeIT_Util_Gzip::compressIfNotCompressed($ifile);
- $text = CubeIT_Util_Gzip::file_get_contents($tfile);
- $ipage = CubeIT_Util_Gzip::file_get_contents($ifile);
-
- if ($simple) {
- $this->fillIndexWithWordsSimple($index, $book_page, $ipage);
- } else {
- $this->fillIndexWithWords($index, $book_page, $ipage);
- }
- $textes[$book_page] = $text;
- }
- ksort($index);
-
- $textes = json_encode($textes);
- $index = json_encode($index);
-
- CubeIT_Util_Gzip::file_put_contents($tfilec, $textes);
- CubeIT_Util_Gzip::file_put_contents($ifilec, $index);
- }
-
- public function makeHighlightIndex($book, $pages) {
- $jar = WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar';
-
- $daoDoc = new wsDAODocument($this->con);
- $res = new stdClass();
- foreach ($pages as $book_page => $infos) {
- $fby = wsDocument::getDir($infos['document_id']) . 'html/p' . $infos['document_page'] . '.fby';
- // Refresh highlight data if fby file doesn't exists or if fwstk has been updated
- $fbymtime = @filemtime($fby);
- if (!file_exists($fby) || filemtime($jar) > $fbymtime || filemtime(__FILE__) > $fbymtime) {
- $doc = $daoDoc->selectById($infos['document_id']);
- $doc->getHighlightTextsData();
- }
-
- if (file_exists($fby)) {
- $words = CubeIT_Util_Json::decode(file_get_contents($fby), CubeIT_Util_Json::TYPE_OBJECT);
-
- foreach ($words as $w) {
- $word = $w->word;
- $word = trim($word, "\0");
- if ($word == '') {
- continue;
- }
- unset($w->word);
- $w->page = $book_page;
- if (!isset($res->{$word})) {
- $res->{$word} = array();
- }
- $res->{$word}[] = $w;
- }
- }
- }
- return $res;
- }
-
- protected function _escapeIndex($str) {
- $todelete = array('\ufffd');
- foreach ($todelete as $d) {
- $str = str_replace($d, '', $str);
- }
- return $str;
- }
-
- protected function fillIndexWithWordsSimple(&$index, $page, $ipage) {
- $twords = explode("\n", trim($ipage));
-
- foreach ($twords as $woadata) {
- $w1 = explode(',', trim($woadata));
- if (count($w1) <= 1) {
- continue;
- }
- list($woa, $worddata) = $w1;
- $e = explode("\t", $worddata, 2);
- if (count($e) < 2) {
- continue;
- }
- list($total, $wordslist) = $e;
-
- if ($woa == '') {
- continue;
- }
-
- if (!isset($index[$woa])) {
- $index[$woa] = array('t' => 0, 'p' => array());
- }
- $index[$woa]['t'] += $total;
-
- $words = explode("\t", $wordslist);
- foreach ($words as $word) {
- list($wordwa, $count) = explode('$', $word, 2);
- if (!isset($index[$woa]['p'][$page])) {
- $index[$woa]['p'][$page] = 0;
- }
- $index[$woa]['p'][$page] += $count;
- }
- }
- }
-
- protected function fillIndexWithWords(&$index, $page, $ipage) {
- $twords = explode("\n", trim($ipage));
-
- foreach ($twords as $woadata) {
- $w1 = explode(',', trim($woadata));
- if (count($w1) <= 1) {
- continue;
- }
- list($woa, $worddata) = $w1;
- $e = explode("\t", $worddata, 2);
- if (count($e) < 2) {
- continue;
- }
- list($total, $wordslist) = $e;
-
- if ($woa == '') {
- continue;
- }
-
- if (!isset($index[$woa])) {
- $index[$woa] = array('t' => 0, 'w' => array());
- }
- $index[$woa]['t'] += $total;
-
- $words = explode("\t", $wordslist);
-
- foreach ($words as $word) {
- list($wordwa, $count) = explode('$', $word, 2);
- if (!isset($index[$woa]['w'][$wordwa])) {
- $index[$woa]['w'][$wordwa] = array('t' => 0, 'p' => array());
- }
- if (!isset($index[$woa]['w'][$wordwa]['p'][$page])) {
- $index[$woa]['w'][$wordwa]['p'][$page] = 0;
- }
- $index[$woa]['w'][$wordwa]['t'] += $count;
- $index[$woa]['w'][$wordwa]['p'][$page] += $count;
- }
- }
- }
-
- public function getNumerotationFromDocs($book_id) {
- $pages = $this->getPagesOfBook($book_id);
- }
-
- public function compileTemp($book_id, $version, $dir) {
- if ($version == 'ha' || $version == 'hi') {
- if ($version == 'ha') {
- $os = 'android';
- } elseif ($version == 'hi') {
- $os = 'ios';
- }
- $packager = new wsPackagerPhonegap($book_id, $dir, false, true, $os);
- $packager->makePackage(false);
- }
- }
-
- public function compile($book_id, $version = 'all', $complete = false, $force = false, $dev = false) {
- if (is_null($book_id) || !$book_id) {
- return;
- }
-
- $v1 = $v2 = $html5 = false;
-
- if ($version == 'all') {
- $v1 = $v2 = $html5 = true;
- } else if ($version == '1') {
- $v1 = true;
- } else if ($version == '2') {
- $v2 = true;
- } elseif ($version == 'html5') {
- $html5 = true;
- }
-
- $book = $this->selectById($book_id);
- $pages = $this->getPagesOfBook($book_id);
-
- if (!$force) {
-
- $v1 = $v1 && !$this->isUpToDate($book, 1);
- $v2 = $v2 && !$this->isUpToDate($book, 2);
- $html5 = $html5 && !$this->isUpToDate($book, 'html5');
- } else {
- $v1 = false;
- $html5 = true;
- $v2 = true;
- }
-
-
- $res = '';
- if ($v1) {
- fb(time(), 'Compile V1');
- $res .= $this->compile1($book_id, $book, $pages);
- $this->touchCompile($book_id, '1');
- }
- if ($v2) {
- fb(time(), 'Compile V2');
- $res .= $this->compile3($book_id, $complete, $book, $pages);
- $this->touchCompile($book_id, '2');
- }
- if ($html5) {
- fb(time(), 'Compile HTML5');
- $res .= $this->compileHTML5($book_id, $book, $dev);
- $this->touchCompile($book_id, 'html5');
- }
- if ($v1 || $v2) {
- fb(time(), 'Compile PDF & Widget');
- $this->compilePDF($book, $pages);
- $this->compileWidget($book, $pages);
- }
-
- fb(time(), 'End Compile');
- return $res;
- }
-
- public function compile1($book_id, $book, $pages) {
- $finalDir = WS_BOOKS . '/finalv1/' . $book_id . '/';
- $packager = new wsPackagerV1($book_id, $finalDir, false);
- $packager->makePackage(false);
- }
-
- public function compile3($book_id, $complete, $book, $pages) {
- $res = '';
-
- $compilerDir = WS_BOOKS . '/datasCompiler/' . $book_id . '/';
- $finalDir = WS_BOOKS . '/final/' . $book_id . '/';
-
- $vdir = new CubeIT_Files_VirtualDirectory($finalDir);
-
- $debug = false;
-
- $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
- $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
-
- $filesToCopy = array();
- $this->compileFlex($book_id, $complete, $compilerDir, $vdir, $filesToCopy, $book, $pages, $flex, $flexLight, $finalDir);
-
- $res .= $flex->compile() . "\n\n-------------------\n\n";
- $flexLight->addVariable('datasSize', filesize($compilerDir . '/FluidbookDatas.swf'));
- $res .= $flexLight->compile();
-
- $filesToCopy['data/fd.swf'] = $compilerDir . '/FluidbookDatas.swf';
- $filesToCopy['data/fdl.swf'] = $compilerDir . '/FluidbookDatasLight.swf';
-
- // Copy of files
- // Check if dest dir exists
-
- foreach ($filesToCopy as $local => $source) {
- $localPath = $local;
- $vdir->copy($source, $localPath);
- }
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
- $vdir->copyDirectory($workingDir . 'media', 'data');
- $vdir->sync(true);
-
- return $res;
- }
-
- public function copy($source, $dest) {
- copy($source, $dest);
- touch($dest, filemtime($source));
- }
-
- public static function getDocumentPage($book_id, $book_page) {
- global $core;
- $dao = new wsDAOBook($core->con);
- $pages = $dao->getPagesOfBook($book_id);
- return $pages[$book_page];
- }
-
- public function compileAir($book_id) {
- $compilerDir = WS_BOOKS . '/air/' . $book_id . '/compiler';
- $finalDir = WS_BOOKS . '/air/' . $book_id . '/';
-
- $book = $this->selectById($book_id);
- $pages = $this->getPagesOfBook($book_id);
-
- $src = AS3_FLUIDBOOK_SOURCES . '/_src/';
- $lib10 = AS3_FLUIDBOOK_SOURCES . '/lib10/';
- $libs = array(
- $src,
- $lib10,
- AS3_SOURCES,
- $src . 'lib/fluidbook3dLibrary.swc',
- $src . 'lib/mdm.swc',
- $lib10 . 'flash.swc',
- $lib10 . 'flex.swc',
- $lib10 . 'framework.swc',
- );
-
- wsSVN::updateToLastRevision();
-
- $swf = 'FluidbookAirProjector' . $book_id;
- $flex = new cubeFlexCompiler($swf, $compilerDir, 'com.fluidbook.player.AIRMain', $libs, '/usr/local/flex/bin/mxmlc', 'air', 45, 800, 600, true);
-
- $this->compileFlex($book_id, true, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flex);
- $res = $flex->compile();
-
- $air = new cubeAIRCompiler($swf . '.swf', '/usr/local/flex/bin', $compilerDir, '2.0');
- $air->setApplicationDatas('com.fluidbook' . $book_id, $book->parametres->title, $book->parametres->title, cubeText::str2URL($book->parametres->title), $book->lang);
- $air->setInitialWindow($book->parametres->title);
- $res .= $air->compile();
-
- return $res;
- }
-
- public function compileFlex($book_id, $complete, $compilerDir, $vdir, &$filesToCopy, $book, $pages, $flex, $flexLight) {
- /* @var $vdir CubeIT_Files_VirtualDirectory */
-
- cubePHP::neverStop();
- /* @var $flex cubeFlexCompiler */
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
-
- $res = '';
-
- $daoDoc = new wsDAODocument($this->con);
- $firstDoc = $daoDoc->selectById($pages[1]['document_id']);
- $size = $firstDoc->generalInfos['size'];
-
- $daoLang = new wsDAOLang($this->con);
- $lang = $daoLang->selectById($book->lang);
-
- $langs = $daoLang->selectAll();
-
- $daoTheme = new wsDAOTheme($this->con);
- $theme = $daoTheme->getThemeOfBook($book_id, true);
-
- $daoSignature = new wsDAOSignature($this->con);
- $signature = $daoSignature->selectById($book->parametres->signature);
-
- $exportSignature = array('main' => $signature->main,
- 'mainLink' => $signature->mainLink,
- 'partner' => $signature->partner,
- 'partnerLink' => $signature->partnerLink);
-
- $index = '';
- $textes = '';
- $pageLabels = array();
-
- $hash = $book_id;
- $hash .= 'kjgl!az4.';
- $hash .= count($pages);
- $hash .= round($size[0], 3);
-
- $hash = sha1($hash);
-
- $this->makeTextsIndexes($book, $pages, $index, $textes);
-
- $daoDoc->getLinksAndRulers($book_id, $links, $rulers);
-
- $audiodescription = array();
-
- $imagesassets = array();
- $id = 1;
- $ignoreLinks = array();
- foreach ($links as $id => $link) {
- $links[$id]['id'] = $id;
- $skipCopyAsset = false;
-
- if (isset($link['image']) && $link['image']) {
- $workingFile = $workingDir . '/' . $link['image'];
- $assetId = 'link_datas_i_' . md5($link['image']);
-
- if (isset($imagesassets[$assetId])) {
-
- } else {
- if (file_exists($workingFile)) {
- if ($link['page'] <= 1) {
- $flexLight->addBitmap($workingFile, $assetId);
- } else {
- $flex->addBitmap($workingFile, $assetId);
- }
- }
- $imagesassets[$assetId] = true;
- }
- }
-
- if ($link['type'] == 16 && $book->parametres->linkFilePrefix) {
- if (!CubeIT_Util_Url::isDistant($link['to'])) {
- $skipCopyAsset = true;
- $links[$id]['to'] = $book->parametres->linkFilePrefix . $link['to'];
- }
- }
-
- if ($link['type'] == 15) {
- if (isset($imagesassets[$id])) {
- continue;
- }
- if ($link['page'] <= 1) {
- $flexLight->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
- } else {
- $flex->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
- }
- $imagesassets[$id] = true;
- } else if (in_array($link['type'], array(4, 6, 7, 9, 16, 17, 25))) {
- if (!$skipCopyAsset) {
- $workingFile = $workingDir . '/' . $link['to'];
- if (file_exists($workingFile)) {
- $filesToCopy['data/' . $link['to']] = $workingFile;
- }
-
- if ($link['type'] == 4) {
- $poster = $link['to'];
- $e = explode('.', $poster);
- array_pop($e);
- array_push($e, 'jpg');
- $poster = implode('.', $e);
-
- $workingFile = $workingDir . '/' . $poster;
- if (file_exists($workingFile)) {
- $filesToCopy['data/' . $poster] = $workingFile;
- }
- }
- }
- }
-
- if ($link['type'] == 25) {
- $audiodescription[$link['page']] = $link['to'];
- $ignoreLinks[] = $id;
- }
- if ($link['type'] == 26) {
- $pageLabels[$link['to']] = $link['page'];
- $ignoreLinks[] = $id;
- }
- }
-
- foreach ($ignoreLinks as $ignoreLink) {
- unset($links[$ignoreLink]);
- }
- $links = array_values($links);
-
- $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives', 'ambientSound');
- foreach ($externalsOptions as $e) {
- if (isset($book->parametres->$e) && $book->parametres->$e != '') {
- $f = $workingDir . '/' . $book->parametres->$e;
- if (file_exists($f)) {
- $filesToCopy['data/' . $book->parametres->$e] = $f;
- }
- }
- }
-
- $flex->addVariable('audiodescription', $audiodescription, false, true, "JSONObject");
- $flex->addVariable('pagelabels', $pageLabels, false, true, 'JSONObject');
- $flex->addVariable('links', $links, false, true, 'JSONObject');
-
- $flex->addVariable('signature', $exportSignature, false, true, 'JSONObject');
- $flexLight->addVariable('datas', $book->parametres->toStandardObject(), false, true, 'JSONObject');
- $flexLight->addVariable('id', $book_id, false, true, 'uint');
- $flexLight->addVariable('cid', $book->cid, false, true, 'String');
-
- $traductions = (!count($book->traductions)) ? $lang->traductions : $book->traductions;
- $allTraductions = array();
- foreach ($langs as $l) {
- $allTraductions[$l->lang_id] = $l->traductions;
- }
-
- $flex->addVariable('traductions', $traductions, false, true, 'JSONObject', false);
- $flex->addVariable('allTraductions', $allTraductions, false, true, 'JSONObject');
- $flex->addVariable('chapters', $book->chapters, false, true, 'JSONObject');
- $flex->addVariable('extras', '<extras>' . $book->extras . '</extras>', false, true, 'XML');
- $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');
- $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');
- $flexLight->addVariable('pages', $book->parametres->pages);
- $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');
- $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');
- $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');
- $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);
- $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);
-
- $rasterized = array();
- $sizes = array();
-
- foreach ($pages as $i => $infos) {
- $base = wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'];
- $baset = wsDocument::getDir($infos['document_id']) . 't' . $infos['document_page'];
- $swffile = $base . '.swf';
- if (file_exists($swffile)) {
- clearstatcache(true, $swffile);
- $fsize = filesize($swffile);
- } else {
- $fsize = 0;
- }
-
- if ($complete) {
- $flex->addSWF($swffile, 'page' . $i);
- } else {
- $filesToCopy['data/p' . $i . '.swf'] = $swffile;
- if ($infos['method'] >= wsDocument::BARBARE_PNM) {
- $rasterized[$i] = true;
- $filesToCopy['data/t' . $i . '.swf'] = $baset . '.swf';
- } else {
- $rasterized[$i] = false;
- }
- }
-
- $thumb = false;
- if ($book->parametres->pdfThumbnails) {
- $thumb = wsPDFConvert::getThumbFromPDF($workingDir . '/' . $book->parametres->pdfThumbnails, $i);
- }
- if (!$thumb) {
- $thumb = $base . '.jpg';
- }
-
- if ($i == 1) {
- $flexLight->addBitmap($thumb, 'thumb1');
- } else {
- $flex->addBitmap($thumb, 'thumb' . $i);
- }
- $sizes[$i] = $fsize;
- }
-
- $flexLight->addVariable('rasterized', $rasterized, false, true, 'JSONObject');
- $flexLight->addVariable('sizes', $sizes, false, true, 'JSONObject');
-
- if ($book->parametres->soundTheme != '') {
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-drag.mp3', 'soundDragCorner');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-release.mp3', 'soundReleaseCorner');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-1.mp3', 'soundPage0');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-2.mp3', 'soundPage1');
- $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/cover-flip.mp3', 'soundCover0');
- }
- // Theme assets
- $themeRoot = WS_THEMES . '/' . $theme->theme_id . '/';
-
- if ($theme->parametres->backgroundImage != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->backgroundImage, 'background');
- }
- if ($theme->parametres->menuImage != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->menuImage, 'menu');
- }
- if ($theme->parametres->logoLoader != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->logoLoader, 'logoLoader');
- }
- if ($theme->parametres->topBar != '') {
- $flexLight->addBitmap($themeRoot . $theme->parametres->topBar, 'topBar');
- }
- if ($theme->parametres->logo != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->logo, 'logo');
- }
- if ($theme->parametres->afterSearch != '') {
- $flex->addBitmap($themeRoot . $theme->parametres->afterSearch, 'aftersearch');
- }
- if ($theme->parametres->favicon != '') {
- $filesToCopy['data/fluidbook.ico'] = $themeRoot . 'fluidbook.ico';
- }
-
- // Icons assets
- $iconsRoot = WS_ICONS . '/' . $theme->parametres->iconSet . '/';
- foreach (wsIcone::$files as $file) {
- $flex->addBitmap($iconsRoot . 'nav-' . $file . '.png', 'nav_' . $file);
- }
- // Share icons
- $iconsRoot = WS_ICONS . '/share/';
- foreach (wsIcone::$share as $file) {
- $flex->addBitmap($iconsRoot . 'share-' . $file . '.png', 'share_' . $file);
- }
-
- // Multilang
- if (trim($book->parametres->multilang) != '') {
- $m = str_replace("\r", "\n", trim($book->parametres->multilang));
- $langs = explode("\n", $m);
- $langNames = array();
- $countryNames = array();
- $iso = l10n::getISOcodes();
- $chars = '()';
- $vuFlags = array();
- foreach ($langs as $l) {
- list($mlang, $flag, $url) = explode(',', trim($l), 3);
- if (!isset($vuFlags[$flag])) {
- $flex->addBitmap(cubeMedia::getFlagFile($flag), 'flag_' . $flag);
- $vuFlags[$flag] = true;
- }
- $ll = explode('-', $mlang);
- $n = cubeText::ucfirst($iso[$ll[0]]);
- $langNames[$mlang] = $n;
- $cn = cubeCountry::getCountryName($flag, $mlang);
- $countryNames[$mlang . '_' . $flag] = $cn;
- $chars .= $n . $cn;
- }
-
- $chars = preg_split('/(?<!^)(?!$)/u', $chars);
- $chars = array_unique($chars);
-
- $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);
- $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');
- $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');
- }
- $flexLight->addVariable('lang', $book->lang);
-
- // Basket
- if ($book->parametres->basket) {
- $formats = array('jpg', 'png', 'jpeg');
- $referencesFile = self::getWorkingFile($book->parametres->basketReferences, $book_id, 'commerce');
-
- if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
- $ext = CubeIT_Files::getExtension($referencesFile);
- if ($ext == 'xml') {
- $xml = simplexml_load_file($referencesFile);
- $i = 0;
- $allref = array();
- foreach ($xml->item as $item) {
- $ref = (string)$item['reference'];
- if (isset($allref[$ref])) {
- continue;
- }
- $allref[$ref] = true;
- foreach ($formats as $f) {
- $refimage = $workingDir . 'commerce/' . $ref . '.' . $f;
- if (file_exists($refimage)) {
- $flex->addBitmap($refimage, "basket_image_" . $ref);
- break;
- }
- }
- $i++;
- }
- } elseif ($ext == 'xlsx') {
- $references = wsUtil::excelToArray($referencesFile);
- if ($book->parametres->customLinkClass == 'AtlanticDownloadLink') {
- $references = wsUtil::atlanticReferences($references, 'local/', null, array($vdir, 'copy'));
- }
- $flex->addVariable('basketReferences', $references, false, true, "OrderedObject");
- }
- }
- if (isset($xml)) {
- $flex->addVariable('basketReferences', cubeXML::condense($xml->asXML()), false, true, "String");
- }
- if ($book->parametres->basketPDFBackground != '') {
- $flex->addByteArray($workingDir . 'commerce/' . $book->parametres->basketPDFBackground, 'basket_pdf_background');
- }
- }
- // Fonts
- if ($theme->parametres->fontKit == 'auto') {
- if ($lang->font != 'system') {
- $font = FONT_PATH . '/' . $lang->font;
- $bfont = FONT_PATH . '/B' . $lang->font;
- if (!file_exists($bfont)) {
- $bfont = $font;
- }
-
- $flex->addFont($bfont, 'BoldFont', $lang->charset);
- $flex->addFont($font, 'GeneralFont', $lang->charset);
- }
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/FluidbookLoader.ttf', 'LoaderFont', 'Numerals');
- } else if ($theme->parametres->fontKit == 'vagrounded') {
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'BoldFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Light.otf', 'GeneralFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'LoaderFont', 'Numerals');
- } else if ($theme->parametres->fontKit == 'gill') {
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'BoldFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'GeneralFont', $lang->charset);
- $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
- $flexLight->addFont(FONT_PATH . '/gill/gill.ttf', 'LoaderFont', 'Numerals');
- }
-
- $flexLight->addVariable('checksum', $hash, false, true, 'String');
- }
-
-
- public static function getWorkingFile($path, $book_id, $dir = "") {
- if (CubeIT_Util_Url::isDistant($path) || (substr($path, 0, 1) == '/' && file_exists($path))) {
- return $path;
- }
-
- $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
- return $workingDir . trim($dir, '/') . '/' . $path;
- }
-
- public function compileWidget($book, $pages) {
- if (!$book->parametres->widget) {
- return;
- }
-
- global $core;
-
- $finalDir = WS_BOOKS . '/final/' . $book->book_id . '/widget/';
- $finalWidget = $finalDir . 'miniFluidbook.swf';
-
- if (!file_exists($finalDir)) {
- mkdir($finalDir, 0777, true);
- }
-
- if ($book->parametres->widgetCover) {
- $file = 'miniFluidbookCouv.swf';
- } else {
- $file = 'miniFluidbook.swf';
- }
- $mini = WS_COMPILE_ASSETS . '/_widget/' . $file;
-
- $from = max(1, $book->parametres->widgetStart);
- $to = min($book->parametres->widgetEnd, count($pages));
-
- $swfcombine = new cubeCommandLine('swfcombine');
- $swfcombine->setPath(CONVERTER_PATH);
- $swfcombine->setArg('merge');
- $swfcombine->setArg('stack1');
- $swfcombine->setArg('z');
- $swfcombine->setArg('o', $finalWidget);
- $swfcombine->setArg(null, $mini);
-
- $tempimage = array();
- $tempswf = array();
- $timg = array();
-
- for ($i = $from; $i <= $to; $i++) {
- $page = $pages[$i];
-
- $timg[$i] = $tempimage[$i] = cubeFiles::tempnam();
- $tempswf[$i] = cubeFiles::tempnam();
-
- $it = new imageTools();
- $image = wsDocument::getDir($page['document_id']) . '/html/t150-' . $page['document_page'] . '.jpg';
-
- try {
- $it->loadImage($image);
- $it->resize($book->parametres->widgetSize, 10000);
- $it->output('jpeg', $tempimage[$i], 100);
- } catch (Exception $e) {
- $tempimage[$i] = $image;
- }
- $jpg2swf = new cubeCommandLine('jpeg2swf');
- $jpg2swf->setEnv('PATH', '/bin:/usr/bin:/usr/local/bin');
- $jpg2swf->setArg('q', $book->parametres->widgetQuality);
- $jpg2swf->setArg('o', $tempswf[$i]);
- $jpg2swf->setArg(null, $tempimage[$i]);
- $jpg2swf->execute();
-
- $swfcombine->setArg(null, $tempswf[$i]);
- }
- $swfcombine->execute();
-
- foreach ($timg as $t) {
- if (file_exists($t)) {
- unlink($t);
- }
- }
- foreach ($tempswf as $t) {
- unlink($t);
- }
- }
-
- public function compileHTML5($book_id, $book, $dev = false) {
- $version = $book->parametres->mobileLVersion;
- if ($dev) {
- $version = 'dev';
- }
-
- $htmlCompiler = wsHTML5::compilerFactory($book_id, $version);
- $htmlCompiler->compile();
- }
-
- /* public function indexPDF($book, $pages) {
- $indexPath = WS_BOOKS . '/search/' . $book->book_id;
-
- Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
-
- if (file_exists($indexPath)) {
- files::deltree($indexPath);
- }
- $index = Zend_Search_Lucene::create($indexPath);
-
- foreach ($pages as $i => $infos) {
- $doc = new Zend_Search_Lucene_Document();
- $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i));
- $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'] . '.txt')));
- $index->addDocument($doc);
- }
-
- $c = $this->con->openCursor('books');
- $c->lucene_time = TIME;
- $c->update('WHERE book_id=' . $book->book_id);
- } */
-
- public function compilePDF($book, $pages) {
- if (substr($book->parametres->pdfName, 0, 4) == 'http') {
- return;
- }
- if (isset($book->parametres->pdfName) && $book->parametres->pdfName != '') {
- $pdfName = $book->parametres->pdfName;
- }
-
- $cacheDir = WS_BOOKS . '/pdf/' . $book->book_id;
- if (!file_exists($cacheDir)) {
- mkdir($cacheDir, 0777, true);
- }
-
- $normalPDF = $cacheDir . '/normal.pdf';
- $originalPDF = $cacheDir . '/original.pdf';
- $compressedPDF = $cacheDir . '/compressed.pdf';
-
- if (file_exists($originalPDF)) {
- $fmtime = filemtime($originalPDF);
- if ($fmtime >= $book->composition_update) {
- $invalid = false;
- foreach ($pages as $i => $infos) {
- $doc = wsDocument::getDir($infos['document_id']) . 'crop.pdf';
- if (filemtime($doc) > $fmtime) {
- $invalid = true;
- }
- }
- } else {
- $invalid = true;
- }
- } else {
- $invalid = true;
- }
-
-
- if ($invalid) {
- $pdfList = array();
- $pagesList = array();
- $nb_pages = array();
- $j = 0;
- $k = 0;
- $original = true;
-
- foreach ($pages as $i => $infos) {
- if (!isset($firstDoc)) {
- $firstDoc = $infos['document_id'];
- }
-
- $doc = wsDocument::getDir($infos['document_id']) . 'crop.pdf';
- if (!isset($pdfList[$doc])) {
- $pdfList[$doc] = $j;
- $nb_pages[$doc] = $infos['nb_pages'];
- $k = $j;
- $j++;
- } else {
- $k = $pdfList[$doc];
- }
- $pagesList[$i] = array($k, $infos['document_page']);
-
- if ($i != $infos['document_page'] || $infos['document_id'] != $firstDoc) {
- $original = false;
- }
- }
-
- if ($original) {
-
- $this->copy(wsDocument::getDir($firstDoc) . 'crop.pdf', $originalPDF);
- } else {
- $args = '';
- foreach ($pdfList as $doc => $index) {
- $lettre = cubeMath::toPDFLetter($index, true);
- $args .= $lettre . '=' . $doc . ' ';
- }
-
- $args .= ' cat ';
-
- $ranges = array();
- $currentRange = null;
-
- foreach ($pagesList as $p) {
- $lettre = cubeMath::toPDFLetter($p[0], true);
- $page = $p[1];
-
- // Initialise l'intervale
- if (is_null($currentRange)) {
- $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);
- continue;
- }
-
- // Poursuit le remplissage si la lettre est identique et si la page suivante est bien la page suivante dans le document
- if ($currentRange['lettre'] == $lettre && $currentRange['end'] + 1 == $page) {
- $currentRange['end'] = $page;
- continue;
- }
-
- // Ajoute l'intervale à la liste finale
- $ranges[] = $currentRange;
-
- // Réinitialise l'intervale suivant
- $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);
- }
-
- // Ajoute la dernière
- if (!is_null($currentRange)) {
- $ranges[] = $currentRange;
- }
- // Si le pdf final est constitué du document complet d'un document
- if (count($ranges) == 1 && $ranges[0]['start'] == 1) {
- $alldocs = array_keys($pdfList);
- $doc = array_pop($alldocs);
- if ($nb_pages[$doc] == $ranges[0]['end']) {
- $this->copy($doc, $originalPDF);
- return;
- }
- }
-
- foreach ($ranges as $range) {
- $args .= ' ' . $range['lettre'] . $range['start'];
- if ($range['start'] == $range['end']) {
- continue;
- }
- $args .= '-' . $range['end'];
- }
-
- $hash = sha1($args);
-
- $args .= ' output ' . $originalPDF;
-
- $cached = WS_BOOKS . '/pdf/' . $hash . '.pdf';
-
- if (file_exists($cached)) {
- $this->copy($cached, $originalPDF);
- } else {
- $pdftk = new cubeCommandLine('pdftk');
- $pdftk->setPath(CONVERTER_PATH);
- $pdftk->setManualArg($args);
- $pdftk->execute();
- $this->copy($normalPDF, $cached);
- }
- }
- }
-
-
- if ($book->parametres->pdfReplace) {
- $replace = WS_BOOKS . '/working/' . $book->book_id . '/' . $book->parametres->pdfReplace;
- if (file_exists($replace)) {
- if (!file_exists($normalPDF) || filemtime($normalPDF) < filemtime($replace) || filesize($normalPDF) != filesize($replace)) {
- $this->copy($replace, $normalPDF);
- }
- }
- } else {
- $this->copy($originalPDF, $normalPDF);
- }
- $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;
-
- if ($book->parametres->pdfCompress) {
- if (!file_exists($compressedPDF) || filemtime($compressedPDF) < filemtime($normalPDF)) {
- $gs = new cubeCommandLine('gs', null, true);
- $gs->setPath(CONVERTER_PATH);
- $gs->setEnv('GS_FONTPATH', '/home/ws/fonts');
- $gs->setArg('-dBATCH');
- $gs->setArg('-dNOPAUSE');
- $gs->setArg('-dNOPROMPT');
- $gs->setArg('-sOutputFile=' . $compressedPDF);
- $gs->setArg('-sDEVICE=pdfwrite');
- $gs->setArg('-dPDFSETTINGS=/ebook');
- $gs->setArg('-dColorImageResolution=72');
- $gs->setArg('-dAutoRotatePages=/None');
- $gs->setArg('-dColorConversionStrategy=/LeaveColorUnchanged');
- $gs->setArg(null, $normalPDF);
- $gs->execute();
- }
- copy($compressedPDF, $finalPDF);
- } else {
- copy($normalPDF, $finalPDF);
- }
- }
-
- public function generateCID() {
-
- do {
- $res = '';
- for ($i = 0; $i < 8; $i++) {
- $j = rand(0, 61);
- $res .= $this->base62($j);
- }
- $r = $this->con->select('SELECT book_id FROM books WHERE cid=\'' . $res . '\'');
- if ($r->count() == 0) {
- return $res;
- }
- } while (true);
- }
-
- protected function base62($val) {
- $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
- $base = strlen($chars);
- $str = '';
- do {
- $i = $val % $base;
- $str = $chars[$i] . $str;
- $val = ($val - $i) / $base;
- } while ($val > 0);
- return $str;
- }
+class wsDAOBook extends commonDAO
+{
+
+ public static $pagesOfBookCache = array();
+
+ /**
+ * wsDAOBook::singleton()
+ *
+ * @param mixed $r
+ * @return
+ */
+ protected function singleton($r)
+ {
+ $book = new wsBook();
+ $book->book_id = $r->book_id;
+ $book->cid = $r->cid;
+ $book->nom = $r->nom;
+ $book->lang = $r->lang;
+ $book->theme = $r->theme;
+ $book->proprietaire = $r->proprietaire_nom;
+ $book->proprietaire_id = $r->proprietaire_id;
+ $book->proprietaire_utilisateur = $r->proprietaire_utilisateur;
+ $book->hash = $r->hash;
+ $book->compteur_visites = $r->compteur_visites;
+ $book->status = $r->status;
+ $book->date_status = $r->date_status;
+ $book->date = $r->date;
+ $book->pages = array();
+ $book->chapters = $r->chapters;
+ $book->traductions = $r->traductions;
+ $book->specialLinks = $r->specialLinks;
+ $book->specialRulers = $r->specialRulers;
+ $book->parametres = $r->parametres;
+ $book->extras = $r->extras;
+ $book->numerotation = $r->numerotation;
+ $book->changedate = $r->changedate;
+ $book->compiledate = $r->compiledate;
+ $book->compile1date = $r->compile1date;
+ $book->compilehtml5date = $r->compilehtml5date;
+ $book->facturable = $r->facturable;
+ $book->facturable_id = $r->facturable_id;
+ $book->tache = $r->tache;
+ if (isset($r->projet)) {
+ $book->projet = $r->projet;
+ }
+ $book->version = $r->version;
+ $book->composition_update = $r->composition_update;
+ $book->dir_references = $r->dir_references;
+ $book->dir_hosting = $r->dir_hosting;
+ $book->dir_macbook_phonegap_ios = $r->dir_macbook_phonegap_ios;
+ $book->dir_phonegap_android = $r->dir_phonegap_android;
+ $book->dir_external = $r->dir_external;
+ $book->demo_counter = $r->demo_counter;
+ $book->exportdatas = $r->exportdatas;
+
+ return $book;
+ }
+
+ protected function cree($r)
+ {
+ $book = new wsBook();
+ $book->book_id = 'new';
+ $book->nom = '';
+ $book->cid = null;
+ $book->lang = 'fr';
+ $book->theme = 1;
+ $book->proprietaire = '';
+ $book->proprietaire_id = 0;
+ $book->hash = '';
+ $book->compteur_visites = 20;
+ $book->status = 0;
+ $book->date_status = TIME;
+ $book->date = TIME;
+ $book->composition_update = TIME;
+ $book->chapters = json_encode(array());
+ $book->parametres = new wsBookParametres();
+ $book->tache = 0;
+ $book->pages = array();
+ $book->version = 2;
+ return $book;
+ }
+
+ protected function getNextId()
+ {
+ $r = $this->con->select('SELECT MAX(book_id) AS book_id FROM books');
+ if ($r->book_id < 10000) {
+ return 10000;
+ }
+ return $r->book_id + 1;
+ }
+
+ public function saveExportDatas($book_id, $datas)
+ {
+ $c = $this->con->openCursor('books');
+ $c->exportdatas = json_encode($datas);
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function addDemoCount($book_id)
+ {
+
+ $r = $this->con->select('SELECT demo_counter,nom FROM books WHERE book_id=\'' . $book_id . '\'');
+ $m = 20;
+ if ($r->demo_counter > 0 && $r->demo_counter % $m == 0) {
+ $mail = new cubeMail();
+ $mail->charset = 'UTF-8';
+ $mail->from = 'contact@fluidbook.com';
+ $mail->to = 'tech@fluidbook.com';
+ $mail->subject = '[Fluidbook Workshop] Fluidbook consulté via l\'url publique';
+ $mail->body = 'Le fluidbook suivant a été consulté ' . $m . ' fois (et ' . $r->demo_counter . ' au total) via l\'url publique : ' . "\r\n" .
+ 'Fluidbook # ' . $book_id . ' - ' . $r->nom;
+ $mail->send();
+ }
+
+ $this->con->select('UPDATE books SET demo_counter=demo_counter+1 WHERE book_id=\'' . $book_id . '\'');
+ }
+
+ public function selectByIds($book_ids = array(), $simple = false)
+ {
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $ids = array();
+ foreach ($book_ids as $bid) {
+ fb($bid);
+ if (intval($bid) > 0) {
+ $ids[] = $bid;
+ }
+ }
+
+ $sql = 'SELECT * FROM ' . $table . ' WHERE book_id IN (' . implode(',', $ids) . ')';
+ $books = $this->factory($this->con->select($sql));
+ $res = array();
+ foreach ($books as $book) {
+ $res[$book->book_id] = $book;
+ }
+ return $res;
+ }
+
+ public function selectById($book_id = null, $simple = false)
+ {
+ if (is_null($book_id)) {
+ return $this->cree();
+ }
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+ $sql = 'SELECT * FROM ' . $table . ' WHERE book_id=\'' . $this->con->escape($book_id) . '\' LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->singleton($r);
+ }
+
+ public function selectByCid($cid = null, $simple = false)
+ {
+ if ($simple) {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $sql = 'SELECT * FROM ' . $table . ' WHERE cid LIKE BINARY \'' . $this->con->escape($cid) . '\' LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->singleton($r);
+ }
+
+ public function selectLuceneToDo()
+ {
+ $sql = 'SELECT * FROM books_vue WHERE lucene_time<composition_update AND version=2 ORDER BY book_id ASC LIMIT 1';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ public function selectLuceneTimeNotSet()
+ {
+ $sql = 'SELECT * FROM books_vue WHERE lucene_time=0 AND version=2';
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ /**
+ * wsDAOBook::sauve()
+ *
+ * @param mixed $createur
+ * @param mixed $data
+ * @return
+ */
+ public function sauve($createur, $data)
+ {
+ $c = $this->con->openCursor('books');
+ if (isset($data['nom'])) {
+ $c->nom = $data['nom'];
+ }
+ if (isset($data['lang'])) {
+ $c->lang = $data['lang'];
+ }
+ if (isset($data['theme'])) {
+ $c->theme = $data['theme'];
+ }
+ if (isset($data['proprietaire'])) {
+ $c->proprietaire = $data['proprietaire'];
+ }
+
+ if ($data['book_id'] == 'new' || $data['book_id'] == '') {
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 123456789365469));
+ $c->compteur_visites = 20;
+ $c->parametres = serialize(new wsParametres());
+ $c->changedate = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+
+ $c->insert();
+ } else {
+ $c->changedate = TIME;
+ $book_id = $data['book_id'];
+ $c->update('WHERE book_id=\'' . $this->con->escape($data['book_id']) . '\'');
+ }
+
+ if (isset(self::$pagesOfBookCache[$book_id])) {
+ unset(self::$pagesOfBookCache[$book_id]);
+ }
+
+ return $this->selectById($book_id);
+ }
+
+ public function duplicate($book_id, $createur, $nom, $pages = false)
+ {
+ $r = $this->con->select('SELECT * FROM books_vue WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $old_id = $book_id;
+
+ $parametres = unserialize($r->parametres);
+ $parametres->setParent($this);
+ $parametres->title = $nom;
+ $parametres->pdfReplace = '';
+
+ $c = $this->con->openCursor('books');
+ $c->proprietaire = $createur;
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 1234567893));
+ $c->cid = $this->generateCID();
+ $c->compteur_visites = 20;
+ $c->status = -1;
+ $c->date_status = TIME;
+ $c->lang = $r->lang;
+ $c->parametres = serialize($parametres);
+ $c->nom = $nom;
+ $c->theme = $r->theme;
+ $c->changedate = TIME;
+ $c->compiledate = 0;
+ $c->version = 2;
+ $c->traductions = $r->traductions;
+ $c->specialLinks = $r->specialLinks;
+ $c->specialRulers = $r->specialRulers;
+ $c->composition_update = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+ if ($pages) {
+ $c->numerotation = $r->numerotation;
+ $c->chapters = $r->chapters;
+ $this->con->execute('INSERT INTO book_pages SELECT ' . $book_id . ' AS book_id,book_page,document_id,document_page FROM book_pages WHERE book_id=' . $old_id);
+ }
+ $c->insert();
+ $this->saveCompositionVersion($book_id);
+
+ return $this->selectById($book_id);
+ }
+
+ public function creeEmpty($createur, $lang, $nom)
+ {
+ $c = $this->con->openCursor('books');
+
+ $parametres = new wsBookParametres($this);
+ $parametres->title = $nom;
+
+ $c->proprietaire = $createur;
+ $c->cid = $this->generateCID();
+ $c->nom = $nom;
+ $c->date = TIME;
+ $c->hash = md5(rand(0, 1234567893));
+ $c->compteur_visites = 20;
+ $c->status = -1;
+ $c->date_status = TIME;
+ $c->parametres = serialize($parametres);
+
+ $c->theme = 1;
+ $c->lang = $lang;
+ $c->changedate = TIME;
+ $c->compiledate = 0;
+ $c->version = 2;
+ $c->composition_update = TIME;
+ $book_id = $c->book_id = $this->getNextId();
+ $c->insert();
+ return $this->selectById($book_id);
+ }
+
+ public function supprime($book_id)
+ {
+ $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ return $this->con->execute('DELETE FROM books WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function count($limitedToUserRights = false)
+ {
+ $filters = $this->makeWhereFromFiltres();
+ if ($filters == '1=1') {
+ $table = 'books';
+ } else {
+ $table = 'books_vue';
+ }
+
+ $where = '(' . $filters . ')';
+ $where .= $this->limitToUserRights($limitedToUserRights);
+ $r = $this->con->select('SELECT COUNT(*) AS nb FROM ' . $table . ' WHERE ' . $where);
+ return $r->nb;
+ }
+
+ public function getPagesOfBookAt($book_id, $time)
+ {
+ $r = $this->con->select('SELECT * FROM book_pages_versions WHERE book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY `update` ASC');
+ if (!$r->count()) {
+ return $this->getPagesOfBook($book_id);
+ }
+ if ($r->count() == 1) {
+ $pages = unserialize($r->composition);
+ if (null === $pages || !count($pages)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $pages;
+ }
+
+ $pages = null;
+ while ($r->fetch()) {
+ if ($r->update > $time) {
+
+ if (is_null($pages)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ $res = unserialize($pages);
+ if (null === $res || !count($res)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $res;
+ }
+ if (!count(unserialize($r->composition))) {
+ continue;
+ }
+ $pages = $r->composition;
+ }
+
+ $res = unserialize($pages);
+ if (null === $res || !count($res)) {
+ return $this->getPagesOfBook($book_id);
+ }
+ return $res;
+ }
+
+ public function getDocumentsToUpdate($book_id)
+ {
+ $res = array();
+ $r = $this->con->select('SELECT DISTINCT d.document_id FROM book_pages b,documents d WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' AND d.version=1 AND b.document_id=d.document_id');
+ while ($r->fetch()) {
+ $res[] = $r->document_id;
+ }
+ return $res;
+ }
+
+ public function getPagesOfBook($book_id, $conversion = true)
+ {
+ if (!isset(self::$pagesOfBookCache[$book_id])) {
+ $pages = array();
+
+ $sql = 'SELECT b.*,d.numberSections AS num,d.conversionInfos AS conversion,d.pages AS doc_pages,d.version AS version FROM book_pages b JOIN documents d ON d.document_id=b.document_id WHERE b.book_id=\'' . $this->con->escape($book_id) . '\' ORDER BY book_page';
+
+ $r = $this->con->select($sql);
+ while ($r->fetch()) {
+ $n = explode(',', $r->num);
+
+ if (isset($n[$r->document_page - 1])) {
+ $num = $n[$r->document_page - 1];
+ } else {
+ $num = '';
+ }
+ $pages[$r->book_page] = array('document_id' => $r->document_id,
+ 'document_page' => $r->document_page,
+ 'version' => $r->version,
+ 'defaultNum' => $num,
+ 'nb_pages' => $r->doc_pages
+ );
+
+ if ($conversion) {
+ if ($r->conversion != '') {
+ $c = unserialize($r->conversion);
+ $c = $c->pages[$r->document_page];
+ }
+ $qp = array('resolution', 'method', 'quality', 'objects');
+ foreach ($qp as $p) {
+ if (isset($c) && isset($c->$p)) {
+ $pages[$r->book_page][$p] = $c->$p;
+ }
+ }
+ }
+ }
+
+ self::$pagesOfBookCache[$book_id] = $pages;
+ }
+ return self::$pagesOfBookCache[$book_id];
+ }
+
+ public function appendDocument($book_id, $document_id)
+ {
+ $r = $this->con->select('SELECT MAX(book_page) AS book_page FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ $lastPage = is_null($r->book_page) ? 0 : $r->book_page;
+ $this->insertDocument($book_id, $lastPage, $document_id);
+ }
+
+ public function removePage($book_id, $book_page)
+ {
+ // Supprime la page
+ $this->con->execute('DELETE FROM book_pages WHERE book_page=\'' . $this->con->escape($book_page) . '\' AND book_id=\'' . $this->con->escape($book_id) . '\'');
+ // Décale les pages suivantes vers le haut
+ $this->decalePages($book_id, $book_page, -1);
+ }
+
+ public function insertPage($book_id, $after_page, $document_id, $document_page)
+ {
+ // Décale les pages vers le bas
+ $this->decalePages($book_id, $after_page, 1);
+ // Insère la page
+ $c = $this->con->openCursor('book_pages');
+ $c->book_id = $book_id;
+ $c->book_page = $after_page + 1;
+ $c->document_id = $document_id;
+ $c->document_page = $document_page;
+ $c->insert();
+ }
+
+ public function insertDocument($book_id, $after_page, $document_id)
+ {
+ // Obtiens le book
+ $book = $this->selectById($book_id);
+ $num = explode(',', $book->numerotation);
+ // Obtiens le nombre de pages
+ $r = $this->con->select('SELECT pages,numberSections FROM documents WHERE document_id=\'' . $this->con->escape($document_id) . '\'');
+ // Décale les pages vers le bas
+ if ($after_page > 0) {
+ $this->decalePages($book_id, $after_page, $r->pages);
+ }
+ // Insère les pages
+ $c = $this->con->openCursor('book_pages');
+ $c->book_id = $book_id;
+ $c->document_id = $document_id;
+ for ($i = 1; $i <= $r->pages; $i++) {
+ $c->document_page = $i;
+ $c->book_page = $after_page + $i;
+ $c->insert();
+ }
+ // Mets à jour la liste des numéros des pages
+ $before = array_slice($num, 0, $after_page);
+ $after = array_slice($num, $after_page, count($num) - $after_page);
+
+ $newnum = $r->numberSections;
+ if (trim($newnum, ',') == '') {
+ // If no number detected, we create a numeric list from 1
+ $between = range(1, $r->pages);
+ } else {
+ // Else, we use numbers detected at conversion
+ $between = explode(',', $r->numberSections);
+ }
+ $num = array_merge($before, $between, $after);
+ // Mets à jour la numerotation de la publication
+ $c = $this->con->openCursor('books');
+ $c->numerotation = implode(',', $num);
+ $c->composition_update = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $this->saveCompositionVersion($book_id);
+ }
+
+ protected function decalePages($book_id, $after_page, $decalage)
+ {
+ $decalage = ($decalage >= 0) ? '+' . $decalage : $decalage;
+ $this->con->execute('UPDATE book_pages SET book_page=book_page' . $decalage . ' WHERE book_page>' . $this->con->escape($after_page) . ' AND book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function getListe($orderby = null, $sens = null, $limit = null, $limitedToUserRights = false)
+ {
+ if (!is_null($this->q)) {
+ $where = '(';
+ if ($this->search_id) {
+ $where .= ' book_id=\'' . $this->con->escape($this->q) . '\' OR ';
+ }
+
+ if (!cubeMath::is_int($this->q)) {
+ $where .= 'nom LIKE \'%' . $this->con->escape($this->q) . '%\'';
+ $daoClient = new commonDAOClient($this->con);
+ $where .= ' OR proprietaire_id IN(' . $daoClient->querySearchByName($this->q) . ') OR ';
+ }
+ $limit = null;
+ $where .= '1=2)';
+ } else {
+ $where = '(' . $this->makeWhereFromFiltres() . ')';
+ }
+ $where .= $this->limitToUserRights($limitedToUserRights);
+
+ $orderby = is_null($orderby) ? 'book_id' : $orderby;
+ $sens = is_null($sens) ? 'DESC' : $sens;
+ $limit = is_null($limit) ? '' : $this->con->limit($limit);
+
+ $sql = 'SELECT * FROM books_vue WHERE ' . $where . ' ORDER BY ' . $orderby . ' ' . $sens . ' ' . $limit;
+ $r = $this->con->select($sql);
+ return $this->factory($r);
+ }
+
+ protected function limitToUserRights($utilisateur)
+ {
+ if ($utilisateur) {
+ if (wsDroits::admin()) {
+ return '';
+ }
+ return ' AND proprietaire IN (' . $utilisateur->ws_rights . ')';
+ }
+ return '';
+ }
+
+ protected function makeWhereFromFiltres()
+ {
+ if (!is_null($this->filtres)) {
+ $w = array('1=1');
+ if (commonFiltre::test('admin_book', $this->filtres)) {
+ $w[] = 'super_admin IN (' . implode(',', array_keys($this->filtres['admin_book'])) . ')';
+ }
+ if (commonFiltre::test('status_book', $this->filtres)) {
+ $w[] = 'status IN(' . implode(',', array_keys($this->filtres['status_book'])) . ')';
+ }
+ if (commonFiltre::test('revendeur_book', $this->filtres)) {
+ $v = array_keys($this->filtres['revendeur_book']);
+ $values = array();
+ foreach ($v as $r) {
+ $values[] = $this->con->escape($r);
+ }
+
+
+ $w[] = 'facturable IN(\'' . implode('\',\'', $values) . '\')';
+ }
+ return implode(' AND ', $w);
+ } else {
+ return '1=1';
+ }
+ }
+
+ public function setChapters($book_id, $json)
+ {
+ $chapters = json_decode($json, true);
+ $res = array();
+
+ foreach ($chapters as $c) {
+ $c['label'] = trim($c['label']);
+ $n = (string)$c['page'];
+ $c['label'] = trim(preg_replace('|\s+' . $n . '$|iu', '', $c['label']));
+ $res[] = $c;
+ }
+
+ $json_chapters = json_encode($res);
+
+ $c = $this->con->openCursor('books');
+ $c->chapters = $json_chapters;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ if ($json_chapters && $json_chapters != '[]') {
+ if (count($res) == 1) {
+ if ($res[0]['label'] == '' && $res[0]['page'] == '') {
+ return;
+ }
+ }
+ $c = $this->con->openCursor('books_chapters_versions');
+ $c->book_id = $book_id;
+ $c->chapters = $json_chapters;
+ $c->time = TIME;
+ $c->insert();
+ }
+ }
+
+ public function setSpecialLinksAndRulers($book_id, $links, $rulers)
+ {
+ $c1 = $this->con->openCursor('special_links_versions');
+ $c = $this->con->openCursor('books');
+
+ if (is_string($links)) {
+ $links = json_encode(json_decode($links, false));
+ }
+ if (is_string($rulers)) {
+ $rulers = json_encode(json_decode($rulers, false));
+ }
+
+ if (is_array($links)) {
+ $links = json_encode($links);
+ }
+ if (is_array($rulers)) {
+ $rulers = json_encode($rulers);
+ }
+
+
+ $c1->links = $c->specialLinks = $links;
+ $c1->rulers = $c->specialRulers = $rulers;
+ $c1->update = $c->changedate = TIME;
+ $c1->book_id = $book_id;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ try {
+ $c1->insert();
+ } catch (Exception $e) {
+ $c1->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\' AND `update`=' . TIME);
+ }
+ }
+
+ public function setTheme($book_id, $theme)
+ {
+ $c = $this->con->openCursor('books');
+ $c->theme = $theme;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setStatus($book_id, $status)
+ {
+ $c = $this->con->openCursor('books');
+ if ($status < 2) {
+ $c->tache = 0;
+ }
+ $c->status = $status;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ return $this->selectById($book_id);
+ }
+
+ public function setChaptersFromOldFluidbook($book_id)
+ {
+ $book = $this->selectById($book_id);
+ $n = explode(',', $book->numerotation);
+
+ $xml = simplexml_load_file('https://ws.fluidbook.com/books/' . $book_id . '/data/links.xml');
+ $res = array();
+ $chapters = $xml->xpath('//chapters');
+ foreach ($chapters as $ch) {
+ $c = array();
+ $c['label'] = (string)$ch->txt;
+
+ $p = intval((string)$ch->page);
+ if ($p <= 0) {
+ continue;
+ }
+ $c['page'] = $n[$p];
+ $c['level'] = intval((string)$ch->level);
+ $res[] = $c;
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->chapters = json_encode($res);
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function saveCompositionVersion($book_id, $time = null)
+ {
+ $time = is_null($time) ? TIME : $time;
+
+ $pages = $this->getPagesOfBook($book_id);
+
+ $c = $this->con->openCursor('book_pages_versions');
+ $c->update = $time;
+ $c->book_id = $book_id;
+ $c->composition = serialize($pages);
+ $c->insert();
+ }
+
+ public function setLang($book_id, $base, $traductions)
+ {
+ // Cleanup user translations
+ $traductions = json_decode($traductions, true);
+ foreach ($traductions as $k => $v) {
+ $traductions[$k] = $v;
+ }
+
+ $daoLang = new wsDAOLang($this->con);
+ $lang = $daoLang->selectById($base);
+ // Cleanup base translations
+ $baseTraductions = $lang->traductions;
+ foreach ($baseTraductions as $k => $v) {
+ $baseTraductions[$k] = $v;
+ }
+ // Then compare them. If there is no differences, we don't save translations in the book
+ if ($traductions == $baseTraductions) {
+ $t = '';
+ } else {
+ $t = json_encode($traductions);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->lang = $base;
+ $c->traductions = $t;
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setSettings($book_id, $settings)
+ {
+ $book = $this->selectById($book_id);
+ $parametres = $book->parametres;
+ $new = $settings;
+ foreach ($new as $k => $v) {
+ if ($k == '_empty_') {
+ continue;
+ }
+ $parametres->$k = $v;
+ }
+
+ $ip = array();
+ if (isset($parametres->stats_exclude_ip) && trim($parametres->stats_exclude_ip) != '') {
+ $list = $parametres->stats_exclude_ip;
+ $list = str_replace("\r", "\n", $list);
+ $e = explode("\n", $list);
+ foreach ($e as $i) {
+ $i = trim($i);
+ if ($i == '') {
+ continue;
+ }
+ $long = ip2long($i);
+ if ($long !== false) {
+ $ip[] = $long;
+ }
+ }
+ }
+
+ $file = '/home/stats/www/exclude/' . $book_id;
+
+ if (count($ip)) {
+ file_put_contents($file, implode(',', $ip));
+ chmod($file, 0777);
+ chown($file, 'stats');
+ } else if (file_exists($file)) {
+ unlink($file);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->nom = $parametres->title;
+ $c->parametres = serialize($parametres);
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setProprietaire($book_id, $proprietaire_id)
+ {
+ $c = $this->con->openCursor('books');
+ $c->proprietaire = $proprietaire_id;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setTache($book_id, $tache)
+ {
+ $c = $this->con->openCursor('books');
+ $c->tache = $tache;
+ $c->status = 2;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setVersion($book_id, $version)
+ {
+ $c = $this->con->openCursor('books');
+ $c->version = $version;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function touch($book_id)
+ {
+ $c = $this->con->openCursor('books');
+ $c->changedate = TIME;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function touchCompile($book_id, $version = 'all')
+ {
+ $c = $this->con->openCursor('books');
+ if ($version == '2') {
+ $c->compiledate = TIME;
+ } elseif ($version == '1') {
+ $c->compile1date = TIME;
+ } elseif ($version == 'html5') {
+ $c->compilehtml5date = TIME;
+ } else {
+ $c->compiledate = TIME;
+ $c->compile1date = TIME;
+ $c->compilehtml5date = TIME;
+ }
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function isUpToDate($book, $version)
+ {
+ $version = (string)$version;
+ if ($version == '2') {
+ if (!file_exists(WS_BOOKS . '/final/' . $book->book_id)) {
+ return false;
+ }
+ if ($book->compiledate < $book->changedate) {
+ return false;
+ }
+ } else if ($version == '1') {
+ // V1
+ if (!file_exists(WS_BOOKS . '/finalv1/' . $book->book_id . '/index.swf')) {
+ return false;
+ }
+ if ($book->compile1date < $book->changedate) {
+ return false;
+ }
+ } else if ($version == 'html5') {
+ return false;
+ // HTML5
+ $checks = array($book->changedate, cubeFiles::filemtimeRecursive(WS_BOOKS . '/working/' . $book->book_id), cubeFiles::filemtimeRecursive(WS_COMPILE_ASSETS . '/_html5'), cubeFiles::filemtimeRecursive(ROOT . '/inc/ws/Util/html5'));
+ foreach ($checks as $check) {
+ if ($check > $book->compilehtml5date) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public function setComposition($book_id, $pages)
+ {
+ $numerotation = array();
+ $nb_pages = 0;
+ foreach ($pages as $p) {
+ $numerotation[] = $p->virtual;
+ $nb_pages++;
+ }
+
+ $book = $this->selectById($book_id);
+ $parametres = $book->parametres;
+ $parametres->pages = $nb_pages;
+
+ $c = $this->con->openCursor('books');
+ $c->parametres = serialize($parametres);
+ $c->numerotation = implode(',', $numerotation);
+ $c->changedate = TIME;
+
+ // Check if composition need to be updated
+ $r = $this->con->select('SELECT * FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ $tab = array();
+ $now = array();
+ $ref = array();
+ while ($r->fetch()) {
+ $ref[$r->book_page] = array((int)$r->document_id, (int)$r->document_page);
+ }
+ $i = 1;
+ foreach ($pages as $p) {
+ $now[$i] = array((int)$p->document_id, (int)$p->document_page);
+ $i++;
+ }
+ if ($now != $ref) {
+ $this->con->execute('DELETE FROM book_pages WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+
+ $c1 = $this->con->openCursor('book_pages');
+ $c1->book_id = $book_id;
+ $i = 1;
+ foreach ($pages as $p) {
+ $c1->document_id = $p->document_id;
+ $c1->document_page = $p->document_page;
+ $c1->book_page = $i;
+ $c1->insert();
+ $i++;
+ }
+ $c->composition_update = TIME;
+ $this->saveCompositionVersion($book_id);
+ }
+
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function setInstallDir($book_id, $dir, $server)
+ {
+ $col = 'dir_' . $server;
+
+ $c = $this->con->openCursor('books');
+ $c->$col = $dir;
+ $c->update('WHERE book_id=\'' . $this->con->escape($book_id) . '\'');
+ }
+
+ public function makeTextsIndexes($book, $pages, &$index, &$textes, $simple = false)
+ {
+ global $core;
+ $prefix = '';
+ if ($book->parametres->textExtraction == 'poppler') {
+ $prefix = 'p';
+ } else if ($book->parametres->textExtraction == 'fluidbook') {
+ $prefix = 'f';
+ }
+
+ $dir = WS_BOOKS . '/index/' . $book->book_id;
+ if ($book->parametres->ignoreSearchSeparators != '') {
+ $dir .= '/' . sha1($book->parametres->ignoreSearchSeparators);
+ }
+ if (!file_exists($dir)) {
+ mkdir($dir, 0777, true);
+ }
+
+ if ($simple) {
+ $ifilec = $dir . '/' . $prefix . 'sindex.json';
+ } else {
+ $ifilec = $dir . '/' . $prefix . 'index.json';
+ }
+ $tfilec = $dir . '/' . $prefix . 'textes.json';
+
+ if (CubeIT_Util_Gzip::file_exists($ifilec) && CubeIT_Util_Gzip::file_exists($tfilec) && (min(CubeIT_Util_Gzip::filemtime($ifilec), CubeIT_Util_Gzip::filemtime($tfilec)) >= max($book->composition_update, filemtime(__FILE__), filemtime(WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar')))) {
+ $index = CubeIT_Util_Gzip::file_get_contents($ifilec);
+ $textes = CubeIT_Util_Gzip::file_get_contents($tfilec);
+ return;
+ }
+
+ if ($book->parametres->ignoreSearchSeparators != "") {
+ $docs = array();
+ foreach ($pages as $p => $i) {
+ $docs[] = $i['document_id'];
+ }
+ $docs = array_unique($docs);
+
+ foreach ($docs as $doc) {
+ $out = wsDocument::getDir($doc);
+
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $out . '/crop.pdf');
+ $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
+ $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
+ $fwstk->setArg('--threads 1');
+ $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
+ $fwstk->execute();
+ }
+ }
+
+ $index = array();
+ $textes = array();
+ foreach ($pages as $book_page => $infos) {
+ $tfile = wsDocument::getDir($infos['document_id']) . $prefix . 'p' . $infos['document_page'] . '.txt';
+ $ifile = wsDocument::getDir($infos['document_id']) . $prefix . 'i' . $infos['document_page'] . '.txt';
+
+ if (!file_exists($tfile) || !file_exists($ifile)) {
+ $daoDoc = new wsDAODocument($core->con);
+ $out = wsDocument::getDir($infos['document_id']);
+
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $out . '/crop.pdf');
+ $fwstk->setArg('--extractTexts ' . $out . '%s%d.txt');
+ $fwstk->setArg('--extractTextsMethod ' . $book->parametres->textExtraction);
+ if ($book->parametres->ignoreSearchSeparators != '') {
+ $fwstk->setArg('--ignoreSeparators ' . $book->parametres->ignoreSearchSeparators);
+ }
+ $fwstk->setArg('--threads 1');
+ $fwstk->execute();
+ }
+
+ CubeIT_Util_Gzip::compressIfNotCompressed($tfile);
+ CubeIT_Util_Gzip::compressIfNotCompressed($ifile);
+ $text = CubeIT_Util_Gzip::file_get_contents($tfile);
+ $ipage = CubeIT_Util_Gzip::file_get_contents($ifile);
+
+ if ($simple) {
+ $this->fillIndexWithWordsSimple($index, $book_page, $ipage);
+ } else {
+ $this->fillIndexWithWords($index, $book_page, $ipage);
+ }
+ $textes[$book_page] = $text;
+ }
+ ksort($index);
+
+ $textes = json_encode($textes);
+ $index = json_encode($index);
+
+ CubeIT_Util_Gzip::file_put_contents($tfilec, $textes);
+ CubeIT_Util_Gzip::file_put_contents($ifilec, $index);
+ }
+
+ public function makeHighlightIndex($book, $pages)
+ {
+ $jar = WS_TOOLS . '/fwstk/out/artifacts/fwstk_jar/fwstk.jar';
+
+ $daoDoc = new wsDAODocument($this->con);
+ $res = new stdClass();
+ foreach ($pages as $book_page => $infos) {
+ $fby = wsDocument::getDir($infos['document_id']) . 'html/p' . $infos['document_page'] . '.fby';
+ // Refresh highlight data if fby file doesn't exists or if fwstk has been updated
+ $fbymtime = @filemtime($fby);
+ if (!file_exists($fby) || filemtime($jar) > $fbymtime || filemtime(__FILE__) > $fbymtime) {
+ $doc = $daoDoc->selectById($infos['document_id']);
+ $doc->getHighlightTextsData();
+ }
+
+ if (file_exists($fby)) {
+ $words = CubeIT_Util_Json::decode(file_get_contents($fby), CubeIT_Util_Json::TYPE_OBJECT);
+
+ foreach ($words as $i => $w) {
+ $word = $w->word;
+ $word = trim($word, "\0");
+ if ($word == '') {
+ continue;
+ }
+ unset($w->word);
+ $w->page = $book_page;
+ $w->idx = $i;
+ if (!isset($res->{$word})) {
+ $res->{$word} = array();
+ }
+ $res->{$word}[] = $w;
+ }
+ }
+ }
+ return $res;
+ }
+
+ protected function _escapeIndex($str)
+ {
+ $todelete = array('\ufffd');
+ foreach ($todelete as $d) {
+ $str = str_replace($d, '', $str);
+ }
+ return $str;
+ }
+
+ protected function fillIndexWithWordsSimple(&$index, $page, $ipage)
+ {
+ $twords = explode("\n", trim($ipage));
+
+ foreach ($twords as $woadata) {
+ $w1 = explode(',', trim($woadata));
+ if (count($w1) <= 1) {
+ continue;
+ }
+ list($woa, $worddata) = $w1;
+ $e = explode("\t", $worddata, 2);
+ if (count($e) < 2) {
+ continue;
+ }
+ list($total, $wordslist) = $e;
+
+ if ($woa == '') {
+ continue;
+ }
+
+ if (!isset($index[$woa])) {
+ $index[$woa] = array('t' => 0, 'p' => array());
+ }
+ $index[$woa]['t'] += $total;
+
+ $words = explode("\t", $wordslist);
+ foreach ($words as $word) {
+ list($wordwa, $count) = explode('$', $word, 2);
+ if (!isset($index[$woa]['p'][$page])) {
+ $index[$woa]['p'][$page] = 0;
+ }
+ $index[$woa]['p'][$page] += $count;
+ }
+ }
+ }
+
+ protected function fillIndexWithWords(&$index, $page, $ipage)
+ {
+ $twords = explode("\n", trim($ipage));
+
+ foreach ($twords as $woadata) {
+ $w1 = explode(',', trim($woadata));
+ if (count($w1) <= 1) {
+ continue;
+ }
+ list($woa, $worddata) = $w1;
+ $e = explode("\t", $worddata, 2);
+ if (count($e) < 2) {
+ continue;
+ }
+ list($total, $wordslist) = $e;
+
+ if ($woa == '') {
+ continue;
+ }
+
+ if (!isset($index[$woa])) {
+ $index[$woa] = array('t' => 0, 'w' => array());
+ }
+ $index[$woa]['t'] += $total;
+
+ $words = explode("\t", $wordslist);
+
+ foreach ($words as $word) {
+ list($wordwa, $count) = explode('$', $word, 2);
+ if (!isset($index[$woa]['w'][$wordwa])) {
+ $index[$woa]['w'][$wordwa] = array('t' => 0, 'p' => array());
+ }
+ if (!isset($index[$woa]['w'][$wordwa]['p'][$page])) {
+ $index[$woa]['w'][$wordwa]['p'][$page] = 0;
+ }
+ $index[$woa]['w'][$wordwa]['t'] += $count;
+ $index[$woa]['w'][$wordwa]['p'][$page] += $count;
+ }
+ }
+ }
+
+ public function getNumerotationFromDocs($book_id)
+ {
+ $pages = $this->getPagesOfBook($book_id);
+ }
+
+ public function compileTemp($book_id, $version, $dir)
+ {
+ if ($version == 'ha' || $version == 'hi') {
+ if ($version == 'ha') {
+ $os = 'android';
+ } elseif ($version == 'hi') {
+ $os = 'ios';
+ }
+ $packager = new wsPackagerPhonegap($book_id, $dir, false, true, $os);
+ $packager->makePackage(false);
+ }
+ }
+
+ public function compile($book_id, $version = 'all', $complete = false, $force = false, $dev = false)
+ {
+ if (is_null($book_id) || !$book_id) {
+ return;
+ }
+
+ $v1 = $v2 = $html5 = false;
+
+ if ($version == 'all') {
+ $v1 = $v2 = $html5 = true;
+ } else if ($version == '1') {
+ $v1 = true;
+ } else if ($version == '2') {
+ $v2 = true;
+ } elseif ($version == 'html5') {
+ $html5 = true;
+ }
+
+ $book = $this->selectById($book_id);
+ $pages = $this->getPagesOfBook($book_id);
+
+ if (!$force) {
+
+ $v1 = $v1 && !$this->isUpToDate($book, 1);
+ $v2 = $v2 && !$this->isUpToDate($book, 2);
+ $html5 = $html5 && !$this->isUpToDate($book, 'html5');
+ } else {
+ $v1 = false;
+ $html5 = true;
+ $v2 = true;
+ }
+
+
+ $res = '';
+ if ($v1) {
+ fb(time(), 'Compile V1');
+ $res .= $this->compile1($book_id, $book, $pages);
+ $this->touchCompile($book_id, '1');
+ }
+ if ($v2) {
+ fb(time(), 'Compile V2');
+ $res .= $this->compile3($book_id, $complete, $book, $pages);
+ $this->touchCompile($book_id, '2');
+ }
+ if ($html5) {
+ fb(time(), 'Compile HTML5');
+ $res .= $this->compileHTML5($book_id, $book, $dev);
+ $this->touchCompile($book_id, 'html5');
+ }
+ if ($v1 || $v2) {
+ fb(time(), 'Compile PDF & Widget');
+ $this->compilePDF($book, $pages);
+ $this->compileWidget($book, $pages);
+ }
+
+ fb(time(), 'End Compile');
+ return $res;
+ }
+
+ public function compile1($book_id, $book, $pages)
+ {
+ $finalDir = WS_BOOKS . '/finalv1/' . $book_id . '/';
+ $packager = new wsPackagerV1($book_id, $finalDir, false);
+ $packager->makePackage(false);
+ }
+
+ public function compile3($book_id, $complete, $book, $pages)
+ {
+ $res = '';
+
+ $compilerDir = WS_BOOKS . '/datasCompiler/' . $book_id . '/';
+ $finalDir = WS_BOOKS . '/final/' . $book_id . '/';
+
+ $vdir = new CubeIT_Files_VirtualDirectory($finalDir);
+
+ $debug = false;
+
+ $flex = new cubeFlexCompiler('FluidbookDatas', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
+ $flexLight = new cubeFlexCompiler('FluidbookDatasLight', $compilerDir, 'flash.display.Sprite', explode(';', AS3_SOURCES), MXMLC_PATH, 10, 30, 800, 600, $debug);
+
+ $filesToCopy = array();
+ $this->compileFlex($book_id, $complete, $compilerDir, $vdir, $filesToCopy, $book, $pages, $flex, $flexLight, $finalDir);
+
+ $res .= $flex->compile() . "\n\n-------------------\n\n";
+ $flexLight->addVariable('datasSize', filesize($compilerDir . '/FluidbookDatas.swf'));
+ $res .= $flexLight->compile();
+
+ $filesToCopy['data/fd.swf'] = $compilerDir . '/FluidbookDatas.swf';
+ $filesToCopy['data/fdl.swf'] = $compilerDir . '/FluidbookDatasLight.swf';
+
+ // Copy of files
+ // Check if dest dir exists
+
+ foreach ($filesToCopy as $local => $source) {
+ $localPath = $local;
+ $vdir->copy($source, $localPath);
+ }
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+ $vdir->copyDirectory($workingDir . 'media', 'data');
+ $vdir->sync(true);
+
+ return $res;
+ }
+
+ public function copy($source, $dest)
+ {
+ copy($source, $dest);
+ touch($dest, filemtime($source));
+ }
+
+ public static function getDocumentPage($book_id, $book_page)
+ {
+ global $core;
+ $dao = new wsDAOBook($core->con);
+ $pages = $dao->getPagesOfBook($book_id);
+ return $pages[$book_page];
+ }
+
+ public function compileAir($book_id)
+ {
+ $compilerDir = WS_BOOKS . '/air/' . $book_id . '/compiler';
+ $finalDir = WS_BOOKS . '/air/' . $book_id . '/';
+
+ $book = $this->selectById($book_id);
+ $pages = $this->getPagesOfBook($book_id);
+
+ $src = AS3_FLUIDBOOK_SOURCES . '/_src/';
+ $lib10 = AS3_FLUIDBOOK_SOURCES . '/lib10/';
+ $libs = array(
+ $src,
+ $lib10,
+ AS3_SOURCES,
+ $src . 'lib/fluidbook3dLibrary.swc',
+ $src . 'lib/mdm.swc',
+ $lib10 . 'flash.swc',
+ $lib10 . 'flex.swc',
+ $lib10 . 'framework.swc',
+ );
+
+ wsSVN::updateToLastRevision();
+
+ $swf = 'FluidbookAirProjector' . $book_id;
+ $flex = new cubeFlexCompiler($swf, $compilerDir, 'com.fluidbook.player.AIRMain', $libs, '/usr/local/flex/bin/mxmlc', 'air', 45, 800, 600, true);
+
+ $this->compileFlex($book_id, true, $compilerDir, $finalDir, $filesToCopy, $book, $pages, $flex, $flex);
+ $res = $flex->compile();
+
+ $air = new cubeAIRCompiler($swf . '.swf', '/usr/local/flex/bin', $compilerDir, '2.0');
+ $air->setApplicationDatas('com.fluidbook' . $book_id, $book->parametres->title, $book->parametres->title, cubeText::str2URL($book->parametres->title), $book->lang);
+ $air->setInitialWindow($book->parametres->title);
+ $res .= $air->compile();
+
+ return $res;
+ }
+
+ public function compileFlex($book_id, $complete, $compilerDir, $vdir, &$filesToCopy, $book, $pages, $flex, $flexLight)
+ {
+ /* @var $vdir CubeIT_Files_VirtualDirectory */
+
+ cubePHP::neverStop();
+ /* @var $flex cubeFlexCompiler */
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+
+ $res = '';
+
+ $daoDoc = new wsDAODocument($this->con);
+ $firstDoc = $daoDoc->selectById($pages[1]['document_id']);
+ $size = $firstDoc->generalInfos['size'];
+
+ $daoLang = new wsDAOLang($this->con);
+ $lang = $daoLang->selectById($book->lang);
+
+ $langs = $daoLang->selectAll();
+
+ $daoTheme = new wsDAOTheme($this->con);
+ $theme = $daoTheme->getThemeOfBook($book_id, true);
+
+ $daoSignature = new wsDAOSignature($this->con);
+ $signature = $daoSignature->selectById($book->parametres->signature);
+
+ $exportSignature = array('main' => $signature->main,
+ 'mainLink' => $signature->mainLink,
+ 'partner' => $signature->partner,
+ 'partnerLink' => $signature->partnerLink);
+
+ $index = '';
+ $textes = '';
+ $pageLabels = array();
+
+ $hash = $book_id;
+ $hash .= 'kjgl!az4.';
+ $hash .= count($pages);
+ $hash .= round($size[0], 3);
+
+ $hash = sha1($hash);
+
+ $this->makeTextsIndexes($book, $pages, $index, $textes);
+
+ $daoDoc->getLinksAndRulers($book_id, $links, $rulers);
+
+ $audiodescription = array();
+
+ $imagesassets = array();
+ $id = 1;
+ $ignoreLinks = array();
+ foreach ($links as $id => $link) {
+ $links[$id]['id'] = $id;
+ $skipCopyAsset = false;
+
+ if (isset($link['image']) && $link['image']) {
+ $workingFile = $workingDir . '/' . $link['image'];
+ $assetId = 'link_datas_i_' . md5($link['image']);
+
+ if (isset($imagesassets[$assetId])) {
+
+ } else {
+ if (file_exists($workingFile)) {
+ if ($link['page'] <= 1) {
+ $flexLight->addBitmap($workingFile, $assetId);
+ } else {
+ $flex->addBitmap($workingFile, $assetId);
+ }
+ }
+ $imagesassets[$assetId] = true;
+ }
+ }
+
+ if ($link['type'] == 16 && $book->parametres->linkFilePrefix) {
+ if (!CubeIT_Util_Url::isDistant($link['to'])) {
+ $skipCopyAsset = true;
+ $links[$id]['to'] = $book->parametres->linkFilePrefix . $link['to'];
+ }
+ }
+
+ if ($link['type'] == 15) {
+ if (isset($imagesassets[$id])) {
+ continue;
+ }
+ if ($link['page'] <= 1) {
+ $flexLight->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
+ } else {
+ $flex->addBitmap($workingDir . '/' . $link['to'], 'link_datas_' . $id);
+ }
+ $imagesassets[$id] = true;
+ } else if (in_array($link['type'], array(4, 6, 7, 9, 16, 17, 25))) {
+ if (!$skipCopyAsset) {
+ $workingFile = $workingDir . '/' . $link['to'];
+ if (file_exists($workingFile)) {
+ $filesToCopy['data/' . $link['to']] = $workingFile;
+ }
+
+ if ($link['type'] == 4) {
+ $poster = $link['to'];
+ $e = explode('.', $poster);
+ array_pop($e);
+ array_push($e, 'jpg');
+ $poster = implode('.', $e);
+
+ $workingFile = $workingDir . '/' . $poster;
+ if (file_exists($workingFile)) {
+ $filesToCopy['data/' . $poster] = $workingFile;
+ }
+ }
+ }
+ }
+
+ if ($link['type'] == 25) {
+ $audiodescription[$link['page']] = $link['to'];
+ $ignoreLinks[] = $id;
+ }
+ if ($link['type'] == 26) {
+ $pageLabels[$link['to']] = $link['page'];
+ $ignoreLinks[] = $id;
+ }
+ }
+
+ foreach ($ignoreLinks as $ignoreLink) {
+ unset($links[$ignoreLink]);
+ }
+ $links = array_values($links);
+
+ $externalsOptions = array('ongletsSWF', 'tabs2DSWF', 'externalChapters', 'externalArchives', 'ambientSound');
+ foreach ($externalsOptions as $e) {
+ if (isset($book->parametres->$e) && $book->parametres->$e != '') {
+ $f = $workingDir . '/' . $book->parametres->$e;
+ if (file_exists($f)) {
+ $filesToCopy['data/' . $book->parametres->$e] = $f;
+ }
+ }
+ }
+
+ $flex->addVariable('audiodescription', $audiodescription, false, true, "JSONObject");
+ $flex->addVariable('pagelabels', $pageLabels, false, true, 'JSONObject');
+ $flex->addVariable('links', $links, false, true, 'JSONObject');
+
+ $flex->addVariable('signature', $exportSignature, false, true, 'JSONObject');
+ $flexLight->addVariable('datas', $book->parametres->toStandardObject(), false, true, 'JSONObject');
+ $flexLight->addVariable('id', $book_id, false, true, 'uint');
+ $flexLight->addVariable('cid', $book->cid, false, true, 'String');
+
+ $traductions = (!count($book->traductions)) ? $lang->traductions : $book->traductions;
+ $allTraductions = array();
+ foreach ($langs as $l) {
+ $allTraductions[$l->lang_id] = $l->traductions;
+ }
+
+ $flex->addVariable('traductions', $traductions, false, true, 'JSONObject', false);
+ $flex->addVariable('allTraductions', $allTraductions, false, true, 'JSONObject');
+ $flex->addVariable('chapters', $book->chapters, false, true, 'JSONObject');
+ $flex->addVariable('extras', '<extras>' . $book->extras . '</extras>', false, true, 'XML');
+ $flex->addVariable('numerotation', $book->numerotation, false, true, 'String');
+ $flexLight->addVariable('theme', $theme->parametres->toStandardObject(), false, true, 'JSONObject');
+ $flexLight->addVariable('pages', $book->parametres->pages);
+ $flexLight->addVariable('fwidth', round($size[0], 4), false, true, 'Number');
+ $flexLight->addVariable('fheight', round($size[1], 4), false, true, 'Number');
+ $flexLight->addVariable('pagesInDatas', $complete, false, true, 'Boolean');
+ $flex->addVariable('index', $index, false, true, 'JSONObject', false, false);
+ $flex->addVariable('textes', $textes, false, true, 'JSONObject', false, false);
+
+ $rasterized = array();
+ $sizes = array();
+
+ foreach ($pages as $i => $infos) {
+ $base = wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'];
+ $baset = wsDocument::getDir($infos['document_id']) . 't' . $infos['document_page'];
+ $swffile = $base . '.swf';
+ if (file_exists($swffile)) {
+ clearstatcache(true, $swffile);
+ $fsize = filesize($swffile);
+ } else {
+ $fsize = 0;
+ }
+
+ if ($complete) {
+ $flex->addSWF($swffile, 'page' . $i);
+ } else {
+ $filesToCopy['data/p' . $i . '.swf'] = $swffile;
+ if ($infos['method'] >= wsDocument::BARBARE_PNM) {
+ $rasterized[$i] = true;
+ $filesToCopy['data/t' . $i . '.swf'] = $baset . '.swf';
+ } else {
+ $rasterized[$i] = false;
+ }
+ }
+
+ $thumb = false;
+ if ($book->parametres->pdfThumbnails) {
+ $thumb = wsPDFConvert::getThumbFromPDF($workingDir . '/' . $book->parametres->pdfThumbnails, $i);
+ }
+ if (!$thumb) {
+ $thumb = $base . '.jpg';
+ }
+
+ if ($i == 1) {
+ $flexLight->addBitmap($thumb, 'thumb1');
+ } else {
+ $flex->addBitmap($thumb, 'thumb' . $i);
+ }
+ $sizes[$i] = $fsize;
+ }
+
+ $flexLight->addVariable('rasterized', $rasterized, false, true, 'JSONObject');
+ $flexLight->addVariable('sizes', $sizes, false, true, 'JSONObject');
+
+ if ($book->parametres->soundTheme != '') {
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-drag.mp3', 'soundDragCorner');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/corner-release.mp3', 'soundReleaseCorner');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-1.mp3', 'soundPage0');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/page-flip-2.mp3', 'soundPage1');
+ $flex->addSound(WS_SOUNDS . '/' . $book->parametres->soundTheme . '/cover-flip.mp3', 'soundCover0');
+ }
+ // Theme assets
+ $themeRoot = WS_THEMES . '/' . $theme->theme_id . '/';
+
+ if ($theme->parametres->backgroundImage != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->backgroundImage, 'background');
+ }
+ if ($theme->parametres->menuImage != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->menuImage, 'menu');
+ }
+ if ($theme->parametres->logoLoader != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->logoLoader, 'logoLoader');
+ }
+ if ($theme->parametres->topBar != '') {
+ $flexLight->addBitmap($themeRoot . $theme->parametres->topBar, 'topBar');
+ }
+ if ($theme->parametres->logo != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->logo, 'logo');
+ }
+ if ($theme->parametres->afterSearch != '') {
+ $flex->addBitmap($themeRoot . $theme->parametres->afterSearch, 'aftersearch');
+ }
+ if ($theme->parametres->favicon != '') {
+ $filesToCopy['data/fluidbook.ico'] = $themeRoot . 'fluidbook.ico';
+ }
+
+ // Icons assets
+ $iconsRoot = WS_ICONS . '/' . $theme->parametres->iconSet . '/';
+ foreach (wsIcone::$files as $file) {
+ $flex->addBitmap($iconsRoot . 'nav-' . $file . '.png', 'nav_' . $file);
+ }
+ // Share icons
+ $iconsRoot = WS_ICONS . '/share/';
+ foreach (wsIcone::$share as $file) {
+ $flex->addBitmap($iconsRoot . 'share-' . $file . '.png', 'share_' . $file);
+ }
+
+ // Multilang
+ if (trim($book->parametres->multilang) != '') {
+ $m = str_replace("\r", "\n", trim($book->parametres->multilang));
+ $langs = explode("\n", $m);
+ $langNames = array();
+ $countryNames = array();
+ $iso = l10n::getISOcodes();
+ $chars = '()';
+ $vuFlags = array();
+ foreach ($langs as $l) {
+ list($mlang, $flag, $url) = explode(',', trim($l), 3);
+ if (!isset($vuFlags[$flag])) {
+ $flex->addBitmap(cubeMedia::getFlagFile($flag), 'flag_' . $flag);
+ $vuFlags[$flag] = true;
+ }
+ $ll = explode('-', $mlang);
+ $n = cubeText::ucfirst($iso[$ll[0]]);
+ $langNames[$mlang] = $n;
+ $cn = cubeCountry::getCountryName($flag, $mlang);
+ $countryNames[$mlang . '_' . $flag] = $cn;
+ $chars .= $n . $cn;
+ }
+
+ $chars = preg_split('/(?<!^)(?!$)/u', $chars);
+ $chars = array_unique($chars);
+
+ $flex->addFont(WS_FILES . '/fonts/FluidbookMultilang.ttf', 'MultilangFont', $chars);
+ $flex->addVariable('langNames', $langNames, false, true, 'JSONObject');
+ $flex->addVariable('countryNames', $countryNames, false, true, 'JSONObject');
+ }
+ $flexLight->addVariable('lang', $book->lang);
+
+ // Basket
+ if ($book->parametres->basket) {
+ $formats = array('jpg', 'png', 'jpeg');
+ $referencesFile = self::getWorkingFile($book->parametres->basketReferences, $book_id, 'commerce');
+
+ if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
+ $ext = CubeIT_Files::getExtension($referencesFile);
+ if ($ext == 'xml') {
+ $xml = simplexml_load_file($referencesFile);
+ $i = 0;
+ $allref = array();
+ foreach ($xml->item as $item) {
+ $ref = (string)$item['reference'];
+ if (isset($allref[$ref])) {
+ continue;
+ }
+ $allref[$ref] = true;
+ foreach ($formats as $f) {
+ $refimage = $workingDir . 'commerce/' . $ref . '.' . $f;
+ if (file_exists($refimage)) {
+ $flex->addBitmap($refimage, "basket_image_" . $ref);
+ break;
+ }
+ }
+ $i++;
+ }
+ } elseif ($ext == 'xlsx') {
+ $references = wsUtil::excelToArray($referencesFile);
+ if ($book->parametres->customLinkClass == 'AtlanticDownloadLink') {
+ $references = wsUtil::atlanticReferences($references, 'local/', null, array($vdir, 'copy'));
+ }
+ $flex->addVariable('basketReferences', $references, false, true, "OrderedObject");
+ }
+ }
+ if (isset($xml)) {
+ $flex->addVariable('basketReferences', cubeXML::condense($xml->asXML()), false, true, "String");
+ }
+ if ($book->parametres->basketPDFBackground != '') {
+ $flex->addByteArray($workingDir . 'commerce/' . $book->parametres->basketPDFBackground, 'basket_pdf_background');
+ }
+ }
+ // Fonts
+ if ($theme->parametres->fontKit == 'auto') {
+ if ($lang->font != 'system') {
+ $font = FONT_PATH . '/' . $lang->font;
+ $bfont = FONT_PATH . '/B' . $lang->font;
+ if (!file_exists($bfont)) {
+ $bfont = $font;
+ }
+
+ $flex->addFont($bfont, 'BoldFont', $lang->charset);
+ $flex->addFont($font, 'GeneralFont', $lang->charset);
+ }
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/FluidbookLoader.ttf', 'LoaderFont', 'Numerals');
+ } else if ($theme->parametres->fontKit == 'vagrounded') {
+ $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'BoldFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Light.otf', 'GeneralFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/vagrounded/VAGRoundedStd-Bold.otf', 'LoaderFont', 'Numerals');
+ } else if ($theme->parametres->fontKit == 'gill') {
+ $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'BoldFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/gill/gill.ttf', 'GeneralFont', $lang->charset);
+ $flex->addFont(FONT_PATH . '/FluidbookCredits.ttf', 'CreditsFont', 'ASCII');
+ $flexLight->addFont(FONT_PATH . '/gill/gill.ttf', 'LoaderFont', 'Numerals');
+ }
+
+ $flexLight->addVariable('checksum', $hash, false, true, 'String');
+ }
+
+
+ public static function getWorkingFile($path, $book_id, $dir = "")
+ {
+ if (CubeIT_Util_Url::isDistant($path) || (substr($path, 0, 1) == '/' && file_exists($path))) {
+ return $path;
+ }
+
+ $workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+ return $workingDir . trim($dir, '/') . '/' . $path;
+ }
+
+ public function compileWidget($book, $pages)
+ {
+ if (!$book->parametres->widget) {
+ return;
+ }
+
+ global $core;
+
+ $finalDir = WS_BOOKS . '/final/' . $book->book_id . '/widget/';
+ $finalWidget = $finalDir . 'miniFluidbook.swf';
+
+ if (!file_exists($finalDir)) {
+ mkdir($finalDir, 0777, true);
+ }
+
+ if ($book->parametres->widgetCover) {
+ $file = 'miniFluidbookCouv.swf';
+ } else {
+ $file = 'miniFluidbook.swf';
+ }
+ $mini = WS_COMPILE_ASSETS . '/_widget/' . $file;
+
+ $from = max(1, $book->parametres->widgetStart);
+ $to = min($book->parametres->widgetEnd, count($pages));
+
+ $swfcombine = new cubeCommandLine('swfcombine');
+ $swfcombine->setPath(CONVERTER_PATH);
+ $swfcombine->setArg('merge');
+ $swfcombine->setArg('stack1');
+ $swfcombine->setArg('z');
+ $swfcombine->setArg('o', $finalWidget);
+ $swfcombine->setArg(null, $mini);
+
+ $tempimage = array();
+ $tempswf = array();
+ $timg = array();
+
+ for ($i = $from; $i <= $to; $i++) {
+ $page = $pages[$i];
+
+ $timg[$i] = $tempimage[$i] = cubeFiles::tempnam();
+ $tempswf[$i] = cubeFiles::tempnam();
+
+ $it = new imageTools();
+ $image = wsDocument::getDir($page['document_id']) . '/html/t150-' . $page['document_page'] . '.jpg';
+
+ try {
+ $it->loadImage($image);
+ $it->resize($book->parametres->widgetSize, 10000);
+ $it->output('jpeg', $tempimage[$i], 100);
+ } catch (Exception $e) {
+ $tempimage[$i] = $image;
+ }
+ $jpg2swf = new cubeCommandLine('jpeg2swf');
+ $jpg2swf->setEnv('PATH', '/bin:/usr/bin:/usr/local/bin');
+ $jpg2swf->setArg('q', $book->parametres->widgetQuality);
+ $jpg2swf->setArg('o', $tempswf[$i]);
+ $jpg2swf->setArg(null, $tempimage[$i]);
+ $jpg2swf->execute();
+
+ $swfcombine->setArg(null, $tempswf[$i]);
+ }
+ $swfcombine->execute();
+
+ foreach ($timg as $t) {
+ if (file_exists($t)) {
+ unlink($t);
+ }
+ }
+ foreach ($tempswf as $t) {
+ unlink($t);
+ }
+ }
+
+ public function compileHTML5($book_id, $book, $dev = false)
+ {
+ $version = $book->parametres->mobileLVersion;
+ if ($dev) {
+ $version = 'dev';
+ }
+
+ $htmlCompiler = wsHTML5::compilerFactory($book_id, $version);
+ $htmlCompiler->compile();
+ }
+
+ /* public function indexPDF($book, $pages) {
+ $indexPath = WS_BOOKS . '/search/' . $book->book_id;
+
+ Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
+
+ if (file_exists($indexPath)) {
+ files::deltree($indexPath);
+ }
+ $index = Zend_Search_Lucene::create($indexPath);
+
+ foreach ($pages as $i => $infos) {
+ $doc = new Zend_Search_Lucene_Document();
+ $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i));
+ $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'] . '.txt')));
+ $index->addDocument($doc);
+ }
+
+ $c = $this->con->openCursor('books');
+ $c->lucene_time = TIME;
+ $c->update('WHERE book_id=' . $book->book_id);
+ } */
+
+ public function compilePDF($book, $pages)
+ {
+ if (substr($book->parametres->pdfName, 0, 4) == 'http') {
+ return;
+ }
+ if (isset($book->parametres->pdfName) && $book->parametres->pdfName != '') {
+ $pdfName = $book->parametres->pdfName;
+ }
+
+ $cacheDir = WS_BOOKS . '/pdf/' . $book->book_id;
+ if (!file_exists($cacheDir)) {
+ mkdir($cacheDir, 0777, true);
+ }
+
+ $normalPDF = $cacheDir . '/normal.pdf';
+ $originalPDF = $cacheDir . '/original.pdf';
+ $compressedPDF = $cacheDir . '/compressed.pdf';
+
+ if (file_exists($originalPDF)) {
+ $fmtime = filemtime($originalPDF);
+ if ($fmtime >= $book->composition_update) {
+ $invalid = false;
+ foreach ($pages as $i => $infos) {
+ $doc = wsDocument::getDir($infos['document_id']) . 'crop.pdf';
+ if (filemtime($doc) > $fmtime) {
+ $invalid = true;
+ }
+ }
+ } else {
+ $invalid = true;
+ }
+ } else {
+ $invalid = true;
+ }
+
+
+ if ($invalid) {
+ $pdfList = array();
+ $pagesList = array();
+ $nb_pages = array();
+ $j = 0;
+ $k = 0;
+ $original = true;
+
+ foreach ($pages as $i => $infos) {
+ if (!isset($firstDoc)) {
+ $firstDoc = $infos['document_id'];
+ }
+
+ $doc = wsDocument::getDir($infos['document_id']) . 'crop.pdf';
+ if (!isset($pdfList[$doc])) {
+ $pdfList[$doc] = $j;
+ $nb_pages[$doc] = $infos['nb_pages'];
+ $k = $j;
+ $j++;
+ } else {
+ $k = $pdfList[$doc];
+ }
+ $pagesList[$i] = array($k, $infos['document_page']);
+
+ if ($i != $infos['document_page'] || $infos['document_id'] != $firstDoc) {
+ $original = false;
+ }
+ }
+
+ if ($original) {
+
+ $this->copy(wsDocument::getDir($firstDoc) . 'crop.pdf', $originalPDF);
+ } else {
+ $args = '';
+ foreach ($pdfList as $doc => $index) {
+ $lettre = cubeMath::toPDFLetter($index, true);
+ $args .= $lettre . '=' . $doc . ' ';
+ }
+
+ $args .= ' cat ';
+
+ $ranges = array();
+ $currentRange = null;
+
+ foreach ($pagesList as $p) {
+ $lettre = cubeMath::toPDFLetter($p[0], true);
+ $page = $p[1];
+
+ // Initialise l'intervale
+ if (is_null($currentRange)) {
+ $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);
+ continue;
+ }
+
+ // Poursuit le remplissage si la lettre est identique et si la page suivante est bien la page suivante dans le document
+ if ($currentRange['lettre'] == $lettre && $currentRange['end'] + 1 == $page) {
+ $currentRange['end'] = $page;
+ continue;
+ }
+
+ // Ajoute l'intervale à la liste finale
+ $ranges[] = $currentRange;
+
+ // Réinitialise l'intervale suivant
+ $currentRange = array('lettre' => $lettre, 'start' => $page, 'end' => $page);
+ }
+
+ // Ajoute la dernière
+ if (!is_null($currentRange)) {
+ $ranges[] = $currentRange;
+ }
+ // Si le pdf final est constitué du document complet d'un document
+ if (count($ranges) == 1 && $ranges[0]['start'] == 1) {
+ $alldocs = array_keys($pdfList);
+ $doc = array_pop($alldocs);
+ if ($nb_pages[$doc] == $ranges[0]['end']) {
+ $this->copy($doc, $originalPDF);
+ return;
+ }
+ }
+
+ foreach ($ranges as $range) {
+ $args .= ' ' . $range['lettre'] . $range['start'];
+ if ($range['start'] == $range['end']) {
+ continue;
+ }
+ $args .= '-' . $range['end'];
+ }
+
+ $hash = sha1($args);
+
+ $args .= ' output ' . $originalPDF;
+
+ $cached = WS_BOOKS . '/pdf/' . $hash . '.pdf';
+
+ if (file_exists($cached)) {
+ $this->copy($cached, $originalPDF);
+ } else {
+ $pdftk = new cubeCommandLine('pdftk');
+ $pdftk->setPath(CONVERTER_PATH);
+ $pdftk->setManualArg($args);
+ $pdftk->execute();
+ $this->copy($normalPDF, $cached);
+ }
+ }
+ }
+
+
+ if ($book->parametres->pdfReplace) {
+ $replace = WS_BOOKS . '/working/' . $book->book_id . '/' . $book->parametres->pdfReplace;
+ if (file_exists($replace)) {
+ if (!file_exists($normalPDF) || filemtime($normalPDF) < filemtime($replace) || filesize($normalPDF) != filesize($replace)) {
+ $this->copy($replace, $normalPDF);
+ }
+ }
+ } else {
+ $this->copy($originalPDF, $normalPDF);
+ }
+ $finalPDF = WS_BOOKS . '/final/' . $book->book_id . '/data/' . $book->parametres->pdfName;
+
+ if ($book->parametres->pdfCompress) {
+ if (!file_exists($compressedPDF) || filemtime($compressedPDF) < filemtime($normalPDF)) {
+ $gs = new cubeCommandLine('gs', null, true);
+ $gs->setPath(CONVERTER_PATH);
+ $gs->setEnv('GS_FONTPATH', '/home/ws/fonts');
+ $gs->setArg('-dBATCH');
+ $gs->setArg('-dNOPAUSE');
+ $gs->setArg('-dNOPROMPT');
+ $gs->setArg('-sOutputFile=' . $compressedPDF);
+ $gs->setArg('-sDEVICE=pdfwrite');
+ $gs->setArg('-dPDFSETTINGS=/ebook');
+ $gs->setArg('-dColorImageResolution=72');
+ $gs->setArg('-dAutoRotatePages=/None');
+ $gs->setArg('-dColorConversionStrategy=/LeaveColorUnchanged');
+ $gs->setArg(null, $normalPDF);
+ $gs->execute();
+ }
+ copy($compressedPDF, $finalPDF);
+ } else {
+ copy($normalPDF, $finalPDF);
+ }
+ }
+
+ public function generateCID()
+ {
+
+ do {
+ $res = '';
+ for ($i = 0; $i < 8; $i++) {
+ $j = rand(0, 61);
+ $res .= $this->base62($j);
+ }
+ $r = $this->con->select('SELECT book_id FROM books WHERE cid=\'' . $res . '\'');
+ if ($r->count() == 0) {
+ return $res;
+ }
+ } while (true);
+ }
+
+ protected function base62($val)
+ {
+ $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ $base = strlen($chars);
+ $str = '';
+ do {
+ $i = $val % $base;
+ $str = $chars[$i] . $str;
+ $val = ($val - $i) / $base;
+ } while ($val > 0);
+ return $str;
+ }
}
<?php
-class wsBookParametres extends wsParametres {
-
- public function __construct($parent) {
- parent::__construct($parent);
- }
-
- /**
- * wsBookParametres::initFields()
- *
- * @return
- */
- protected function initFields() {
- parent::initFields();
- // if (is_null($this->parent)) {
- // return;
- // }
-
- // .
- $swfFilter = new stdClass();
- $swfFilter->name = __('Animation SWF') . ' (*.swf)';
- $swfFilter->extensions = '*.swf';
-
- $multimediaFilter = new stdClass();
- $multimediaFilter->name = __('Archive ZIP') . ' (*.zip)';
- $multimediaFilter->extensions = '*.zip';
-
- $pdfFilter = new stdClass();
- $pdfFilter->name = __('Document PDF') . ' (*.pdf)';
- $pdfFilter->extensions = '*.pdf';
-
- $basketFilter = new stdClass();
- $basketFilter->name = __('Liste de produits') . ' (*.xml, *.xlsx)';
- $basketFilter->extensions = '*.xml;*.xlsx';
-
- $imageFilter = new stdClass();
- $imageFilter->name = __('Images') . ' (*.jpg, *.png)';
- $imageFilter->extensions = '*.jpg;*.jpeg;*.png';
-
- $epsFilter = new stdClass();
- $epsFilter->name = __('Fichier vectoriel') . ' (*.ai, *.eps)';
- $epsFilter->extensions = '*.ai;*.eps';
-
- $svgFilter = new stdClass();
- $svgFilter->name = __('Fichier SVG') . ' (*.svg)';
- $svgFilter->extensions = '*.svg';
-
- $imageExtraFilter = new stdClass();
- $imageExtraFilter->name = __('Images') . ' (*.svg, *.jpg, *.png, *.gif)';
- $imageExtraFilter->extensions = '*.svg;*.jpg;*.png;*.gif';
-
- $soundFilter = new stdClass();
- $soundFilter->name = __('Fichier sonore') . ' (*.mp3, *.wav)';
- $soundFilter->extensions = '*.mp3;*.wav';
-
- $branches = array('master : git (stable)' => 'stable',
- 'master : local (dev)' => 'dev');
- $gitbranches = json_decode(file_get_contents(WS_CACHE . '/activebranches'));
- foreach ($gitbranches as $b) {
- if ($b == 'master') {
- continue;
- }
- $branches[$b . ' : git'] = $b . '|git';
- $branches[$b . ' : local'] = $b . '|local';
- }
- $extraVisibility = [
- __('Navigation horizontale') => 'horizontal',
- __('Navigation burger') => 'burger',
- __('Navigations horizontale et burger') => 'both'];
-
- $extraType = [
- __('Icône + Label') => 'icon',
- __('Image') => 'image'];
-
- $this->fields['mobileLVersion'] = array('type' => 'combo', 'default' => 'stable', 'editable' => true,
- 'label' => __('Version logicielle'), 'grade' => 1,
- 'datas' => $branches
- );
- $this->fields['mobileVersion'] = array('type' => 'combo', 'default' => 'html5-desktop', 'editable' => true, 'label' => __('Version mobile'), 'grade' => 3,
- 'datas' => array(__('Rediriger vers le PDF') => 'pdf',
- __('Version HTML5 recommandée (vecteurs sur desktop)') => 'html5-desktop',
- __('Version HTML5 vecteurs') => 'html5',
- __("Version HTML5 en images") => 'html5-images')
- );
-
- $this->fields['version'] = array('type' => 'combo', 'default' => '2', 'editable' => true, 'label' => __('Version'), 'datas' => array('1' => '1', '2' => '2'), 'grade' => 3);
- $this->fields['title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de la publication"), 'embed' => false);
- $this->fields['url_link'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du lien de retour au site"));
- $this->fields['signature'] = array('type' => 'combo', 'default' => '1', 'editable' => true, 'label' => __('Signature'), 'grade' => 3, 'datas' => wsDroits::getSignatures());
- $this->forms['important'] = array('label' => __('Description de la publication'),
- 'fieldsnames' => array('version', 'mobileLVersion', 'mobileVersion', 'title', 'url_link', 'signature'));
- // .
- // .
-
- $this->fields['email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
- $this->fields['email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
- $this->fields['email_editable'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Permettre au lecteur de modifier le corps de l'email"));
- $this->fields['askAcknowledge'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Demander au destinataire un accusé de réception"), 'grade' => 3);
- $this->fields['sendasfluidbook'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail comme Fluidbook"), 'grade' => 3, 'hint' => __("L'expéditeur apparaîtra en reply-to"));
- $this->fields['email_mailto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail via le client mail du visiteur (mailto:)"), 'grade' => 3);
-
- $this->fields['facebook_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre du contenu partagé"), 'hint' => __('Titre proposé sur les fonction de partage (par défaut, titre de la publication)'));
- $this->fields['facebook_description'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Description du contenu partagé"), 'grade' => 1, 'hint' => __('Description proposée sur les fonctions de partage (par défaut, vide)'));
- $this->fields['twitter_description'] = array('type' => 'textarea', 'default' => '%title% : %short%', 'editable' => true, 'label' => __("Contenu Partage court"), 'hint' => __('Contenu du partagé sur les partages courts'));
- $this->fields['facebook_image'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Miniature affichée'), 'fileFilter' => $imageFilter);
-
- $this->fields['share'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les fonctions de partage'));
- $this->fields['friend'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('E-mail'));
- $this->fields['facebook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Facebook'));
- $this->fields['twitter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Twitter'));
- $this->fields['googleplus'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Google +'));
- $this->fields['linkedin'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('LinkedIn'));
- $this->fields['viadeo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Viadeo'));
- $this->fields['customSharer'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Classe personnalisée de partage"), 'grade' => 5);
- $this->fields['friendWidth'] = array('type' => 'integer', 'default' => 319, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
- $this->fields['friendHeight'] = array('type' => 'integer', 'default' => 500, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
- $this->forms['share'] = array('label' => __('Fonctions de partage'),
- 'fieldsnames' => array('share', '|', 'email_title', 'email_body', 'email_editable', 'askAcknowledge', 'sendasfluidbook', 'email_mailto', '|',
- 'facebook_title', 'facebook_description', 'facebook_image', 'twitter_description', '|',
- 'friend', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo', '|', 'customSharer', '|', 'friendWidth', 'friendHeight'));
- // .
- $this->fields['pages'] = array('type' => 'integer', 'default' => '', 'editable' => false, 'label' => __('Nombre de pages'));
- $this->fields['width'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Largeur'));
- $this->fields['height'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Hauteur'));
- // .
- $this->fields['visualisationMode'] = array('type' => 'combo', 'default' => '3', 'editable' => true, 'label' => __("Mode de visualisation 3D"),
- 'datas' => array(__('Mode 3D') => '0',
- __('Mode 2D (caméra fixe et pages à plat)') => '1',
- __("Laisser le choix à l'utilisateur (mode 3D par défaut)") => '2',
- __("Laisser le choix à l'utilisateur (mode 2D par défaut)") => '3'));
- $this->fields['viewMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de visualisation (beta)"),
- 'datas' => array(__('Classique') => '0',
- __("Diaporama") => '1'), 'grade' => 5);
- $this->fields['antialiasReading'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Amélioration de la lisibilité en mode 2D"));
- $this->fields['pagesBaseAngle'] = array('type' => 'integer', 'default' => '2', 'editable' => true, 'label' => __('Angle de base entre les pages'), 'grade' => 3,
- 'hint' => __("0 : Publication à plat") . "\n" . __('2 : Valeur par défaut'));
- $this->fields['extraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
- $this->fields['extraYSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire verticale'), 'grade' => 3);
- $this->fields['centerBook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Centrer la publication sur les couvertures'), 'grade' => 2);
- $this->fields['correctCenter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Corriger les lignes blanches entre les pages'), 'grade' => 2);
- $this->fields['maxResolution'] = array('type' => 'combo', 'default' => 300, 'editable' => true, 'datas' => array('300dpi' => 300, '150dpi' => 150), 'grade' => 2, 'label' => __('Résolution maximale des pages'));
- $this->forms['3d_mode'] = array('label' => __('Options de visualisation'),
- 'fieldsnames' => array('visualisationMode', 'antialiasReading', 'correctCenter', 'pagesBaseAngle', 'centerBook', '|', 'extraXSpace', 'extraYSpace', '|', 'viewMode', '|', 'maxResolution'));
-
- $this->fields['preload'] = array('type' => 'integer', 'default' => 16, 'editable' => true, 'label' => __('Nombre de pages à précharger'), 'grade' => 3);
-
- $this->fields['navOrder'] = array('type' => 'textarea', 'default' => 'index, chapters, search, print, friend, bookmark, pdf, archives, basket, fullscreen, sound, 3d, extra, extra1, extra2, extra3, extra4, extra5, help, lang', 'editable' => true, 'label' => __('Ordre des icônes dans la nav'), 'grade' => 3);
- $this->fields['tooltipTimer'] = array('type' => 'float', 'default' => 3, "editable" => true, 'label' => __("Temps maximum d'apparition des infos-bulles (en secondes)"));
-
-
- $this->forms['general'] = array('label' => __('Fonctionnalités générales'),
- 'fieldsnames' => array('navOrder', 'tooltipTimer', 'preload', 'pages', 'width', 'height'));
- //.
- //
-
- $this->forms['menu'] = array('label' => __('Menu'), 'fieldsnames' => ['afterSearchDisplayForHTML', '|']);
- $this->fields['afterSearchDisplayForHTML'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher l\'image après le moteur de recherche sur la version HTML5'), 'grade' => 1);
- $extraNum = 5;
- for ($i = 0; $i <= $extraNum; $i++) {
- if ($i > 0) {
- $j = $i;
- $this->fields['navExtraIcon' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Icône supplémentaire') . ' ' . $j, 'fileFilter' => $imageExtraFilter);
- $this->fields['navExtraType' . $j] = array('type' => 'combo', 'datas' => $extraType, 'default' => 'icon', 'editable' => true, 'label' => __('Type'));
- $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL") . ' ' . $j);
- $this->fields['navExtraVisibility' . $j] = array('type' => 'combo', 'datas' => $extraVisibility, 'default' => 'both', 'editable' => true, 'label' => __("Visible") . ' ' . $j);
- $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraIcon' . $j, 'navExtraType' . $j, 'navExtraLink' . $j, 'navExtraVisibility' . $j, '|']);
- } else {
- $j = '';
- $this->fields['navExtraImage' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour navigation'), 'fileFilter' => $imageExtraFilter);
- $this->fields['navExtraImageMobile' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour mobile'), 'fileFilter' => $imageExtraFilter);
- $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL"));
- $this->fields['navExtraTooltip' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Infobulle ou label"));
- $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraImage' . $j, 'navExtraImageMobile' . $j, 'navExtraLink' . $j, 'navExtraTooltip' . $j, '|']);
- }
- }
-
-
- $this->fields['landingPage'] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Landing Page content'), 'grade' => 3);
- $this->forms['landing'] = array('label' => __('Custom Landing Page'), 'fieldsnames' => array('landingPage'));
-
-
- $this->fields['fullscreen'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le mode plein-écran'));
- $this->fields['fullscreenAuto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Lancer la publication en mode plein écran (lorsque possible)'));
- $this->forms['fs'] = array('label' => __('Plein écran'),
- 'fieldsnames' => array('fullscreen', 'fullscreenAuto'));
-
-
- $this->fields['bookmark'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les marques-pages'));
- $this->fields['bookmarkSendEnable'] = array('type' => 'boolean', 'default' => 'true', 'editable' => true, 'label' => __("Activer l'envoi des marques-pages par e-mail"));
- $this->fields['bookmark_email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
- $this->fields['bookmark_email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
- $this->fields['bookmarkCornerSize'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __("Taille des marques-pages"), 'hint' => __('Taille relative à la largeur de la page'));
- $this->fields['bookmarkOffset'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Décaler de x pixels vers l'intérieur"));
- $this->fields['bookmarkBlinkOnPageChange'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Faire clignoter le marque page à l\'apparition de la page'));
- $this->fields['bookmarkUsePDF'] = array('type' => 'combo', 'default' => 'pages', 'editable' => true, 'label' => __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'),
- 'datas' => [__('PDF des pages') => 'pages',
- __('PDF de remplacement') => 'download',
- __('PDF des miniatures') => 'thumbnails']);
- $this->forms['bookmark'] = array('label' => __('Marques-pages'),
- 'fieldsnames' => array('bookmark', '|', 'bookmarkSendEnable', 'bookmark_email_title', 'bookmark_email_body', '|', 'bookmarkCornerSize', 'bookmarkOffset', 'bookmarkBlinkOnPageChange', 'bookmarkUsePDF'));
-
- $this->fields['help'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'aide"));
- $this->fields['helpBookmarks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Améliorer l'aide des marques-pages"));
- $this->fields['helpStartup'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher l'aide au démarrage"));
- $this->fields['helpStartupTime'] = array('type' => 'integer', 'default' => 15, 'editable' => true, 'label' => __("Temps d'affichage en secondes"));
- $this->fields['helpArrowTooltip'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Bulle affichée au niveau de la flèche de droite'), 'grade' => 5);
- $this->forms['help'] = array('label' => __('Aide'),
- 'fieldsnames' => array('help', '|', 'helpStartup', 'helpStartupTime', '|', 'helpBookmarks', '|', 'helpArrowTooltip'));
- // .
- //
- $this->fields['indexAutoScroll'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le scroll automatique'));
- $this->fields['pdfThumbnails'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('PDF utilisé pour générer les miniatures'), 'grade' => 1, 'fileFilter' => $pdfFilter);
-
- $this->forms['index'] = array('label' => __('Index'), 'fieldsnames' => array('indexAutoScroll', 'pdfThumbnails'));
-
- // .
- //
- $this->fields['print'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'impression"));
- $this->fields['printMode'] = array('type' => 'combo', 'default' => 'vector', 'editable' => true, 'label' => __("Mode d'impression"),
- 'datas' => array(__('Bitmap') => 'bitmap',
- __('Vectoriel') => 'vector',
- __('PDF') => 'pdf'));
- $this->fields['printCoverWithMarks'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Imprimer les couvertures avec les pages marquées"), 'grade' => 3);
- $this->forms['print'] = array('label' => __('Impression'),
- 'fieldsnames' => array('print', 'printMode', 'printCoverWithMarks'));
-
-
- $this->fields['search'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le moteur de recherche'));
- $this->fields['highlightResults'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Surligner les résultats'));
- $this->fields['highlightAllOccurences'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Surligner toutes les occurences'), 'hint' => __('Même sur les pages non considérées comme un résultat'));
- $this->fields['ignoreSearch'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Mots à ignorer'),
- 'hint' => __('Liste des mots à ignorer séparés par des virgules'), 'grade' => 5);
- $this->fields['ignoreSearchSeparators'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Caractères à ne pas considérer comme un séparateur de mot'));
- $this->fields['ignoreWordLimit'] = ['type' => 'integer', 'default' => 3, 'editable' => true, 'label' => __('Ignorer les mots de moins de X caractères')];
- $this->fields['textExtraction'] = array('type' => 'combo', 'default' => 'pdfbox', 'editable' => true, 'label' => __("Méthode d'extraction des textes"),
- 'datas' => array(__('PDFBox') => 'pdfbox',
- __('Poppler') => 'poppler',
- __('Fluidbook (expérimentation basée sur PDFBox)') => 'fluidbook'));
- $this->fields['searchShowNoResultsPages'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher les pages sans résultats"));
- $this->fields['searchPageSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'AND',
- 'datas' => [__('les double-pages qui contiennent tous les mots recherchés (ET logique)') => 'AND', __('les double-page qui contiennent un des mots recherché (OU logique)') => 'OR'], 'label' => __('Algorithme de sélection des résultats'));
- $this->fields['searchWordSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'begins',
- 'datas' => [__('mot commençant par la requête') => 'begins', __('mot correspondant exactement à la requête') => 'exact', __('mot contenant la requête') => 'contains'],
- 'label' => __('Algorithme de sélection des occurences'));
-
- $this->forms['search'] = array('label' => __('Moteur de recherche'),
- 'fieldsnames' => array('search', '|', 'ignoreWordLimit', 'ignoreSearch', 'ignoreSearchSeparators',
- '|', 'searchWordSelectionAlgorithm', 'searchPageSelectionAlgorithm',
- '|', 'highlightResults', 'highlightAllOccurences',
- '|', 'searchShowNoResultsPages',
- '|', 'textExtraction'));
-
- $this->fields['soundTheme'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Thème sonore"),
- 'datas' => array(__('Pas de son') => '',
- __('Classique') => 'classic',
- __("Papier épais") => 'heavy',
- __("Papier fin") => 'light'));
- $this->fields['soundOn'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les effets sonores à l'ouverture"));
- $this->fields['ambientSound'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Ambiance sonore'), 'grade' => 3, 'fileFilter' => $soundFilter);
- $this->fields['ambientSoundVolume'] = array('type' => 'integer', 'default' => 50, 'editable' => true,
- 'label' => __("Volume de l'ambiance sonore"),
- 'min' => 0, 'max' => 100);
- $this->forms['sound'] = array('label' => __('Effets sonores'),
- 'fieldsnames' => array('soundTheme', 'soundOn', '|', 'ambientSound', 'ambientSoundVolume'));
- // .
- $this->fields['pdf'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les fonctions de téléchargement"));
- $this->fields['pdfName'] = array('type' => 'text', 'default' => 'document.pdf', 'editable' => true, 'label' => __("Nom du fichier PDF"));
- $this->fields['pdfComplex'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téchargement de PDF avancé'), "hint" => __("Permet à l'utilisateur de sélectionner les pages qu'il souhaite télécharger"), 'grade' => 3);
- $this->fields['pdfCompress'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Compression du fichier PDF'));
- $this->fields['pdfReplace'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('PDF de remplacement'), 'grade' => 3, 'fileFilter' => $pdfFilter);
- $this->fields['offlineExport'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téléchargement des versions offline'), "hint" => __('Valable si le téléchargement avancé est activé'), 'grade' => 3);
- $this->forms['pdf'] = array('label' => __('Fonction de téléchargement'),
- 'fieldsnames' => array('pdf', 'pdfName', 'pdfReplace', 'pdfCompress', 'pdfComplex', 'offlineExport'));
- // .
- $this->fields['zoomMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de zoom"), 'grade' => 3,
- 'datas' => array(__('Normal') => '0',
- __('Une page') => '1',
- __('Zoom désactivé') => '2'));
- $this->fields['zoom'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Zoom par défaut (atteint au clic)'));
- $this->fields['zoomw'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Zoom maximal (atteint à l'aide de la molette)"));
- $this->forms['zoom'] = array('label' => __('Zoom'),
- 'fieldsnames' => array('zoomMode', '|', 'zoom', 'zoomw'));
- // .
- $this->fields['stats'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les statistiques Fluidbook'), 'grade' => 3);
- $this->fields['stats_score'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher les scores dans les rapports'), 'grade' => 5);
- $this->fields['stats_exclude_ip'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Exclure les IP suivantes des statistiques'), 'grade' => 3, 'hint' => sprintf(__('Indiquer une adresse ip de la forme %s par ligne'), 'www.xxx.yyy.zzz'));
- $this->fields['googleAnalytics'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Code Google Analytics'), 'size' => 10);
- $this->fields['googleAnalyticsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture de head)'));
- $this->fields['statsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture du body)'));
- $this->fields['xiti'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code XiTi global'));
- $this->fields['xiti_page'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Modèle code xiti (pour tags relatifs aux pages)'));
- $this->forms['stats'] = array('label' => __('Statistiques'),
- 'fieldsnames' => array('stats', 'stats_score', 'stats_exclude_ip', '|', 'googleAnalytics', '|', 'googleAnalyticsCustom', 'statsCustom', '|', 'xiti', 'xiti_page'));
-
- $this->fields['displayChaptersPopup'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Always display chapters in a popup'), 'grade' => 1);
- $this->fields['displayChaptersIcon'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche l'icône du sommaire"), 'grade' => 1);
- $this->fields['displayChaptersLine'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche une ligne entre le label et le numéro de page"), 'grade' => 5);
- $this->fields['chaptersPage'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Faire pointer le sommaire sur la page'), 'grade' => 3, 'hint' => __('Laisser vide pour utiliser le sommaire classique'), 'size' => 5);
- $this->fields['displayChaptersAtStart'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher le sommaire au chargement de la publication"), 'grade' => 3);
- $this->fields['chaptersColumns'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Afficher le sommaire sur x colonne(s)'), 'grade' => 3);
- $this->fields['chaptersColMaxWidth'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Largeur max d'une colonne"), 'grade' => 3);
- $this->fields['chaptersLevelLimit'] = array('type' => 'integer', 'default' => 5, 'editable' => true, 'label' => __('Limiter à x niveaux'));
- $this->fields['externalChapters'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Sommaire personnalisé'), 'grade' => 3, 'fileFilter' => $swfFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
- $this->fields['externalChaptersHTML'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Sommaire personnalisé (HTML5)'), 'grade' => 3, 'fileFilter' => $multimediaFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
- $this->fields['fullExternalChapters'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire totalement personnalisé"), 'grade' => 3, 'hint' => __('Supprime la flèche de fermeture, titre prédéfini et couleur de fond'));
- $this->fields['mobileChaptersStyle'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __('Style des chapîtres') . ' (' . __('version mobile') . ')'
- , 'datas' => array(__('Classique') => 'classic',
- __('INA') => 'ina'));
-
- $this->fields['chaptersPosition'] = array('type' => 'combo', 'default' => 'center', 'editable' => true, 'label' => __("Position du sommaire"),
- 'datas' => array(__('Centré') => 'center',
- __("Aligné sur l'icône") => 'chaptersIcon'));
- $this->fields['chaptersCascade'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire en cascade"), 'grade' => 3);
-
- $this->forms['sommaire'] = array('label' => __('Sommaire'),
- 'fieldsnames' => array('displayChaptersIcon', 'displayChaptersPopup', 'displayChaptersAtStart', 'chaptersPage', 'chaptersPosition', 'chaptersLevelLimit', 'chaptersCascade', '|', 'chaptersColMaxWidth', 'chaptersColumns', 'displayChaptersLine', '|', 'externalChapters', 'fullExternalChapters', '|', 'externalChaptersHTML', '|', 'mobileChaptersStyle'));
- // .
-
- $this->fields['ongletsXML'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('XML de configuration des onglets'), 'grade' => 5);
- $this->fields['ongletsSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('SWF pour onglets personnalisés'), 'grade' => 3, 'fileFilter' => $swfFilter);
-
- $this->fields['tabs2DSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('SWF pour onglets 2D'), 'grade' => 3, 'fileFilter' => $swfFilter);
-
- $this->fields['tabsHTML5'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Onglets HTML5'), 'grade' => 3);
-
- $this->fields['flatTabsAbsolute'] = array('type' => 'boolean', 'default' => false, "editable" => true,
- 'label' => __("Positionnement relatif à l'interface"), 'grade' => 5);
-
- $this->forms['tabs'] = array('label' => __('Onglets'),
- 'fieldsnames' => array('ongletsSWF', 'ongletsXML', '|', 'tabs2DSWF', 'flatTabsAbsolute', '|', 'tabsHTML5'));
-
- $this->fields['customLinkClass'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Classe pour les liens personnalisés'), 'grade' => 5);
- $this->fields['permanentLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Liens visibles en permanence'), 'grade' => 3);
- $this->fields['ignoreLinksTypes'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Ignorer les liens de type'), 'hint' => __('Liste des numéros séparés par des virgules'), 'grade' => 5);
- $this->fields['linkBlinkTime'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __("Temps d'apparition du lien à l'ouverture de la page (en secondes)"));
- $this->fields['linkTooltipManager'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Gestionnaire des info-bulles"), 'grade' => 5);
- $this->fields['linkTracker'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens'), 'grade' => 5);
- $this->fields['linkTrackerRegexp'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens applicables aux liens du domaine'), 'grade' => 5);
- $this->fields['linkFilePrefix'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Préfixer les liens de téléchargement'));
- $this->fields['linkMultimediaPerformanceMode'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Mode perfomance pour les liens multimédia'), 'grade' => 5);
- $this->fields['linkMultimediaQuality'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __('Qualité de rendu des animations'), 'grade' => 5);
- $this->fields['linkCornerSize'] = array('type' => 'integer', 'default' => '10', 'editable' => true, 'label' => __('Taille des liens de coins de page'), 'hint' => __("Pourcentage de la largeur de la page"));
- $this->fields['linkTooltipMaxWidth'] = array('type' => 'integer', 'default' => '140', 'editable' => true, 'label' => __('Largeur max des infobulles des liens de type "infobulle"'));
- $this->fields['videoReset'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Réinitialiser les vidéos après la lecture'), 'grade' => 3);
- $this->fields['videoBigPlay'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher le gros bouton Play'), 'grade' => 3);
- $this->fields['brightcovePlayerId'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Id'), 'grade' => 3);
- $this->fields['brightcovePlayerSecret'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Secret'), 'grade' => 3);
- $this->forms['multimedia'] = array('label' => __('Liens et multimédia'),
- 'fieldsnames' => array('permanentLinks', 'linkBlinkTime', 'customLinkClass', 'ignoreLinksTypes', 'linkTooltipManager', 'linkCornerSize', 'linkTooltipMaxWidth', '|', 'linkTracker', 'linkTrackerRegexp', '|', 'linkFilePrefix', '|', 'linkMultimediaPerformanceMode', 'linkMultimediaQuality', '|', 'videoReset', 'videoBigPlay', '|', 'brightcovePlayerId', 'brightcovePlayerSecret'));
- //.
- $this->fields['externalArchives'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Archives'), 'grade' => 3, 'fileFilter' => $imageFilter);
- $this->fields['externalArchivesBack'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Image de fond'), 'grade' => 3, 'fileFilter' => $imageFilter);
- $this->fields['archivesLink'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Lien'), 'grade' => 5);
- $this->fields['archivesLabel'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Label'), 'grade' => 5);
-
- $this->forms['archives'] = array('label' => __('Archives'),
- 'fieldsnames' => array('externalArchives', 'externalArchivesBack', '|', 'archivesLink', 'archivesLabel'));
- // .
- $this->fields['form'] = array('type' => 'combo', 'default' => '', 'editable' => true, 'grade' => 5, 'label' => __('Formulaire'), 'datas' => array(__('Aucun') => '', __('Bulle Groupe') => 'bulle'));
- $this->forms['form'] = array('label' => __('Formulaire'),
- 'fieldsnames' => array('form'));
-
- $this->fields['cookieConsent'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Message cookie'));
- $this->fields['cookieConsentMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Texte du consentement'));
- $this->fields['cookieConsentAutoclose'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Masquer automatiquement après x secondes'));
- $this->forms['privacy'] = array('label' => __('Respect de la vie privée'),
- 'fieldsnames' => array('cookieConsent', 'cookieConsentMessage', 'cookieConsentAutoclose'));
-
- //.
- $this->fields['basket'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Panier activé'), 'grade' => 5);
- $this->fields['basketManager'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Manager de panier"),
- 'datas' => array(__('Classic') => 'com.fluidbook.player.basket.BasketManager',
- 'Grdf' => 'com.fluidbook.player.basket.custom.grdf.GrdfBasketManager',
- 'Grdf 2013' => 'com.fluidbook.player.basket.custom.grdf.grdf2013.GrdfBasketManager2013',
- 'Grdf 2015' => 'com.fluidbook.player.basket.custom.grdf.grdf2015.GrdfBasketManager2015',
- 'Essilor' => 'com.fluidbook.player.basket.custom.essilor.EssilorBasketManager',
- 'Essilor Recap' => 'com.fluidbook.player.basket.custom.essilorrecap.EssilorRecapBasketManager',
- 'Wesco Ventes' => 'com.fluidbook.player.basket.custom.wesco.WescoBasketManager',
- 'Atlantic Download' => 'com.fluidbook.player.basket.custom.atlantic.AtlanticDownloadBasketManager'
- ), 'grade' => 5);
- $this->fields['basketReferences'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Références produits'), 'grade' => 3, 'fileFilter' => $basketFilter, 'hint' => __('Fichier contenant les références produits'), 'dir' => 'commerce');
- $this->fields['basketImages'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Images des produits'), 'grade' => 5, 'fileFilter' => $imageFilter, 'hint' => __('Chaque image doit avoir pour nom exact la référence du produit'),
- 'multiple' => true, 'dir' => 'commerce');
- $this->fields['basketPDFBackground'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Fond du PDF (bon de commande)'), 'grade' => 5, 'fileFilter' => $epsFilter, 'hint' => __('Fond du bon de commande'), 'dir' => 'commerce');
-
- $this->forms['basket'] = array('label' => __('Panier'),
- 'fieldsnames' => array('basket', 'basketManager', 'basketReferences', 'basketImages', 'basketPDFBackground'));
- // .
- $this->fields['offlineLink'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du Fluidbook"), 'hint' => __('URL du fluidbook utilisée pour la version Offline (CD-ROM, clé USB, Exécutables)'));
- $this->fields['offlineTitle'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'application"));
- $this->forms['offline'] = array('label' => __('Version offline'),
- 'fieldsnames' => array('offlineTitle', 'offlineLink'));
-
- $this->fields['alwaysHTML5'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Toujours utiliser la version HTML5'), 'grade' => 1);
-
- $this->fields['html5priority'] = array('type' => 'combo', 'default' => 'true', 'editable' => true, 'label' => __("Rediriger vers la version HTML5"), 'grade' => 1,
- 'datas' => array(__('Si l\'utilisateur a un appareil tactile') => 'false',
- __('Si flash n\'est pas installé') => 'notinstalled',
- __("Si flash n'est pas pas installé ou bloqué") => 'true'));
-
- $this->fields['flashBlockedWait'] = array('type' => 'float', 'default' => 1.5, 'editable' => true, 'label' => __("Temps d'attente avant de considérer flash comme bloqué"));
-
-
- $this->fields['navOrderH'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ordre des icônes dans la nav') . ' (' . __('Si différente') . ')', 'grade' => 3);
-
- $this->fields['menuBreakpoint'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Breakpoint burger menu'), 'hint' => 'Par défaut 1023px', 'grade' => 3);
-
-
- $this->fields['mobileTransitions'] = array('type' => 'combo', 'default' => 'flip', 'editable' => true, 'label' => __('Transitions entre les pages'), 'grade' => 3,
- 'datas' => array(__('Aucune transition') => 'none',
- __('Glisser') => 'slide',
- __('Tourner') => 'flip')
- );
- $this->fields['mobileNavigationType'] = array('type' => 'combo', 'default' => 'book', 'editable' => true, 'label' => __('Mode de navigation'), 'grade' => 5,
- 'datas' => array(__('Normal (automatique)') => 'book',
- __('Normal (double page)') => 'landscape',
- __('Normal (une page)') => 'portrait',
- __('Magazine tablette') => 'tab')
- );
- $this->fields['rasterizePages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ecraser les pages'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
- $this->fields['vectorPages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Conserver les pages en vecteur'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
-
-
- $this->fields['mobileTransitionDuration'] = array('type' => 'float', 'default' => '0.75', 'editable' => true, 'label' => __('Durée de la transition'));
- $this->fields['mobileLinksRevealAnim'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Animer les liens après un changement de page"), 'grade' => 3);
-
- $this->fields['mobileIconVector'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Utiliser les icônes vectorielles'));
- $this->fields['mobileServerConfig'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Inclure les fichiers de configuration serveur'), 'grade' => 3);
-
- $this->fields['mobilePlugins'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Plugin'), 'grade' => 5);
-
- $this->fields['mobileVideosPath'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Chemin vers les vidéos'), 'grade' => 5);
- $this->fields['mobileExtraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
- $this->fields['mobileNavScale'] = array('type' => 'integer', 'default' => '100', 'editable' => true, 'label' => __('Taille du menu (en %)'), 'grade' => 3);
-
- $this->fields['mobileIgnoreBackgroundLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Ignorer les liens de background'));
-
- $this->forms['mobile'] = array('label' => __('Version mobile'),
- 'fieldsnames' => array('alwaysHTML5', 'html5priority', 'flashBlockedWait', 'mobileNavigationType', '|', 'rasterizePages', 'vectorPages', '|', 'mobileNavScale', '|', 'mobileTransitions', 'mobileTransitionDuration', "mobileLinksRevealAnim", '|', 'menuBreakpoint', 'navOrderH', '|', 'mobileIconVector', 'mobileServerConfig', 'mobilePlugins', '|', 'mobileVideosPath', '|', 'mobileExtraXSpace', '|', 'mobileIgnoreBackgroundLinks'));
-
-
- $this->fields['phonegapId'] = array('type' => 'text', 'default' => 'com.fluidbook.phonegap.$id', 'editable' => true, 'label' => __("Identifiant de l'identifiant"), 'grade' => 5, 'hint' => __('De la forme') . ' com.fluidbook.phonegap.xxxxx');
- $this->fields['phonegapVersion'] = array('type' => 'text', 'default' => '1.0.0', 'editable' => true, 'label' => __("Version de l'application"), 'grade' => 5, 'hint' => __('De la forme') . ' 1.2.3');
- $this->fields['phonegapPlugins'] = array('type' => 'textarea', 'default' => 'ChildBrowser', 'editable' => true, 'label' => __('Plugins Phonegap'), 'grade' => 5);
- $defaultScreenshots = "P,0\nL,2\nL,index";
- $this->fields['appScreenshots'] = array('type' => 'textarea', 'default' => $defaultScreenshots, 'editable' => true, 'label' => 'Générer les screenshots', 'grade' => 5, 'hint' => __('Une ligne par vue à générer de la forme X,Y (X : P(ortrait) ou L(andscape), Y : numéro de page ou vue (1, index))'));
-
- $this->forms['phonegap'] = array('label' => __('Applications mobile'),
- 'fieldsnames' => array('phonegapId', 'phonegapVersion', 'phonegapPlugins', 'appScreenshots'));
-
- $this->fields['secureURL'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('URL de sécurisation'), 'grade' => 5, 'hint' => __('URL intérrogé pour vérifier si le visiteur à les droits pour consulter la publication'));
- $this->fields['secureURLRedirect'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('Redirection'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
- $this->fields['preventRightClick'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Essayer d'empêcher le clic droit"), 'grade' => 1);
- $this->forms['secure'] = array('label' => __('Sécurisation'),
- 'fieldsnames' => array('secureURL', 'secureURLRedirect', '|', 'preventRightClick'));
-
- $this->fields['seoVersion'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Générer une version pour les moteurs de recherche'));
- $this->fields['seoRobots'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Autoriser le parcours par les moteurs de recherche'));
- $this->fields['seoDescription'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Description'));
- $this->fields['seoKeywords'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Keywords'));
-
- $this->forms['seo'] = array('label' => __('Optimisation pour les moteurs de recherche'),
- 'fieldsnames' => array('seoVersion', 'seoRobots', 'seoDescription', "seoKeywords"));
-
- $this->fields['home'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Accueil de l'interface multibrochure"), 'grade' => 5);
- $this->fields['multilang'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Langues'), 'hint' => __('Code langue') . ',' . __('Code pays') . ',' . __('URL'));
- $this->fields['country'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Pays de la brochure'));
- $this->fields['multilangDisplay'] = array('type' => 'combo', 'default' => 'lang', 'editable' => true, 'label' => __('Affichage'),
- 'datas' => array(__('Langue') => 'lang',
- __('Langue') . ' (' . __('Pays') . ')' => 'lang_country',
- __('Pays') . ' (' . __('Langue') . ')' => 'country_lang'));
- $this->forms['multibrochure'] = array('label' => __('Multibrochure'),
- 'fieldsnames' => array('home', 'country', 'multilangDisplay', 'multilang'));
-
- $this->fields['plv'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le mode PLV'), 'grade' => 3);
- $this->fields['plvTimer'] = array('type' => 'integer', 'min' => 1, 'max' => 60, 'default' => 5, 'editable' => true, 'label' => __('Temps'), 'grade' => 3);
- $this->fields['plvMode'] = array('type' => 'combo', 'default' => 'first', 'editable' => true, 'label' => __('Arrivé à la dernière page'), 'grade' => 3,
- 'datas' => array(__('Remonter vers la première page') => 'back',
- __('Recommencer à la première page') => 'first'));
- $this->forms['plv'] = array('label' => __('Mode PLV'),
- 'fieldsnames' => array('plv', 'plvTimer', 'plvMode'));
-
- $this->fields['widget'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Générer le widget'), 'grade' => 3);
- $this->fields['widgetCover'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher la couverture') . ')', 'grade' => 3);
- $this->fields['widgetSize'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Optimiser pour une hauteur de (en pixels)'), 'grade' => 3);
- $this->fields['widgetQuality'] = array('type' => 'integer', 'default' => 85, 'min' => 0, 'max' => 100, 'editable' => true, 'label' => __('Qualité JPEG'), 'grade' => 3);
- $this->fields['widgetStart'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Page de début'), 'grade' => 3);
- $this->fields['widgetEnd'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __('Page de fin'), 'grade' => 3);
- $this->forms['widget'] = array('label' => __('Widget') . ' (' . __('Mini Fluidbook') . ')',
- 'fieldsnames' => array('widget', 'widgetCover', 'widgetSize', 'widgetQuality', 'widgetStart', 'widgetEnd'));
-
- $this->fields['extras'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Extras'), 'grade' => 3);
- $this->fields['v1SWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
- 'label' => __('Index.swf spécifique'), 'grade' => 5, 'fileFilter' => $swfFilter);
- $this->forms['v1'] = array('label' => __('Options spécifiques au fluidbook version 1'),
- 'fieldsnames' => array('extras', 'v1SWF'));
-
- $this->fields['themeEnableAfterSearch'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Afficher l'image supplémentaire à droite du moteur de recherche"), 'grade' => 3);
- $this->forms['theme'] = array('label' => __('Options du thème'),
- 'fieldsnames' => array('themeEnableAfterSearch'));
-
- $this->fields['forceCompileOnDownload'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Forcer la compilation lors du téléchargement'), 'grade' => 3);
- $this->fields['htmlExtension'] = array('type' => 'text', 'default' => 'html', 'editable' => true, 'label' => __('Extension des fichiers html'), 'grade' => 5, 'hint' => __('Ex : php, htm, html, phtml, asp'), 'grade' => 5);
- $this->fields['htmlPrepend'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code à insérer en tête des fichiers'), 'grade' => 5);
- $this->fields['baseUrl'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Base de l\'url'), 'grade' => 5, 'grade' => 5);
-
- $this->forms['package'] = array('label' => __('Option d\'export'),
- 'fieldsnames' => array('htmlExtension', 'htmlPrepend', 'baseUrl', 'forceCompileOnDownload'));
-
- $this->fields['disableDemo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Désactiver le lien de démo'), 'grade' => 5);
- $this->fields['redirectDemo'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Rediriger le lien de démo vers'), 'grade' => 5);
- $this->forms['demo'] = array('label' => __('Lien de démo'),
- 'fieldsnames' => array('disableDemo', 'redirectDemo'));
-
-
- $this->fields['scorm_enable'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer SCORM'), 'grade' => 5);
- $this->fields['scorm_id'] = array('type' => 'text', 'default' => 'MFMCTE091mobile', 'editable' => true, 'label' => __('Identifiant SCORM'), 'grade' => 5);
- $this->fields['scorm_org'] = array('type' => 'text', 'default' => 'ACME-ORG-1350650111249', 'editable' => true, 'label' => __('Organisation SCORM'), 'grade' => 5);
- $this->fields['scorm_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Titre SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
- $this->fields['scorm_variables'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Variables SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
-
- $this->forms['scorm'] = array('label' => __('SCORM'),
- 'fieldsnames' => array('scorm_enable', 'scorm_id', 'scorm_org', 'scorm_title', 'scorm_variables'));
- }
+class wsBookParametres extends wsParametres
+{
+
+ public function __construct($parent)
+ {
+ parent::__construct($parent);
+ }
+
+ /**
+ * wsBookParametres::initFields()
+ *
+ * @return
+ */
+ protected function initFields()
+ {
+ parent::initFields();
+ // if (is_null($this->parent)) {
+ // return;
+ // }
+
+ // .
+ $swfFilter = new stdClass();
+ $swfFilter->name = __('Animation SWF') . ' (*.swf)';
+ $swfFilter->extensions = '*.swf';
+
+ $multimediaFilter = new stdClass();
+ $multimediaFilter->name = __('Archive ZIP') . ' (*.zip)';
+ $multimediaFilter->extensions = '*.zip';
+
+ $pdfFilter = new stdClass();
+ $pdfFilter->name = __('Document PDF') . ' (*.pdf)';
+ $pdfFilter->extensions = '*.pdf';
+
+ $basketFilter = new stdClass();
+ $basketFilter->name = __('Liste de produits') . ' (*.xml, *.xlsx)';
+ $basketFilter->extensions = '*.xml;*.xlsx';
+
+ $imageFilter = new stdClass();
+ $imageFilter->name = __('Images') . ' (*.jpg, *.png)';
+ $imageFilter->extensions = '*.jpg;*.jpeg;*.png';
+
+ $epsFilter = new stdClass();
+ $epsFilter->name = __('Fichier vectoriel') . ' (*.ai, *.eps)';
+ $epsFilter->extensions = '*.ai;*.eps';
+
+ $svgFilter = new stdClass();
+ $svgFilter->name = __('Fichier SVG') . ' (*.svg)';
+ $svgFilter->extensions = '*.svg';
+
+ $imageExtraFilter = new stdClass();
+ $imageExtraFilter->name = __('Images') . ' (*.svg, *.jpg, *.png, *.gif)';
+ $imageExtraFilter->extensions = '*.svg;*.jpg;*.png;*.gif';
+
+ $soundFilter = new stdClass();
+ $soundFilter->name = __('Fichier sonore') . ' (*.mp3, *.wav)';
+ $soundFilter->extensions = '*.mp3;*.wav';
+
+ $branches = array('master : git (stable)' => 'stable',
+ 'master : local (dev)' => 'dev');
+ $gitbranches = json_decode(file_get_contents(WS_CACHE . '/activebranches'));
+ foreach ($gitbranches as $b) {
+ if ($b == 'master') {
+ continue;
+ }
+ $branches[$b . ' : git'] = $b . '|git';
+ $branches[$b . ' : local'] = $b . '|local';
+ }
+ $extraVisibility = [
+ __('Navigation horizontale') => 'horizontal',
+ __('Navigation burger') => 'burger',
+ __('Navigations horizontale et burger') => 'both'];
+
+ $extraType = [
+ __('Icône + Label') => 'icon',
+ __('Image') => 'image'];
+
+ $this->fields['mobileLVersion'] = array('type' => 'combo', 'default' => 'stable', 'editable' => true,
+ 'label' => __('Version logicielle'), 'grade' => 1,
+ 'datas' => $branches
+ );
+ $this->fields['mobileVersion'] = array('type' => 'combo', 'default' => 'html5-desktop', 'editable' => true, 'label' => __('Version mobile'), 'grade' => 3,
+ 'datas' => array(__('Rediriger vers le PDF') => 'pdf',
+ __('Version HTML5 recommandée (vecteurs sur desktop)') => 'html5-desktop',
+ __('Version HTML5 vecteurs') => 'html5',
+ __("Version HTML5 en images") => 'html5-images')
+ );
+
+ $this->fields['version'] = array('type' => 'combo', 'default' => '2', 'editable' => true, 'label' => __('Version'), 'datas' => array('1' => '1', '2' => '2'), 'grade' => 3);
+ $this->fields['title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de la publication"), 'embed' => false);
+ $this->fields['url_link'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du lien de retour au site"));
+ $this->fields['signature'] = array('type' => 'combo', 'default' => '1', 'editable' => true, 'label' => __('Signature'), 'grade' => 3, 'datas' => wsDroits::getSignatures());
+ $this->forms['important'] = array('label' => __('Description de la publication'),
+ 'fieldsnames' => array('version', 'mobileLVersion', 'mobileVersion', 'title', 'url_link', 'signature'));
+ // .
+ // .
+
+ $this->fields['email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+ $this->fields['email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+ $this->fields['email_editable'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Permettre au lecteur de modifier le corps de l'email"));
+ $this->fields['askAcknowledge'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Demander au destinataire un accusé de réception"), 'grade' => 3);
+ $this->fields['sendasfluidbook'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail comme Fluidbook"), 'grade' => 3, 'hint' => __("L'expéditeur apparaîtra en reply-to"));
+ $this->fields['email_mailto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Envoyer le mail via le client mail du visiteur (mailto:)"), 'grade' => 3);
+
+ $this->fields['facebook_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre du contenu partagé"), 'hint' => __('Titre proposé sur les fonction de partage (par défaut, titre de la publication)'));
+ $this->fields['facebook_description'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Description du contenu partagé"), 'grade' => 1, 'hint' => __('Description proposée sur les fonctions de partage (par défaut, vide)'));
+ $this->fields['twitter_description'] = array('type' => 'textarea', 'default' => '%title% : %short%', 'editable' => true, 'label' => __("Contenu Partage court"), 'hint' => __('Contenu du partagé sur les partages courts'));
+ $this->fields['facebook_image'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Miniature affichée'), 'fileFilter' => $imageFilter);
+
+ $this->fields['share'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les fonctions de partage'));
+ $this->fields['friend'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('E-mail'));
+ $this->fields['facebook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Facebook'));
+ $this->fields['twitter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Twitter'));
+ $this->fields['googleplus'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Google +'));
+ $this->fields['linkedin'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('LinkedIn'));
+ $this->fields['viadeo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Viadeo'));
+ $this->fields['customSharer'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Classe personnalisée de partage"), 'grade' => 5);
+ $this->fields['friendWidth'] = array('type' => 'integer', 'default' => 319, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
+ $this->fields['friendHeight'] = array('type' => 'integer', 'default' => 500, 'editable' => true, 'label' => __('Largeur du menu'), 'grade' => 5);
+ $this->forms['share'] = array('label' => __('Fonctions de partage'),
+ 'fieldsnames' => array('share', '|', 'email_title', 'email_body', 'email_editable', 'askAcknowledge', 'sendasfluidbook', 'email_mailto', '|',
+ 'facebook_title', 'facebook_description', 'facebook_image', 'twitter_description', '|',
+ 'friend', 'facebook', 'twitter', 'googleplus', 'linkedin', 'viadeo', '|', 'customSharer', '|', 'friendWidth', 'friendHeight'));
+ // .
+ $this->fields['pages'] = array('type' => 'integer', 'default' => '', 'editable' => false, 'label' => __('Nombre de pages'));
+ $this->fields['width'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Largeur'));
+ $this->fields['height'] = array('type' => 'float', 'default' => '', 'editable' => false, 'label' => __('Hauteur'));
+ // .
+ $this->fields['visualisationMode'] = array('type' => 'combo', 'default' => '3', 'editable' => true, 'label' => __("Mode de visualisation 3D"),
+ 'datas' => array(__('Mode 3D') => '0',
+ __('Mode 2D (caméra fixe et pages à plat)') => '1',
+ __("Laisser le choix à l'utilisateur (mode 3D par défaut)") => '2',
+ __("Laisser le choix à l'utilisateur (mode 2D par défaut)") => '3'));
+ $this->fields['viewMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de visualisation (beta)"),
+ 'datas' => array(__('Classique') => '0',
+ __("Diaporama") => '1'), 'grade' => 5);
+ $this->fields['antialiasReading'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Amélioration de la lisibilité en mode 2D"));
+ $this->fields['pagesBaseAngle'] = array('type' => 'integer', 'default' => '2', 'editable' => true, 'label' => __('Angle de base entre les pages'), 'grade' => 3,
+ 'hint' => __("0 : Publication à plat") . "\n" . __('2 : Valeur par défaut'));
+ $this->fields['extraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
+ $this->fields['extraYSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire verticale'), 'grade' => 3);
+ $this->fields['centerBook'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Centrer la publication sur les couvertures'), 'grade' => 2);
+ $this->fields['correctCenter'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Corriger les lignes blanches entre les pages'), 'grade' => 2);
+ $this->fields['maxResolution'] = array('type' => 'combo', 'default' => 300, 'editable' => true, 'datas' => array('300dpi' => 300, '150dpi' => 150), 'grade' => 2, 'label' => __('Résolution maximale des pages'));
+ $this->forms['3d_mode'] = array('label' => __('Options de visualisation'),
+ 'fieldsnames' => array('visualisationMode', 'antialiasReading', 'correctCenter', 'pagesBaseAngle', 'centerBook', '|', 'extraXSpace', 'extraYSpace', '|', 'viewMode', '|', 'maxResolution'));
+
+ $this->fields['preload'] = array('type' => 'integer', 'default' => 16, 'editable' => true, 'label' => __('Nombre de pages à précharger'), 'grade' => 3);
+
+ $this->fields['navOrder'] = array('type' => 'textarea', 'default' => 'index, chapters, search, print, friend, bookmark, pdf, archives, basket, fullscreen, sound, 3d, extra, extra1, extra2, extra3, extra4, extra5, help, lang', 'editable' => true, 'label' => __('Ordre des icônes dans la nav'), 'grade' => 3);
+ $this->fields['tooltipTimer'] = array('type' => 'float', 'default' => 3, "editable" => true, 'label' => __("Temps maximum d'apparition des infos-bulles (en secondes)"));
+
+
+ $this->forms['general'] = array('label' => __('Fonctionnalités générales'),
+ 'fieldsnames' => array('navOrder', 'tooltipTimer', 'preload', 'pages', 'width', 'height'));
+ //.
+ //
+
+ $this->forms['menu'] = array('label' => __('Menu'), 'fieldsnames' => ['afterSearchDisplayForHTML', '|']);
+ $this->fields['afterSearchDisplayForHTML'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher l\'image après le moteur de recherche sur la version HTML5'), 'grade' => 1);
+ $extraNum = 5;
+ for ($i = 0; $i <= $extraNum; $i++) {
+ if ($i > 0) {
+ $j = $i;
+ $this->fields['navExtraIcon' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Icône supplémentaire') . ' ' . $j, 'fileFilter' => $imageExtraFilter);
+ $this->fields['navExtraType' . $j] = array('type' => 'combo', 'datas' => $extraType, 'default' => 'icon', 'editable' => true, 'label' => __('Type'));
+ $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL") . ' ' . $j);
+ $this->fields['navExtraVisibility' . $j] = array('type' => 'combo', 'datas' => $extraVisibility, 'default' => 'both', 'editable' => true, 'label' => __("Visible") . ' ' . $j);
+ $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraIcon' . $j, 'navExtraType' . $j, 'navExtraLink' . $j, 'navExtraVisibility' . $j, '|']);
+ } else {
+ $j = '';
+ $this->fields['navExtraImage' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour navigation'), 'fileFilter' => $imageExtraFilter);
+ $this->fields['navExtraImageMobile' . $j] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Image pour mobile'), 'fileFilter' => $imageExtraFilter);
+ $this->fields['navExtraLink' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("URL"));
+ $this->fields['navExtraTooltip' . $j] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Infobulle ou label"));
+ $this->forms['menu']['fieldsnames'] = array_merge($this->forms['menu']['fieldsnames'], ['navExtraImage' . $j, 'navExtraImageMobile' . $j, 'navExtraLink' . $j, 'navExtraTooltip' . $j, '|']);
+ }
+ }
+
+
+ $this->fields['landingPage'] = array('type' => 'freefile', 'default' => '', 'editable' => true, 'label' => __('Landing Page content'), 'grade' => 3);
+ $this->forms['landing'] = array('label' => __('Custom Landing Page'), 'fieldsnames' => array('landingPage'));
+
+
+ $this->fields['fullscreen'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le mode plein-écran'));
+ $this->fields['fullscreenAuto'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Lancer la publication en mode plein écran (lorsque possible)'));
+ $this->forms['fs'] = array('label' => __('Plein écran'),
+ 'fieldsnames' => array('fullscreen', 'fullscreenAuto'));
+
+
+ $this->fields['bookmark'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les marques-pages'));
+ $this->fields['bookmarkSendEnable'] = array('type' => 'boolean', 'default' => 'true', 'editable' => true, 'label' => __("Activer l'envoi des marques-pages par e-mail"));
+ $this->fields['bookmark_email_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+ $this->fields['bookmark_email_body'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __("Corps de l'email") . ' "' . __('Envoyer à un ami') . '"', 'hint' => __('Laisser vide pour utiliser la valeur par défaut'));
+ $this->fields['bookmarkCornerSize'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __("Taille des marques-pages"), 'hint' => __('Taille relative à la largeur de la page'));
+ $this->fields['bookmarkOffset'] = array('type' => 'integer', 'default' => 0, 'editable' => true, 'label' => __("Décaler de x pixels vers l'intérieur"));
+ $this->fields['bookmarkBlinkOnPageChange'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Faire clignoter le marque page à l\'apparition de la page'));
+ $this->fields['bookmarkUsePDF'] = array('type' => 'combo', 'default' => 'pages', 'editable' => true, 'label' => __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'),
+ 'datas' => [__('PDF des pages') => 'pages',
+ __('PDF de remplacement') => 'download',
+ __('PDF des miniatures') => 'thumbnails']);
+ $this->forms['bookmark'] = array('label' => __('Marques-pages'),
+ 'fieldsnames' => array('bookmark', '|', 'bookmarkSendEnable', 'bookmark_email_title', 'bookmark_email_body', '|', 'bookmarkCornerSize', 'bookmarkOffset', 'bookmarkBlinkOnPageChange', 'bookmarkUsePDF'));
+
+ $this->fields['help'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'aide"));
+ $this->fields['helpBookmarks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Améliorer l'aide des marques-pages"));
+ $this->fields['helpStartup'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher l'aide au démarrage"));
+ $this->fields['helpStartupTime'] = array('type' => 'integer', 'default' => 15, 'editable' => true, 'label' => __("Temps d'affichage en secondes"));
+ $this->fields['helpArrowTooltip'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Bulle affichée au niveau de la flèche de droite'), 'grade' => 5);
+ $this->forms['help'] = array('label' => __('Aide'),
+ 'fieldsnames' => array('help', '|', 'helpStartup', 'helpStartupTime', '|', 'helpBookmarks', '|', 'helpArrowTooltip'));
+ // .
+ //
+ $this->fields['indexAutoScroll'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le scroll automatique'));
+ $this->fields['pdfThumbnails'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('PDF utilisé pour générer les miniatures'), 'grade' => 1, 'fileFilter' => $pdfFilter);
+
+ $this->forms['index'] = array('label' => __('Index'), 'fieldsnames' => array('indexAutoScroll', 'pdfThumbnails'));
+
+ // .
+ //
+ $this->fields['print'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer l'impression"));
+ $this->fields['printMode'] = array('type' => 'combo', 'default' => 'vector', 'editable' => true, 'label' => __("Mode d'impression"),
+ 'datas' => array(__('Bitmap') => 'bitmap',
+ __('Vectoriel') => 'vector',
+ __('PDF') => 'pdf'));
+ $this->fields['printCoverWithMarks'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Imprimer les couvertures avec les pages marquées"), 'grade' => 3);
+ $this->forms['print'] = array('label' => __('Impression'),
+ 'fieldsnames' => array('print', 'printMode', 'printCoverWithMarks'));
+
+
+ $this->fields['search'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer le moteur de recherche'));
+ $this->fields['highlightResults'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Surligner les résultats'));
+ $this->fields['highlightAllOccurences'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Surligner toutes les occurences'), 'hint' => __('Même sur les pages non considérées comme un résultat'));
+ $this->fields['ignoreSearch'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Mots à ignorer'),
+ 'hint' => __('Liste des mots à ignorer séparés par des virgules'), 'grade' => 5);
+ $this->fields['ignoreSearchSeparators'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Caractères à ne pas considérer comme un séparateur de mot'));
+ $this->fields['ignoreWordLimit'] = ['type' => 'integer', 'default' => 3, 'editable' => true, 'label' => __('Ignorer les mots de moins de X caractères')];
+ $this->fields['textExtraction'] = array('type' => 'combo', 'default' => 'pdfbox', 'editable' => true, 'label' => __("Méthode d'extraction des textes"),
+ 'datas' => array(__('PDFBox') => 'pdfbox',
+ __('Poppler') => 'poppler',
+ __('Fluidbook (expérimentation basée sur PDFBox)') => 'fluidbook'));
+ $this->fields['searchShowNoResultsPages'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher les pages sans résultats"));
+ $this->fields['searchPageSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'AND',
+ 'datas' => [__('les double-pages qui contiennent tous les mots recherchés (ET logique)') => 'AND', __('les double-page qui contiennent un des mots recherché (OU logique)') => 'OR'], 'label' => __('Algorithme de sélection des résultats'));
+ $this->fields['searchWordSelectionAlgorithm'] = array('type' => 'combo', 'editable' => true, 'default' => 'begins',
+ 'datas' => [__('mot commençant par la requête') => 'begins', __('mot correspondant exactement à la requête') => 'exact', __('mot contenant la requête') => 'contains', __('expression exacte') => 'expression'],
+ 'label' => __('Algorithme de sélection des occurences'));
+
+ $this->forms['search'] = array('label' => __('Moteur de recherche'),
+ 'fieldsnames' => array('search', '|', 'ignoreWordLimit', 'ignoreSearch', 'ignoreSearchSeparators',
+ '|', 'searchWordSelectionAlgorithm', 'searchPageSelectionAlgorithm',
+ '|', 'highlightResults', 'highlightAllOccurences',
+ '|', 'searchShowNoResultsPages',
+ '|', 'textExtraction'));
+
+ $this->fields['soundTheme'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Thème sonore"),
+ 'datas' => array(__('Pas de son') => '',
+ __('Classique') => 'classic',
+ __("Papier épais") => 'heavy',
+ __("Papier fin") => 'light'));
+ $this->fields['soundOn'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les effets sonores à l'ouverture"));
+ $this->fields['ambientSound'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Ambiance sonore'), 'grade' => 3, 'fileFilter' => $soundFilter);
+ $this->fields['ambientSoundVolume'] = array('type' => 'integer', 'default' => 50, 'editable' => true,
+ 'label' => __("Volume de l'ambiance sonore"),
+ 'min' => 0, 'max' => 100);
+ $this->forms['sound'] = array('label' => __('Effets sonores'),
+ 'fieldsnames' => array('soundTheme', 'soundOn', '|', 'ambientSound', 'ambientSoundVolume'));
+ // .
+ $this->fields['pdf'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Activer les fonctions de téléchargement"));
+ $this->fields['pdfName'] = array('type' => 'text', 'default' => 'document.pdf', 'editable' => true, 'label' => __("Nom du fichier PDF"));
+ $this->fields['pdfComplex'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téchargement de PDF avancé'), "hint" => __("Permet à l'utilisateur de sélectionner les pages qu'il souhaite télécharger"), 'grade' => 3);
+ $this->fields['pdfCompress'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Compression du fichier PDF'));
+ $this->fields['pdfReplace'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('PDF de remplacement'), 'grade' => 3, 'fileFilter' => $pdfFilter);
+ $this->fields['offlineExport'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Téléchargement des versions offline'), "hint" => __('Valable si le téléchargement avancé est activé'), 'grade' => 3);
+ $this->forms['pdf'] = array('label' => __('Fonction de téléchargement'),
+ 'fieldsnames' => array('pdf', 'pdfName', 'pdfReplace', 'pdfCompress', 'pdfComplex', 'offlineExport'));
+ // .
+ $this->fields['zoomMode'] = array('type' => 'combo', 'default' => '0', 'editable' => true, 'label' => __("Mode de zoom"), 'grade' => 3,
+ 'datas' => array(__('Normal') => '0',
+ __('Une page') => '1',
+ __('Zoom désactivé') => '2'));
+ $this->fields['zoom'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Zoom par défaut (atteint au clic)'));
+ $this->fields['zoomw'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Zoom maximal (atteint à l'aide de la molette)"));
+ $this->forms['zoom'] = array('label' => __('Zoom'),
+ 'fieldsnames' => array('zoomMode', '|', 'zoom', 'zoomw'));
+ // .
+ $this->fields['stats'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Activer les statistiques Fluidbook'), 'grade' => 3);
+ $this->fields['stats_score'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher les scores dans les rapports'), 'grade' => 5);
+ $this->fields['stats_exclude_ip'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Exclure les IP suivantes des statistiques'), 'grade' => 3, 'hint' => sprintf(__('Indiquer une adresse ip de la forme %s par ligne'), 'www.xxx.yyy.zzz'));
+ $this->fields['googleAnalytics'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Code Google Analytics'), 'size' => 10);
+ $this->fields['googleAnalyticsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture de head)'));
+ $this->fields['statsCustom'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code Stats personnalisé (placé avant fermeture du body)'));
+ $this->fields['xiti'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code XiTi global'));
+ $this->fields['xiti_page'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Modèle code xiti (pour tags relatifs aux pages)'));
+ $this->forms['stats'] = array('label' => __('Statistiques'),
+ 'fieldsnames' => array('stats', 'stats_score', 'stats_exclude_ip', '|', 'googleAnalytics', '|', 'googleAnalyticsCustom', 'statsCustom', '|', 'xiti', 'xiti_page'));
+
+ $this->fields['displayChaptersPopup'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Always display chapters in a popup'), 'grade' => 1);
+ $this->fields['displayChaptersIcon'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche l'icône du sommaire"), 'grade' => 1);
+ $this->fields['displayChaptersLine'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Affiche une ligne entre le label et le numéro de page"), 'grade' => 5);
+ $this->fields['chaptersPage'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Faire pointer le sommaire sur la page'), 'grade' => 3, 'hint' => __('Laisser vide pour utiliser le sommaire classique'), 'size' => 5);
+ $this->fields['displayChaptersAtStart'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Afficher le sommaire au chargement de la publication"), 'grade' => 3);
+ $this->fields['chaptersColumns'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Afficher le sommaire sur x colonne(s)'), 'grade' => 3);
+ $this->fields['chaptersColMaxWidth'] = array('type' => 'integer', 'default' => 300, 'editable' => true, 'label' => __("Largeur max d'une colonne"), 'grade' => 3);
+ $this->fields['chaptersLevelLimit'] = array('type' => 'integer', 'default' => 5, 'editable' => true, 'label' => __('Limiter à x niveaux'));
+ $this->fields['externalChapters'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Sommaire personnalisé'), 'grade' => 3, 'fileFilter' => $swfFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
+ $this->fields['externalChaptersHTML'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Sommaire personnalisé (HTML5)'), 'grade' => 3, 'fileFilter' => $multimediaFilter, 'hint' => __('Laisser vide pour utiliser le sommaire classique'));
+ $this->fields['fullExternalChapters'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire totalement personnalisé"), 'grade' => 3, 'hint' => __('Supprime la flèche de fermeture, titre prédéfini et couleur de fond'));
+ $this->fields['mobileChaptersStyle'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __('Style des chapîtres') . ' (' . __('version mobile') . ')'
+ , 'datas' => array(__('Classique') => 'classic',
+ __('INA') => 'ina'));
+
+ $this->fields['chaptersPosition'] = array('type' => 'combo', 'default' => 'center', 'editable' => true, 'label' => __("Position du sommaire"),
+ 'datas' => array(__('Centré') => 'center',
+ __("Aligné sur l'icône") => 'chaptersIcon'));
+ $this->fields['chaptersCascade'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Sommaire en cascade"), 'grade' => 3);
+
+ $this->forms['sommaire'] = array('label' => __('Sommaire'),
+ 'fieldsnames' => array('displayChaptersIcon', 'displayChaptersPopup', 'displayChaptersAtStart', 'chaptersPage', 'chaptersPosition', 'chaptersLevelLimit', 'chaptersCascade', '|', 'chaptersColMaxWidth', 'chaptersColumns', 'displayChaptersLine', '|', 'externalChapters', 'fullExternalChapters', '|', 'externalChaptersHTML', '|', 'mobileChaptersStyle'));
+ // .
+
+ $this->fields['ongletsXML'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('XML de configuration des onglets'), 'grade' => 5);
+ $this->fields['ongletsSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('SWF pour onglets personnalisés'), 'grade' => 3, 'fileFilter' => $swfFilter);
+
+ $this->fields['tabs2DSWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('SWF pour onglets 2D'), 'grade' => 3, 'fileFilter' => $swfFilter);
+
+ $this->fields['tabsHTML5'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Onglets HTML5'), 'grade' => 3);
+
+ $this->fields['flatTabsAbsolute'] = array('type' => 'boolean', 'default' => false, "editable" => true,
+ 'label' => __("Positionnement relatif à l'interface"), 'grade' => 5);
+
+ $this->forms['tabs'] = array('label' => __('Onglets'),
+ 'fieldsnames' => array('ongletsSWF', 'ongletsXML', '|', 'tabs2DSWF', 'flatTabsAbsolute', '|', 'tabsHTML5'));
+
+ $this->fields['customLinkClass'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Classe pour les liens personnalisés'), 'grade' => 5);
+ $this->fields['permanentLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Liens visibles en permanence'), 'grade' => 3);
+ $this->fields['ignoreLinksTypes'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Ignorer les liens de type'), 'hint' => __('Liste des numéros séparés par des virgules'), 'grade' => 5);
+ $this->fields['linkBlinkTime'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __("Temps d'apparition du lien à l'ouverture de la page (en secondes)"));
+ $this->fields['linkTooltipManager'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Gestionnaire des info-bulles"), 'grade' => 5);
+ $this->fields['linkTracker'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens'), 'grade' => 5);
+ $this->fields['linkTrackerRegexp'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Tracking des liens applicables aux liens du domaine'), 'grade' => 5);
+ $this->fields['linkFilePrefix'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Préfixer les liens de téléchargement'));
+ $this->fields['linkMultimediaPerformanceMode'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Mode perfomance pour les liens multimédia'), 'grade' => 5);
+ $this->fields['linkMultimediaQuality'] = array('type' => 'float', 'default' => 1.0, 'editable' => true, 'label' => __('Qualité de rendu des animations'), 'grade' => 5);
+ $this->fields['linkCornerSize'] = array('type' => 'integer', 'default' => '10', 'editable' => true, 'label' => __('Taille des liens de coins de page'), 'hint' => __("Pourcentage de la largeur de la page"));
+ $this->fields['linkTooltipMaxWidth'] = array('type' => 'integer', 'default' => '140', 'editable' => true, 'label' => __('Largeur max des infobulles des liens de type "infobulle"'));
+ $this->fields['videoReset'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Réinitialiser les vidéos après la lecture'), 'grade' => 3);
+ $this->fields['videoBigPlay'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher le gros bouton Play'), 'grade' => 3);
+ $this->fields['brightcovePlayerId'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Id'), 'grade' => 3);
+ $this->fields['brightcovePlayerSecret'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Brightcove Player Secret'), 'grade' => 3);
+ $this->forms['multimedia'] = array('label' => __('Liens et multimédia'),
+ 'fieldsnames' => array('permanentLinks', 'linkBlinkTime', 'customLinkClass', 'ignoreLinksTypes', 'linkTooltipManager', 'linkCornerSize', 'linkTooltipMaxWidth', '|', 'linkTracker', 'linkTrackerRegexp', '|', 'linkFilePrefix', '|', 'linkMultimediaPerformanceMode', 'linkMultimediaQuality', '|', 'videoReset', 'videoBigPlay', '|', 'brightcovePlayerId', 'brightcovePlayerSecret'));
+ //.
+ $this->fields['externalArchives'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Archives'), 'grade' => 3, 'fileFilter' => $imageFilter);
+ $this->fields['externalArchivesBack'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Image de fond'), 'grade' => 3, 'fileFilter' => $imageFilter);
+ $this->fields['archivesLink'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Lien'), 'grade' => 5);
+ $this->fields['archivesLabel'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Label'), 'grade' => 5);
+
+ $this->forms['archives'] = array('label' => __('Archives'),
+ 'fieldsnames' => array('externalArchives', 'externalArchivesBack', '|', 'archivesLink', 'archivesLabel'));
+ // .
+ $this->fields['form'] = array('type' => 'combo', 'default' => '', 'editable' => true, 'grade' => 5, 'label' => __('Formulaire'), 'datas' => array(__('Aucun') => '', __('Bulle Groupe') => 'bulle'));
+ $this->forms['form'] = array('label' => __('Formulaire'),
+ 'fieldsnames' => array('form'));
+
+ $this->fields['cookieConsent'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Message cookie'));
+ $this->fields['cookieConsentMessage'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Texte du consentement'));
+ $this->fields['cookieConsentAutoclose'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Masquer automatiquement après x secondes'));
+ $this->forms['privacy'] = array('label' => __('Respect de la vie privée'),
+ 'fieldsnames' => array('cookieConsent', 'cookieConsentMessage', 'cookieConsentAutoclose'));
+
+ //.
+ $this->fields['basket'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Panier activé'), 'grade' => 5);
+ $this->fields['basketManager'] = array('type' => 'combo', 'default' => 'classic', 'editable' => true, 'label' => __("Manager de panier"),
+ 'datas' => array(__('Classic') => 'com.fluidbook.player.basket.BasketManager',
+ 'Grdf' => 'com.fluidbook.player.basket.custom.grdf.GrdfBasketManager',
+ 'Grdf 2013' => 'com.fluidbook.player.basket.custom.grdf.grdf2013.GrdfBasketManager2013',
+ 'Grdf 2015' => 'com.fluidbook.player.basket.custom.grdf.grdf2015.GrdfBasketManager2015',
+ 'Essilor' => 'com.fluidbook.player.basket.custom.essilor.EssilorBasketManager',
+ 'Essilor Recap' => 'com.fluidbook.player.basket.custom.essilorrecap.EssilorRecapBasketManager',
+ 'Wesco Ventes' => 'com.fluidbook.player.basket.custom.wesco.WescoBasketManager',
+ 'Atlantic Download' => 'com.fluidbook.player.basket.custom.atlantic.AtlanticDownloadBasketManager'
+ ), 'grade' => 5);
+ $this->fields['basketReferences'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Références produits'), 'grade' => 3, 'fileFilter' => $basketFilter, 'hint' => __('Fichier contenant les références produits'), 'dir' => 'commerce');
+ $this->fields['basketImages'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Images des produits'), 'grade' => 5, 'fileFilter' => $imageFilter, 'hint' => __('Chaque image doit avoir pour nom exact la référence du produit'),
+ 'multiple' => true, 'dir' => 'commerce');
+ $this->fields['basketPDFBackground'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Fond du PDF (bon de commande)'), 'grade' => 5, 'fileFilter' => $epsFilter, 'hint' => __('Fond du bon de commande'), 'dir' => 'commerce');
+
+ $this->forms['basket'] = array('label' => __('Panier'),
+ 'fieldsnames' => array('basket', 'basketManager', 'basketReferences', 'basketImages', 'basketPDFBackground'));
+ // .
+ $this->fields['offlineLink'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __("URL du Fluidbook"), 'hint' => __('URL du fluidbook utilisée pour la version Offline (CD-ROM, clé USB, Exécutables)'));
+ $this->fields['offlineTitle'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Titre de l'application"));
+ $this->forms['offline'] = array('label' => __('Version offline'),
+ 'fieldsnames' => array('offlineTitle', 'offlineLink'));
+
+ $this->fields['alwaysHTML5'] = array('type' => 'boolean', 'default' => 'false', 'editable' => true, 'label' => __('Toujours utiliser la version HTML5'), 'grade' => 1);
+
+ $this->fields['html5priority'] = array('type' => 'combo', 'default' => 'true', 'editable' => true, 'label' => __("Rediriger vers la version HTML5"), 'grade' => 1,
+ 'datas' => array(__('Si l\'utilisateur a un appareil tactile') => 'false',
+ __('Si flash n\'est pas installé') => 'notinstalled',
+ __("Si flash n'est pas pas installé ou bloqué") => 'true'));
+
+ $this->fields['flashBlockedWait'] = array('type' => 'float', 'default' => 1.5, 'editable' => true, 'label' => __("Temps d'attente avant de considérer flash comme bloqué"));
+
+
+ $this->fields['navOrderH'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ordre des icônes dans la nav') . ' (' . __('Si différente') . ')', 'grade' => 3);
+
+ $this->fields['menuBreakpoint'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Breakpoint burger menu'), 'hint' => 'Par défaut 1023px', 'grade' => 3);
+
+
+ $this->fields['mobileTransitions'] = array('type' => 'combo', 'default' => 'flip', 'editable' => true, 'label' => __('Transitions entre les pages'), 'grade' => 3,
+ 'datas' => array(__('Aucune transition') => 'none',
+ __('Glisser') => 'slide',
+ __('Tourner') => 'flip')
+ );
+ $this->fields['mobileNavigationType'] = array('type' => 'combo', 'default' => 'book', 'editable' => true, 'label' => __('Mode de navigation'), 'grade' => 5,
+ 'datas' => array(__('Normal (automatique)') => 'book',
+ __('Normal (double page)') => 'landscape',
+ __('Normal (une page)') => 'portrait',
+ __('Magazine tablette') => 'tab')
+ );
+ $this->fields['rasterizePages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Ecraser les pages'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
+ $this->fields['vectorPages'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Conserver les pages en vecteur'), 'hint' => '1-3,5 = 1,2,3,5', 'grade' => 1);
+
+
+ $this->fields['mobileTransitionDuration'] = array('type' => 'float', 'default' => '0.75', 'editable' => true, 'label' => __('Durée de la transition'));
+ $this->fields['mobileLinksRevealAnim'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Animer les liens après un changement de page"), 'grade' => 3);
+
+ $this->fields['mobileIconVector'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Utiliser les icônes vectorielles'));
+ $this->fields['mobileServerConfig'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Inclure les fichiers de configuration serveur'), 'grade' => 3);
+
+ $this->fields['mobilePlugins'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Plugin'), 'grade' => 5);
+
+ $this->fields['mobileVideosPath'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Chemin vers les vidéos'), 'grade' => 5);
+ $this->fields['mobileExtraXSpace'] = array('type' => 'integer', 'default' => '0', 'editable' => true, 'label' => __('Marge supplémentaire horizontale'), 'grade' => 3);
+ $this->fields['mobileNavScale'] = array('type' => 'integer', 'default' => '100', 'editable' => true, 'label' => __('Taille du menu (en %)'), 'grade' => 3);
+
+ $this->fields['mobileIgnoreBackgroundLinks'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Ignorer les liens de background'));
+
+ $this->forms['mobile'] = array('label' => __('Version mobile'),
+ 'fieldsnames' => array('alwaysHTML5', 'html5priority', 'flashBlockedWait', 'mobileNavigationType', '|', 'rasterizePages', 'vectorPages', '|', 'mobileNavScale', '|', 'mobileTransitions', 'mobileTransitionDuration', "mobileLinksRevealAnim", '|', 'menuBreakpoint', 'navOrderH', '|', 'mobileIconVector', 'mobileServerConfig', 'mobilePlugins', '|', 'mobileVideosPath', '|', 'mobileExtraXSpace', '|', 'mobileIgnoreBackgroundLinks'));
+
+
+ $this->fields['phonegapId'] = array('type' => 'text', 'default' => 'com.fluidbook.phonegap.$id', 'editable' => true, 'label' => __("Identifiant de l'identifiant"), 'grade' => 5, 'hint' => __('De la forme') . ' com.fluidbook.phonegap.xxxxx');
+ $this->fields['phonegapVersion'] = array('type' => 'text', 'default' => '1.0.0', 'editable' => true, 'label' => __("Version de l'application"), 'grade' => 5, 'hint' => __('De la forme') . ' 1.2.3');
+ $this->fields['phonegapPlugins'] = array('type' => 'textarea', 'default' => 'ChildBrowser', 'editable' => true, 'label' => __('Plugins Phonegap'), 'grade' => 5);
+ $defaultScreenshots = "P,0\nL,2\nL,index";
+ $this->fields['appScreenshots'] = array('type' => 'textarea', 'default' => $defaultScreenshots, 'editable' => true, 'label' => 'Générer les screenshots', 'grade' => 5, 'hint' => __('Une ligne par vue à générer de la forme X,Y (X : P(ortrait) ou L(andscape), Y : numéro de page ou vue (1, index))'));
+
+ $this->forms['phonegap'] = array('label' => __('Applications mobile'),
+ 'fieldsnames' => array('phonegapId', 'phonegapVersion', 'phonegapPlugins', 'appScreenshots'));
+
+ $this->fields['secureURL'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('URL de sécurisation'), 'grade' => 5, 'hint' => __('URL intérrogé pour vérifier si le visiteur à les droits pour consulter la publication'));
+ $this->fields['secureURLRedirect'] = array('type' => 'text', 'default' => 'http://', 'editable' => true, 'label' => __('Redirection'), 'grade' => 5, 'hint' => __("Si l'authentification échoue, redirection vers cette adresse"));
+ $this->fields['preventRightClick'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __("Essayer d'empêcher le clic droit"), 'grade' => 1);
+ $this->forms['secure'] = array('label' => __('Sécurisation'),
+ 'fieldsnames' => array('secureURL', 'secureURLRedirect', '|', 'preventRightClick'));
+
+ $this->fields['seoVersion'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Générer une version pour les moteurs de recherche'));
+ $this->fields['seoRobots'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Autoriser le parcours par les moteurs de recherche'));
+ $this->fields['seoDescription'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Description'));
+ $this->fields['seoKeywords'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Meta tag Keywords'));
+
+ $this->forms['seo'] = array('label' => __('Optimisation pour les moteurs de recherche'),
+ 'fieldsnames' => array('seoVersion', 'seoRobots', 'seoDescription', "seoKeywords"));
+
+ $this->fields['home'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __("Accueil de l'interface multibrochure"), 'grade' => 5);
+ $this->fields['multilang'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Langues'), 'hint' => __('Code langue') . ',' . __('Code pays') . ',' . __('URL'));
+ $this->fields['country'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Pays de la brochure'));
+ $this->fields['multilangDisplay'] = array('type' => 'combo', 'default' => 'lang', 'editable' => true, 'label' => __('Affichage'),
+ 'datas' => array(__('Langue') => 'lang',
+ __('Langue') . ' (' . __('Pays') . ')' => 'lang_country',
+ __('Pays') . ' (' . __('Langue') . ')' => 'country_lang'));
+ $this->forms['multibrochure'] = array('label' => __('Multibrochure'),
+ 'fieldsnames' => array('home', 'country', 'multilangDisplay', 'multilang'));
+
+ $this->fields['plv'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer le mode PLV'), 'grade' => 3);
+ $this->fields['plvTimer'] = array('type' => 'integer', 'min' => 1, 'max' => 60, 'default' => 5, 'editable' => true, 'label' => __('Temps'), 'grade' => 3);
+ $this->fields['plvMode'] = array('type' => 'combo', 'default' => 'first', 'editable' => true, 'label' => __('Arrivé à la dernière page'), 'grade' => 3,
+ 'datas' => array(__('Remonter vers la première page') => 'back',
+ __('Recommencer à la première page') => 'first'));
+ $this->forms['plv'] = array('label' => __('Mode PLV'),
+ 'fieldsnames' => array('plv', 'plvTimer', 'plvMode'));
+
+ $this->fields['widget'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Générer le widget'), 'grade' => 3);
+ $this->fields['widgetCover'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __('Afficher la couverture') . ')', 'grade' => 3);
+ $this->fields['widgetSize'] = array('type' => 'integer', 'default' => 200, 'editable' => true, 'label' => __('Optimiser pour une hauteur de (en pixels)'), 'grade' => 3);
+ $this->fields['widgetQuality'] = array('type' => 'integer', 'default' => 85, 'min' => 0, 'max' => 100, 'editable' => true, 'label' => __('Qualité JPEG'), 'grade' => 3);
+ $this->fields['widgetStart'] = array('type' => 'integer', 'default' => 1, 'editable' => true, 'label' => __('Page de début'), 'grade' => 3);
+ $this->fields['widgetEnd'] = array('type' => 'integer', 'default' => 8, 'editable' => true, 'label' => __('Page de fin'), 'grade' => 3);
+ $this->forms['widget'] = array('label' => __('Widget') . ' (' . __('Mini Fluidbook') . ')',
+ 'fieldsnames' => array('widget', 'widgetCover', 'widgetSize', 'widgetQuality', 'widgetStart', 'widgetEnd'));
+
+ $this->fields['extras'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Extras'), 'grade' => 3);
+ $this->fields['v1SWF'] = array('type' => 'freefile', 'default' => '', 'editable' => true,
+ 'label' => __('Index.swf spécifique'), 'grade' => 5, 'fileFilter' => $swfFilter);
+ $this->forms['v1'] = array('label' => __('Options spécifiques au fluidbook version 1'),
+ 'fieldsnames' => array('extras', 'v1SWF'));
+
+ $this->fields['themeEnableAfterSearch'] = array('type' => 'boolean', 'default' => true, 'editable' => true, 'label' => __("Afficher l'image supplémentaire à droite du moteur de recherche"), 'grade' => 3);
+ $this->forms['theme'] = array('label' => __('Options du thème'),
+ 'fieldsnames' => array('themeEnableAfterSearch'));
+
+ $this->fields['forceCompileOnDownload'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Forcer la compilation lors du téléchargement'), 'grade' => 3);
+ $this->fields['htmlExtension'] = array('type' => 'text', 'default' => 'html', 'editable' => true, 'label' => __('Extension des fichiers html'), 'grade' => 5, 'hint' => __('Ex : php, htm, html, phtml, asp'), 'grade' => 5);
+ $this->fields['htmlPrepend'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Code à insérer en tête des fichiers'), 'grade' => 5);
+ $this->fields['baseUrl'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Base de l\'url'), 'grade' => 5, 'grade' => 5);
+
+ $this->forms['package'] = array('label' => __('Option d\'export'),
+ 'fieldsnames' => array('htmlExtension', 'htmlPrepend', 'baseUrl', 'forceCompileOnDownload'));
+
+ $this->fields['disableDemo'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Désactiver le lien de démo'), 'grade' => 5);
+ $this->fields['redirectDemo'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Rediriger le lien de démo vers'), 'grade' => 5);
+ $this->forms['demo'] = array('label' => __('Lien de démo'),
+ 'fieldsnames' => array('disableDemo', 'redirectDemo'));
+
+
+ $this->fields['scorm_enable'] = array('type' => 'boolean', 'default' => false, 'editable' => true, 'label' => __('Activer SCORM'), 'grade' => 5);
+ $this->fields['scorm_id'] = array('type' => 'text', 'default' => 'MFMCTE091mobile', 'editable' => true, 'label' => __('Identifiant SCORM'), 'grade' => 5);
+ $this->fields['scorm_org'] = array('type' => 'text', 'default' => 'ACME-ORG-1350650111249', 'editable' => true, 'label' => __('Organisation SCORM'), 'grade' => 5);
+ $this->fields['scorm_title'] = array('type' => 'text', 'default' => '', 'editable' => true, 'label' => __('Titre SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
+ $this->fields['scorm_variables'] = array('type' => 'textarea', 'default' => '', 'editable' => true, 'label' => __('Variables SCORM'), 'grade' => 5, 'hint' => __('Laisser vide pour utiliser le titre de la publication'));
+
+ $this->forms['scorm'] = array('label' => __('SCORM'),
+ 'fieldsnames' => array('scorm_enable', 'scorm_id', 'scorm_org', 'scorm_title', 'scorm_variables'));
+ }
}
<?php
-class wsHTML5Compiler {
- protected static $resolutions = array(150, 300);
- public $maxRes = 300;
-
- public $jsFiles = array(
- 'js/libs/modernizr/modernizr.min.js',
- 'js/libs/modernizr/tests.js',
- 'js/libs/cube/fb.js',
- 'js/libs/cube/util.js',
- 'js/libs/screenfull.min.js',
- 'js/libs/storage.js',
- 'js/libs/keymaster.js',
- 'js/libs/jquery/jquery.min.js',
- 'js/libs/jquery/jquery.transform.js',
- 'js/libs/jquery/jquery.form.min.js',
- 'js/libs/jquery/jquery.mousewheel.min.js',
- 'js/libs/jquery/jquery.hashchange.min.js',
- 'js/libs/jquery/perfect-scrollbar.jquery.min.js',
- 'js/libs/mmenu/jquery.mmenu.min.js',
- 'js/libs/mmenu/jquery.mmenu.rtl.min.js',
- 'js/libs/mmenu/jquery.mmenu.offcanvas.min.js',
- 'js/libs/gsap/TweenMax.min.js',
- 'js/libs/gsap/jquery.gsap.min.js',
- 'js/libs/gal/gal.js',
- 'js/libs/gal/gal.filesystem.js',
- 'js/libs/hammer.min.js',
- 'js/libs/fluidbook/forms/fluidbook.form.bulle.js',
- 'js/libs/fluidbook/fluidbook.utils.js',
- 'js/libs/fluidbook/fluidbook.links.js',
- 'js/libs/fluidbook/fluidbook.support.js',
- 'js/libs/fluidbook/fluidbook.video.js',
- 'js/libs/fluidbook/fluidbook.viewport.js',
- 'js/libs/fluidbook/fluidbook.desktop.js',
- 'js/libs/fluidbook/fluidbook.service.js',
- 'js/libs/fluidbook/fluidbook.share.js',
- 'js/libs/fluidbook/fluidbook.l10n.js',
- 'js/libs/fluidbook/fluidbook.slider.js',
- 'js/libs/fluidbook/fluidbook.nav.js',
- 'js/libs/fluidbook/fluidbook.interface.js',
- 'js/libs/fluidbook/fluidbook.touch.js',
- 'js/libs/fluidbook/fluidbook.loader.js',
- 'js/libs/fluidbook/fluidbook.search.js',
- 'js/libs/fluidbook/fluidbook.help.js',
- 'js/libs/fluidbook/fluidbook.resize.js',
- 'js/libs/fluidbook/fluidbook.stats.js',
- 'js/libs/fluidbook/fluidbook.cache.js',
- 'js/libs/fluidbook/fluidbook.tooltip.js',
- 'js/libs/fluidbook/fluidbook.bookmarks.js',
- 'js/libs/fluidbook/fluidbook.background.js',
- 'js/libs/fluidbook/fluidbook.pad.js',
- 'js/libs/fluidbook/fluidbook.audiodescription.js',
- 'js/libs/fluidbook/fluidbook.privacy.js',
- 'js/libs/fluidbook/fluidbook.zoom.js',
- 'js/libs/fluidbook/fluidbook.menu.js',
- 'js/libs/fluidbook/fluidbook.sound.js',
- 'js/libs/fluidbook/fluidbook.scorm.js',
- 'js/libs/fluidbook/menu/fluidbook.chapters.js',
- 'js/libs/fluidbook/menu/fluidbook.index.js',
- 'js/libs/fluidbook/fluidbook.landingpage.js',
- 'js/libs/fluidbook/fluidbook.js',
- 'js/main.js');
-
- public $specialJsFiles = array();
-
- public $debugJsFiles = array(
- 'js/libs/Three.js',
- 'data/search.index.js',
- );
- public $testJsFiles = array(
- 'js/libs/cube/fb.js',
- 'js/libs/modernizr/modernizr.min.js',
- 'js/libs/modernizr/tests.js',
- 'js/libs/jquery/jquery.min.js',
- 'js/libs/jquery/jquery.transform.min.js',
- 'js/libs/jquery/jquery.mousewheel.min.js',
- 'js/libs/jquery/jquery.hashchange.min.js',
- 'js/tester.js'
- );
- public $widgetJsFiles = array(
- 'js/libs/cube/fb.js',
- 'js/libs/modernizr/modernizr.min.js',
- 'js/libs/modernizr/tests.js',
- 'js/libs/jquery/jquery.min.js',
- 'js/libs/jquery/jquery.transit.js',
- 'js/widget.js'
- );
-
- // Collection of LESS files to be compiled
- // Filename with no extension, relative to the /style directory in the player build folder
- public $lessFiles = ['fluidbook'];
-
- public $specialCSS = array();
- public $phonegapStandardPlugins = array('ios' => array('ExternalFileUtil'),
- 'android' => array('webintent'));
- public $pluginCSS = array();
- public $pluginJs = array();
- public $htmlmultimedia = array();
- protected $cssX = array();
- protected $cssY = array();
- protected $cssWidths = array();
- protected $pdf2htmlRatio;
- protected $scale;
- protected $multiply;
- protected $div = array();
- protected $numerotation;
- protected $fontDocs = array();
- protected $dir;
- protected $z = 3;
- public $vdir;
- public $wdir;
-
- /**
- *
- * @var wsBook
- */
- public $book;
- protected $pages;
- protected $theme;
- public $version;
- public $book_id;
- protected $themeRoot;
-
- /**
- *
- * @var wsDAOBook
- */
- protected $daoBook;
- protected $needToRecompileContents = true;
- protected $needToRecompileSettings = true;
- public $width;
- public $height;
- protected $cssWidth;
- protected $cssHeight;
- protected $cssOneWidth;
- protected $cssOneHeight;
- protected $cssScale;
- protected $cssSVGScale;
- protected $optimalWidth = 567;
- protected $optimalHeight = 709;
- protected $additionalConfig = array();
- protected $fontScale = 1;
- protected $cache = array();
- protected $backgroundsPrefix = array();
- protected $svg = true;
- protected $config = array();
- protected $assets = '';
- protected $phonegap = false;
- protected $phonegapVersion;
- protected $standalone = false;
- protected $hiddenContents = array();
- protected $appcache;
- protected $home;
- protected $widget = true;
- protected $multiApp = false;
- protected $pageLabels = array();
- protected $stylesheets = array();
- protected $logfp = null;
- protected $logtime = null;
- protected $beginBody = array();
- protected $seoArticles = [];
- protected $securityPolicyWhitelist = ['*.google-analytics.com', '*.youtube.com', '*.ytimg.com'];
-
-
- function __construct($book_id, $version = 'stable', $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false) {
- global $core;
-
- $this->phonegapVersion = wsHTML5::getPhonegapVersion($phonegapVersion);
- $this->appcache = $appcache;
- $this->multiApp = $this->home = $home;
- $this->version = $version;
-
- if ($version == 'stable') {
- $this->assets = WS_COMPILE_ASSETS . '/player/branches/master';
- } else if ($version == 'dev') {
- $this->assets = WS_COMPILE_ASSETS . '/player/local/master';
- } else {
- list($branch, $location) = explode('|', $version);
- $this->assets = WS_COMPILE_ASSETS . '/player/' . ($location == 'git' ? 'branches' : $location) . '/' . $branch;
- }
-
- $this->phonegap = $phonegap;
- $this->standalone = $standalone || $this->phonegap;
- $this->appcache = $appcache;
- $this->widget = !$this->phonegap;
-
- cubePHP::set_memory('4G');
-
- if (trim($book_id) == '') {
- return;
- }
- $this->book_id = $book_id;
- $this->log('Start compilation');
-
- if (is_null($dir)) {
- $this->dir = WS_BOOKS . '/html5/' . $book_id . '/';
- } else {
- $this->dir = $dir;
- }
- $this->vdir = new CubeIT_Files_VirtualDirectory($this->dir);
- $this->wdir = WS_BOOKS . '/working/' . $this->book_id . '/';
-
- $this->daoBook = new wsDAOBook($core->con);
- $this->book = $this->daoBook->selectById($book_id);
- $this->pages = $this->daoBook->getPagesOfBook($book_id);
-
-
- $daoTheme = new wsDAOTheme($core->con);
- $this->theme = $daoTheme->getThemeOfBook($book_id, true);
- $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/';
-
- $daoDoc = new wsDAODocument($core->con);
- $firstDoc = $daoDoc->selectById($this->pages[1]['document_id']);
- $size = $firstDoc->generalInfos['size'];
-
- $this->log('Got data from database');
-
- $this->width = round($size[0], 3);
- $this->height = round($size[1], 3);
-
- $imagesize = CubeIT_Image::getimagesize(wsDocument::getDir($this->pages[1]['document_id']) . 'html/h150-' . $this->pages[1]['document_page'] . '.jpg');
- $this->pdf2htmlRatio = round(($imagesize[0] * 0.48) / $this->width, 3);
-
- $this->cssScale = $this->z * min($this->optimalWidth / $this->width, $this->optimalHeight / $this->height);
- $this->cssOneScale = $this->z * min(($this->optimalWidth * 2) / $this->width, $this->optimalHeight / $this->height);
-
- $this->cssWidth = $this->width * $this->cssScale;
- $this->cssHeight = $this->height * $this->cssScale;
-
- $this->cssOneWidth = $this->width * $this->cssOneScale;
- $this->cssOneHeight = $this->height * $this->cssOneScale;
-
- $this->cssSVGScale = 1;
-
- $this->scale = 1;
- if ($this->book->parametres->zoomMode == 1) {
- $this->multiply = $this->pdf2htmlRatio * $this->scale * $this->cssOneScale;
- } else {
- $this->multiply = $this->pdf2htmlRatio * $this->scale * $this->cssScale;
- }
- $this->numerotation = explode(',', $this->book->numerotation);
-
- $this->initConfig();
- $this->log('Defined dimensions');
- }
-
- public function initConfig() {
- $this->config = cubeObject::merge($this->book->parametres->toStandardObject(), $this->theme->parametres->toStandardObject());
- $this->config->rasterizePages = cubeArray::parseRange($this->config->rasterizePages);
- $this->config->vectorPages = array_diff(cubeArray::parseRange($this->config->vectorPages), $this->config->rasterizePages);
- }
-
- public function log($step) {
- $currenttime = microtime(true);
- if (null === $this->logfp) {
- $this->logfp = fopen('/var/log/extranet/htmlconversions/' . $this->book_id . '.log', 'w+');
- }
- if (null === $this->logtime) {
- $this->logtime = $currenttime;
- }
- $time = $currenttime - $this->logtime;
- $log = $step . ' | ' . round($time, 3) . 's' . "\n";
- fwrite($this->logfp, $log);
- fflush($this->logfp);
- $this->logtime = $currenttime;
- }
-
- public function addFacebookSDK() {
- $lang = str_replace('-', '_', $this->book->lang);
- $e = explode('_', $lang);
- if (count($e) > 1) {
- $e[1] = mb_strtoupper($lang);
- }
- $lang = implode('_', $e);
-
- $langsMap = ['fr' => 'fr_FR', 'en' => 'en_US'];
-
- if (isset($langsMap[$lang])) {
- $lang = $langsMap[$lang];
- }
-
- $this->beginBody[] = "<div id=\"fb-root\"></div>
+class wsHTML5Compiler
+{
+ protected static $resolutions = array(150, 300);
+ public $maxRes = 300;
+
+ public $jsFiles = array(
+ 'js/libs/modernizr/modernizr.min.js',
+ 'js/libs/modernizr/tests.js',
+ 'js/libs/cube/fb.js',
+ 'js/libs/cube/util.js',
+ 'js/libs/screenfull.min.js',
+ 'js/libs/storage.js',
+ 'js/libs/keymaster.js',
+ 'js/libs/jquery/jquery.min.js',
+ 'js/libs/jquery/jquery.transform.js',
+ 'js/libs/jquery/jquery.form.min.js',
+ 'js/libs/jquery/jquery.mousewheel.min.js',
+ 'js/libs/jquery/jquery.hashchange.min.js',
+ 'js/libs/jquery/perfect-scrollbar.jquery.min.js',
+ 'js/libs/mmenu/jquery.mmenu.min.js',
+ 'js/libs/mmenu/jquery.mmenu.rtl.min.js',
+ 'js/libs/mmenu/jquery.mmenu.offcanvas.min.js',
+ 'js/libs/gsap/TweenMax.min.js',
+ 'js/libs/gsap/jquery.gsap.min.js',
+ 'js/libs/gal/gal.js',
+ 'js/libs/gal/gal.filesystem.js',
+ 'js/libs/hammer.min.js',
+ 'js/libs/fluidbook/forms/fluidbook.form.bulle.js',
+ 'js/libs/fluidbook/fluidbook.utils.js',
+ 'js/libs/fluidbook/fluidbook.links.js',
+ 'js/libs/fluidbook/fluidbook.support.js',
+ 'js/libs/fluidbook/fluidbook.video.js',
+ 'js/libs/fluidbook/fluidbook.viewport.js',
+ 'js/libs/fluidbook/fluidbook.desktop.js',
+ 'js/libs/fluidbook/fluidbook.service.js',
+ 'js/libs/fluidbook/fluidbook.share.js',
+ 'js/libs/fluidbook/fluidbook.l10n.js',
+ 'js/libs/fluidbook/fluidbook.slider.js',
+ 'js/libs/fluidbook/fluidbook.nav.js',
+ 'js/libs/fluidbook/fluidbook.interface.js',
+ 'js/libs/fluidbook/fluidbook.touch.js',
+ 'js/libs/fluidbook/fluidbook.loader.js',
+ 'js/libs/fluidbook/fluidbook.search.js',
+ 'js/libs/fluidbook/fluidbook.help.js',
+ 'js/libs/fluidbook/fluidbook.resize.js',
+ 'js/libs/fluidbook/fluidbook.stats.js',
+ 'js/libs/fluidbook/fluidbook.cache.js',
+ 'js/libs/fluidbook/fluidbook.tooltip.js',
+ 'js/libs/fluidbook/fluidbook.bookmarks.js',
+ 'js/libs/fluidbook/fluidbook.background.js',
+ 'js/libs/fluidbook/fluidbook.pad.js',
+ 'js/libs/fluidbook/fluidbook.audiodescription.js',
+ 'js/libs/fluidbook/fluidbook.privacy.js',
+ 'js/libs/fluidbook/fluidbook.zoom.js',
+ 'js/libs/fluidbook/fluidbook.menu.js',
+ 'js/libs/fluidbook/fluidbook.sound.js',
+ 'js/libs/fluidbook/fluidbook.scorm.js',
+ 'js/libs/fluidbook/menu/fluidbook.chapters.js',
+ 'js/libs/fluidbook/menu/fluidbook.index.js',
+ 'js/libs/fluidbook/fluidbook.landingpage.js',
+ 'js/libs/fluidbook/fluidbook.js',
+ 'js/main.js');
+
+ public $specialJsFiles = array();
+
+ public $debugJsFiles = array(
+ 'js/libs/Three.js',
+ 'data/search.index.js',
+ );
+ public $testJsFiles = array(
+ 'js/libs/cube/fb.js',
+ 'js/libs/modernizr/modernizr.min.js',
+ 'js/libs/modernizr/tests.js',
+ 'js/libs/jquery/jquery.min.js',
+ 'js/libs/jquery/jquery.transform.min.js',
+ 'js/libs/jquery/jquery.mousewheel.min.js',
+ 'js/libs/jquery/jquery.hashchange.min.js',
+ 'js/tester.js'
+ );
+ public $widgetJsFiles = array(
+ 'js/libs/cube/fb.js',
+ 'js/libs/modernizr/modernizr.min.js',
+ 'js/libs/modernizr/tests.js',
+ 'js/libs/jquery/jquery.min.js',
+ 'js/libs/jquery/jquery.transit.js',
+ 'js/widget.js'
+ );
+
+ // Collection of LESS files to be compiled
+ // Filename with no extension, relative to the /style directory in the player build folder
+ public $lessFiles = ['fluidbook'];
+
+ public $specialCSS = array();
+ public $phonegapStandardPlugins = array('ios' => array('ExternalFileUtil'),
+ 'android' => array('webintent'));
+ public $pluginCSS = array();
+ public $pluginJs = array();
+ public $htmlmultimedia = array();
+ protected $cssX = array();
+ protected $cssY = array();
+ protected $cssWidths = array();
+ protected $pdf2htmlRatio;
+ protected $scale;
+ protected $multiply;
+ protected $div = array();
+ protected $numerotation;
+ protected $fontDocs = array();
+ protected $dir;
+ protected $z = 3;
+ public $vdir;
+ public $wdir;
+
+ /**
+ *
+ * @var wsBook
+ */
+ public $book;
+ protected $pages;
+ protected $theme;
+ public $version;
+ public $book_id;
+ protected $themeRoot;
+
+ /**
+ *
+ * @var wsDAOBook
+ */
+ protected $daoBook;
+ protected $needToRecompileContents = true;
+ protected $needToRecompileSettings = true;
+ public $width;
+ public $height;
+ protected $cssWidth;
+ protected $cssHeight;
+ protected $cssOneWidth;
+ protected $cssOneHeight;
+ protected $cssScale;
+ protected $cssSVGScale;
+ protected $optimalWidth = 567;
+ protected $optimalHeight = 709;
+ protected $additionalConfig = array();
+ protected $fontScale = 1;
+ protected $cache = array();
+ protected $backgroundsPrefix = array();
+ protected $svg = true;
+ protected $config = array();
+ protected $assets = '';
+ protected $phonegap = false;
+ protected $phonegapVersion;
+ protected $standalone = false;
+ protected $hiddenContents = array();
+ protected $appcache;
+ protected $home;
+ protected $widget = true;
+ protected $multiApp = false;
+ protected $pageLabels = array();
+ protected $stylesheets = array();
+ protected $logfp = null;
+ protected $logtime = null;
+ protected $beginBody = array();
+ protected $seoArticles = [];
+ protected $securityPolicyWhitelist = ['*.google-analytics.com', '*.youtube.com', '*.ytimg.com'];
+
+
+ function __construct($book_id, $version = 'stable', $phonegap = false, $phonegapVersion = 'latest', $dir = null, $standalone = false, $appcache = false, $home = false)
+ {
+ global $core;
+
+ $this->phonegapVersion = wsHTML5::getPhonegapVersion($phonegapVersion);
+ $this->appcache = $appcache;
+ $this->multiApp = $this->home = $home;
+ $this->version = $version;
+
+ if ($version == 'stable') {
+ $this->assets = WS_COMPILE_ASSETS . '/player/branches/master';
+ } else if ($version == 'dev') {
+ $this->assets = WS_COMPILE_ASSETS . '/player/local/master';
+ } else {
+ list($branch, $location) = explode('|', $version);
+ $this->assets = WS_COMPILE_ASSETS . '/player/' . ($location == 'git' ? 'branches' : $location) . '/' . $branch;
+ }
+
+ $this->phonegap = $phonegap;
+ $this->standalone = $standalone || $this->phonegap;
+ $this->appcache = $appcache;
+ $this->widget = !$this->phonegap;
+
+ cubePHP::set_memory('4G');
+
+ if (trim($book_id) == '') {
+ return;
+ }
+ $this->book_id = $book_id;
+ $this->log('Start compilation');
+
+ if (is_null($dir)) {
+ $this->dir = WS_BOOKS . '/html5/' . $book_id . '/';
+ } else {
+ $this->dir = $dir;
+ }
+ $this->vdir = new CubeIT_Files_VirtualDirectory($this->dir);
+ $this->wdir = WS_BOOKS . '/working/' . $this->book_id . '/';
+
+ $this->daoBook = new wsDAOBook($core->con);
+ $this->book = $this->daoBook->selectById($book_id);
+ $this->pages = $this->daoBook->getPagesOfBook($book_id);
+
+
+ $daoTheme = new wsDAOTheme($core->con);
+ $this->theme = $daoTheme->getThemeOfBook($book_id, true);
+ $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/';
+
+ $daoDoc = new wsDAODocument($core->con);
+ $firstDoc = $daoDoc->selectById($this->pages[1]['document_id']);
+ $size = $firstDoc->generalInfos['size'];
+
+ $this->log('Got data from database');
+
+ $this->width = round($size[0], 3);
+ $this->height = round($size[1], 3);
+
+ $imagesize = CubeIT_Image::getimagesize(wsDocument::getDir($this->pages[1]['document_id']) . 'html/h150-' . $this->pages[1]['document_page'] . '.jpg');
+ $this->pdf2htmlRatio = round(($imagesize[0] * 0.48) / $this->width, 3);
+
+ $this->cssScale = $this->z * min($this->optimalWidth / $this->width, $this->optimalHeight / $this->height);
+ $this->cssOneScale = $this->z * min(($this->optimalWidth * 2) / $this->width, $this->optimalHeight / $this->height);
+
+ $this->cssWidth = $this->width * $this->cssScale;
+ $this->cssHeight = $this->height * $this->cssScale;
+
+ $this->cssOneWidth = $this->width * $this->cssOneScale;
+ $this->cssOneHeight = $this->height * $this->cssOneScale;
+
+ $this->cssSVGScale = 1;
+
+ $this->scale = 1;
+ if ($this->book->parametres->zoomMode == 1) {
+ $this->multiply = $this->pdf2htmlRatio * $this->scale * $this->cssOneScale;
+ } else {
+ $this->multiply = $this->pdf2htmlRatio * $this->scale * $this->cssScale;
+ }
+ $this->numerotation = explode(',', $this->book->numerotation);
+
+ $this->initConfig();
+ $this->log('Defined dimensions');
+ }
+
+ public function initConfig()
+ {
+ $this->config = cubeObject::merge($this->book->parametres->toStandardObject(), $this->theme->parametres->toStandardObject());
+ $this->config->rasterizePages = cubeArray::parseRange($this->config->rasterizePages);
+ $this->config->vectorPages = array_diff(cubeArray::parseRange($this->config->vectorPages), $this->config->rasterizePages);
+ }
+
+ public function log($step)
+ {
+ $currenttime = microtime(true);
+ if (null === $this->logfp) {
+ $this->logfp = fopen('/var/log/extranet/htmlconversions/' . $this->book_id . '.log', 'w+');
+ }
+ if (null === $this->logtime) {
+ $this->logtime = $currenttime;
+ }
+ $time = $currenttime - $this->logtime;
+ $log = $step . ' | ' . round($time, 3) . 's' . "\n";
+ fwrite($this->logfp, $log);
+ fflush($this->logfp);
+ $this->logtime = $currenttime;
+ }
+
+ public function addFacebookSDK()
+ {
+ $lang = str_replace('-', '_', $this->book->lang);
+ $e = explode('_', $lang);
+ if (count($e) > 1) {
+ $e[1] = mb_strtoupper($lang);
+ }
+ $lang = implode('_', $e);
+
+ $langsMap = ['fr' => 'fr_FR', 'en' => 'en_US'];
+
+ if (isset($langsMap[$lang])) {
+ $lang = $langsMap[$lang];
+ }
+
+ $this->beginBody[] = "<div id=\"fb-root\"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js.src = 'https://connect.facebook.net/" . $lang . "/sdk.js#xfbml=1&version=v2.11&appId=132006430233560';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>";
- $this->securityPolicyWhitelist[] = '*.facebook.net';
- $this->securityPolicyWhitelist[] = 'data:';
- }
-
- public function addPageLabel($page, $label) {
- $this->pageLabels[$label] = $page;
- }
-
- public function getResolutions() {
- $res = [];
- foreach (self::$resolutions as $r) {
- if ($r > $this->maxRes) {
- continue;
- }
- $res[] = $r;
- }
- if ($this->widget) {
- $res = array_merge(array(36), $res);
- }
- return $res;
- }
-
- public function getCssScale() {
- return $this->cssScale;
- }
-
- public function virtualToPhysical($virtual) {
- if (isset($this->pageLabels[$virtual])) {
- return $virtual;
- }
- if (!in_array($virtual, $this->numerotation)) {
- return 1;
- }
- $p = array_search($virtual, $this->numerotation);
- return $p + 1;
- }
-
- public function compile($delete = true) {
-
- $this->log('Start compile process');
-
- // Raw copy of some directories
- $directories = array('style/fonts', 'images', 'sound', 'video');
- foreach ($directories as $directory) {
- $from = $this->assets . '/' . $directory;
- $this->vdir->copyDirectory($from, $directory);
- }
-
- $this->log('Copied assets');
- $this->loadPlugins();
- $this->log('Plugins loaded');
- $this->writeImages();
- $this->log('Images written');
- $linksCSS = $this->writeLinks();
- $this->log('Links written');
- $this->writeCSS('data/style/style_%d.css', $linksCSS);
- $this->log('CSS written');
- $this->writeLangs();
- $this->log('Langs written');
- $this->writeIndex();
- $this->log('Index written');
- $this->writeSounds();
- $this->log('Sound written');
- $this->writeTexts();
- $this->log('Texts written');
- $this->writeExtras();
- $this->log('Extras written');
- $this->writeJs();
- $this->log('Js written');
- $this->writeSEO();
- $this->vdir->sync($delete);
- $this->log('Files Synced');
- }
-
- protected function loadPlugins() {
- $e = explode("\n", $this->book->parametres->mobilePlugins);
-
- $main = array_pop($this->jsFiles);
-
- $plugins = array();
-
- foreach ($e as $plugin) {
- $plugin = trim($plugin);
- if ($plugin == '') {
- continue;
- }
-
- $d = 'plugins/' . str_replace('.', '/', $plugin);
- $dir = $this->assets . '/' . $d;
- if (!file_exists($dir)) {
- continue;
- }
-
- $plugins[] = $plugin;
-
- if (file_exists($dir . '/plugin.js')) {
- $f = $d . '/plugin.js';
- $this->pluginJs[] = $f;
- $this->vdir->copy($dir . '/plugin.js', $f);
- }
- if (file_exists($dir . '/plugin.css')) {
- $f = $d . '/plugin.css';
- $this->pluginCSS[] = $f;
- $this->vdir->copy($dir . '/plugin.css', $f);
- }
- }
-
- $this->config->plugins = $plugins;
-
- array_push($this->jsFiles, $main);
- }
-
- public function getVideosFormats($poster = true) {
- $res = [];
- //
- // if (!$this->phonegap) {
- // $res = array('ogv', 'webm', 'mp4', 'flv');
- // } elseif ($this->phonegap == 'ios') {
- // $res = array('mp4');
- // } else if ($this->phonegap == 'android') {
- // $res = array('webm', 'mp4');
- // }
-
- $res[] = 'mp4';
-
- if ($poster) {
- $res[] = 'jpg';
- }
- return $res;
- }
-
- /**
- * Helper function to add a unique script entry to the JS stack.
- * Normally this is a relative path but it can be an external URL.
- * External URLs are added to the pluginJs collection instead of jsFiles.
- * Duplicate paths are ignored.
- * @param $path
- */
- public function addJs($path, $collection = null) {
-
- if (null === $collection) {
- // If JS is external, it will be included via the pluginJs collection
- // Otherwise, it will be compiled into the main JS file
- $collection = (preg_match('#^https?://#i', $path) === 1) ? 'pluginJs' : 'jsFiles';
- }
-
- if (!in_array($path, $this->$collection)) {
- $this->{$collection}[] = $path;
- }
- }
-
- /**
- * Helper function to add a unique stylesheet entry to the LESS stack for compilation
- * Duplicate paths are ignored.
- * @param $path The path of the file relative to the /style folder, without any extension
- * @param $extra_files Optional array of extra files that should be copied across for use during LESS compilation
- */
- public function addLess($path) {
- if (!in_array($path, $this->lessFiles)) {
- $this->lessFiles[] = $path;
- }
- }
-
- protected function writeSounds() {
- if ($this->book->parametres->soundTheme == '') {
- return;
- }
- $this->vdir->copyDirectory(WS_SOUNDS . '/' . $this->book->parametres->soundTheme, 'data/sounds');
- }
-
- protected function writeIndex() {
- global $core;
-
- $html = file_get_contents($this->assets . '/_index.html');
- $uhtml = $html;
-
- $titre = $this->book->parametres->title;
-
-
- $daoSignature = new wsDAOSignature($core->con);
- $signature = $daoSignature->selectById($this->book->parametres->signature);
-
- $exportSignature = array('main' => $signature->main,
- 'mainLink' => $signature->mainLink,
- 'partner' => $signature->partner,
- 'partnerLink' => $signature->partnerLink);
-
- $credits = '';
- if ($signature->partner != '') {
- $credits = '<a href="' . $signature->partnerLink . '" target="_blank">' . $signature->partner . '</a> ';
- }
- $credits .= '<a href="' . $signature->mainLink . '" target="_blank">' . $signature->main . '</a>';
-
- $hiddenContents = implode("\n", $this->hiddenContents);
-
- $bgcolor = $this->theme->parametres->loadingBackColor;
-
- // Google analytics
- $ga = '';
- if ($this->book->parametres->googleAnalytics != '') {
- $ga = cubePage::googleAnalytics($this->book->parametres->googleAnalytics);
- }
- if ($this->book->parametres->googleAnalyticsCustom != '') {
- $ga .= $this->book->parametres->googleAnalyticsCustom;
- }
-
- $statsfooter = '';
- if ($this->book->parametres->statsCustom != '') {
- $statsfooter = $this->book->parametres->statsCustom;
- }
- // Feuilles de style
- $sheets = array_merge($this->stylesheets, $this->specialCSS);
-
- $style = array();
- foreach ($sheets as $sheet) {
- $style[] = '<link type="text/css" rel="stylesheet" media="screen" href="' . $sheet . '">';
- }
- $style = implode("\n\t\t", $style);
-
- $pagesContents = '';
-
- $cache = '';
-
- $beginbody = implode("\n", array_unique($this->beginBody));
-
- $iscript = '';
- if (count($this->htmlmultimedia)) {
- $iscript .= '<script type="text/javascript">' . "\n";
- $iscript .= implode("\n", $this->htmlmultimedia);
- $iscript .= '</script>' . "\n";
- }
-
- $script = '';
- $script .= '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>' . "\n";
- $script .= '<script type="text/javascript" charset="utf-8" src="data/fluidbook.js"></script>' . "\n";
- if ($this->book->parametres->scorm_enable) {
- $script .= '<script type="text/javascript" charset="utf-8" src="data/scorm.js"></script>' . "\n";
- $this->writeScorm();
- }
- if (count($this->specialJsFiles)) {
- $script .= '<script type="text/javascript" charset="utf-8" src="data/special.js"></script>' . "\n";
- }
- foreach ($this->pluginJs as $p) {
- $script .= '<script type="text/javascript" charset="utf-8" src="' . $p . '"></script>' . "\n";
- }
- $script .= $iscript;
- $description = '<meta name="description" content="' . html::escapeHTML(isset($this->book->parametres->seoDescription) && $this->book->parametres->seoDescription ? $this->book->parametres->seoDescription : $titre . ' - Powered by Fluidbook') . '">';
-
- $socialTitle = $this->book->parametres->facebook_title ? $this->book->parametres->facebook_title : $titre;
- $socialDescription = $this->book->parametres->seoDescription ? $this->book->parametres->seoDescription : $this->book->parametres->seoDescription;
- $socialImage = 'https://workshop.fluidbook.com/services/facebook_thumbnail?id=' . $this->book_id . '&j=' . time();
- $dim = CubeIT_Image::getimagesize($socialImage);
- $socialImageWidth = $dim[0];
- $socialImageHeight = $dim[1];
-
- $twittercard = '<meta name="twitter:title" content="' . html::escapeHTML($socialTitle) . '">
+ $this->securityPolicyWhitelist[] = '*.facebook.net';
+ $this->securityPolicyWhitelist[] = 'data:';
+ }
+
+ public function addPageLabel($page, $label)
+ {
+ $this->pageLabels[$label] = $page;
+ }
+
+ public function getResolutions()
+ {
+ $res = [];
+ foreach (self::$resolutions as $r) {
+ if ($r > $this->maxRes) {
+ continue;
+ }
+ $res[] = $r;
+ }
+ if ($this->widget) {
+ $res = array_merge(array(36), $res);
+ }
+ return $res;
+ }
+
+ public function getCssScale()
+ {
+ return $this->cssScale;
+ }
+
+ public function virtualToPhysical($virtual)
+ {
+ if (isset($this->pageLabels[$virtual])) {
+ return $virtual;
+ }
+ if (!in_array($virtual, $this->numerotation)) {
+ return 1;
+ }
+ $p = array_search($virtual, $this->numerotation);
+ return $p + 1;
+ }
+
+ public function compile($delete = true)
+ {
+
+ $this->log('Start compile process');
+
+ // Raw copy of some directories
+ $directories = array('style/fonts', 'images', 'sound', 'video');
+ foreach ($directories as $directory) {
+ $from = $this->assets . '/' . $directory;
+ $this->vdir->copyDirectory($from, $directory);
+ }
+
+ $this->log('Copied assets');
+ $this->loadPlugins();
+ $this->log('Plugins loaded');
+ $this->writeImages();
+ $this->log('Images written');
+ $linksCSS = $this->writeLinks();
+ $this->log('Links written');
+ $this->writeCSS('data/style/style_%d.css', $linksCSS);
+ $this->log('CSS written');
+ $this->writeLangs();
+ $this->log('Langs written');
+ $this->writeIndex();
+ $this->log('Index written');
+ $this->writeSounds();
+ $this->log('Sound written');
+ $this->writeTexts();
+ $this->log('Texts written');
+ $this->writeExtras();
+ $this->log('Extras written');
+ $this->writeJs();
+ $this->log('Js written');
+ $this->writeSEO();
+ $this->vdir->sync($delete);
+ $this->log('Files Synced');
+ }
+
+ protected function loadPlugins()
+ {
+ $e = explode("\n", $this->book->parametres->mobilePlugins);
+
+ $main = array_pop($this->jsFiles);
+
+ $plugins = array();
+
+ foreach ($e as $plugin) {
+ $plugin = trim($plugin);
+ if ($plugin == '') {
+ continue;
+ }
+
+ $d = 'plugins/' . str_replace('.', '/', $plugin);
+ $dir = $this->assets . '/' . $d;
+ if (!file_exists($dir)) {
+ continue;
+ }
+
+ $plugins[] = $plugin;
+
+ if (file_exists($dir . '/plugin.js')) {
+ $f = $d . '/plugin.js';
+ $this->pluginJs[] = $f;
+ $this->vdir->copy($dir . '/plugin.js', $f);
+ }
+ if (file_exists($dir . '/plugin.css')) {
+ $f = $d . '/plugin.css';
+ $this->pluginCSS[] = $f;
+ $this->vdir->copy($dir . '/plugin.css', $f);
+ }
+ }
+
+ $this->config->plugins = $plugins;
+
+ array_push($this->jsFiles, $main);
+ }
+
+ public function getVideosFormats($poster = true)
+ {
+ $res = [];
+ //
+ // if (!$this->phonegap) {
+ // $res = array('ogv', 'webm', 'mp4', 'flv');
+ // } elseif ($this->phonegap == 'ios') {
+ // $res = array('mp4');
+ // } else if ($this->phonegap == 'android') {
+ // $res = array('webm', 'mp4');
+ // }
+
+ $res[] = 'mp4';
+
+ if ($poster) {
+ $res[] = 'jpg';
+ }
+ return $res;
+ }
+
+ /**
+ * Helper function to add a unique script entry to the JS stack.
+ * Normally this is a relative path but it can be an external URL.
+ * External URLs are added to the pluginJs collection instead of jsFiles.
+ * Duplicate paths are ignored.
+ * @param $path
+ */
+ public function addJs($path, $collection = null)
+ {
+
+ if (null === $collection) {
+ // If JS is external, it will be included via the pluginJs collection
+ // Otherwise, it will be compiled into the main JS file
+ $collection = (preg_match('#^https?://#i', $path) === 1) ? 'pluginJs' : 'jsFiles';
+ }
+
+ if (!in_array($path, $this->$collection)) {
+ $this->{$collection}[] = $path;
+ }
+ }
+
+ /**
+ * Helper function to add a unique stylesheet entry to the LESS stack for compilation
+ * Duplicate paths are ignored.
+ * @param $path The path of the file relative to the /style folder, without any extension
+ * @param $extra_files Optional array of extra files that should be copied across for use during LESS compilation
+ */
+ public function addLess($path)
+ {
+ if (!in_array($path, $this->lessFiles)) {
+ $this->lessFiles[] = $path;
+ }
+ }
+
+ protected function writeSounds()
+ {
+ if ($this->book->parametres->soundTheme == '') {
+ return;
+ }
+ $this->vdir->copyDirectory(WS_SOUNDS . '/' . $this->book->parametres->soundTheme, 'data/sounds');
+ }
+
+ protected function writeIndex()
+ {
+ global $core;
+
+ $html = file_get_contents($this->assets . '/_index.html');
+ $uhtml = $html;
+
+ $titre = $this->book->parametres->title;
+
+
+ $daoSignature = new wsDAOSignature($core->con);
+ $signature = $daoSignature->selectById($this->book->parametres->signature);
+
+ $exportSignature = array('main' => $signature->main,
+ 'mainLink' => $signature->mainLink,
+ 'partner' => $signature->partner,
+ 'partnerLink' => $signature->partnerLink);
+
+ $credits = '';
+ if ($signature->partner != '') {
+ $credits = '<a href="' . $signature->partnerLink . '" target="_blank">' . $signature->partner . '</a> ';
+ }
+ $credits .= '<a href="' . $signature->mainLink . '" target="_blank">' . $signature->main . '</a>';
+
+ $hiddenContents = implode("\n", $this->hiddenContents);
+
+ $bgcolor = $this->theme->parametres->loadingBackColor;
+
+ // Google analytics
+ $ga = '';
+ if ($this->book->parametres->googleAnalytics != '') {
+ $ga = cubePage::googleAnalytics($this->book->parametres->googleAnalytics);
+ }
+ if ($this->book->parametres->googleAnalyticsCustom != '') {
+ $ga .= $this->book->parametres->googleAnalyticsCustom;
+ }
+
+ $statsfooter = '';
+ if ($this->book->parametres->statsCustom != '') {
+ $statsfooter = $this->book->parametres->statsCustom;
+ }
+ // Feuilles de style
+ $sheets = array_merge($this->stylesheets, $this->specialCSS);
+
+ $style = array();
+ foreach ($sheets as $sheet) {
+ $style[] = '<link type="text/css" rel="stylesheet" media="screen" href="' . $sheet . '">';
+ }
+ $style = implode("\n\t\t", $style);
+
+ $pagesContents = '';
+
+ $cache = '';
+
+ $beginbody = implode("\n", array_unique($this->beginBody));
+
+ $iscript = '';
+ if (count($this->htmlmultimedia)) {
+ $iscript .= '<script type="text/javascript">' . "\n";
+ $iscript .= implode("\n", $this->htmlmultimedia);
+ $iscript .= '</script>' . "\n";
+ }
+
+ $script = '';
+ $script .= '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>' . "\n";
+ $script .= '<script type="text/javascript" charset="utf-8" src="data/fluidbook.js"></script>' . "\n";
+ if ($this->book->parametres->scorm_enable) {
+ $script .= '<script type="text/javascript" charset="utf-8" src="data/scorm.js"></script>' . "\n";
+ $this->writeScorm();
+ }
+ if (count($this->specialJsFiles)) {
+ $script .= '<script type="text/javascript" charset="utf-8" src="data/special.js"></script>' . "\n";
+ }
+ foreach ($this->pluginJs as $p) {
+ $script .= '<script type="text/javascript" charset="utf-8" src="' . $p . '"></script>' . "\n";
+ }
+ $script .= $iscript;
+ $description = '<meta name="description" content="' . html::escapeHTML(isset($this->book->parametres->seoDescription) && $this->book->parametres->seoDescription ? $this->book->parametres->seoDescription : $titre . ' - Powered by Fluidbook') . '">';
+
+ $socialTitle = $this->book->parametres->facebook_title ? $this->book->parametres->facebook_title : $titre;
+ $socialDescription = $this->book->parametres->seoDescription ? $this->book->parametres->seoDescription : $this->book->parametres->seoDescription;
+ $socialImage = 'https://workshop.fluidbook.com/services/facebook_thumbnail?id=' . $this->book_id . '&j=' . time();
+ $dim = CubeIT_Image::getimagesize($socialImage);
+ $socialImageWidth = $dim[0];
+ $socialImageHeight = $dim[1];
+
+ $twittercard = '<meta name="twitter:title" content="' . html::escapeHTML($socialTitle) . '">
<meta name="twitter:description" content="' . html::escapeHTML($socialDescription) . '">
<meta name="twitter:image" content="' . $socialImage . '">
<meta name="twitter:site" content="@Fluidbook">
<meta name="twitter:card" content="summary_large_image">';
- $opengraph = '<meta property="og:title" content="' . html::escapeHTML($socialTitle) . '"/>
+ $opengraph = '<meta property="og:title" content="' . html::escapeHTML($socialTitle) . '"/>
<meta property="og:description" content="' . html::escapeHTML($socialDescription) . '"/>
<meta property="og:image" content="' . $socialImage . '"/>
<meta property="og:image:width" content="' . $socialImageWidth . '"/>
<meta property="og:image:height" content="' . $socialImageHeight . '"/>';
- $favicon = '';
- $hasIos = false;
- if ($this->theme->parametres->iosicon != '') {
- $hasIos = true;
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->iosicon, 'data/apple-touch-icon.png');
- $favicon .= '<link rel="apple-touch-icon" href="data/apple-touch-icon.png" />';
- }
- if ($this->theme->parametres->favicon != '') {
-
- $pngFile = $this->themeRoot . '/' . $this->theme->parametres->favicon;
- $icoFile = $this->themeRoot . '/favicon.ico';
- if (!file_exists($icoFile) || filemtime($icoFile) < filemtime($pngFile) || filemtime(__FILE__) > filemtime($icoFile)) {
- $tmp = CubeIT_Files::tempnam() . '.png';
- $convert = "convert $pngFile -resize 64x64^ -gravity center $tmp";
- `$convert`;
-
- $icotool = new cubeCommandLine('icotool');
- $icotool->setArg('c');
- $icotool->setArg('o', $icoFile);
- $icotool->setArg(null, $tmp);
- $icotool->execute();
-
- unlink($tmp);
- }
- $this->vdir->copy($pngFile, 'data/favicon.png');
- $this->vdir->copy($icoFile, 'data/favicon.ico');
- $favicon .= '<link rel="shortcut icon" href="data/favicon.ico" />';
- $favicon .= '<link rel="icon" type="image/vnd.microsoft.icon" href="data/favicon.ico" />';
- $favicon .= '<link rel="icon" type="image/png" href="data/favicon.png" />';
- if (!$hasIos) {
- $favicon .= '<link rel="apple-touch-icon" href="data/favicon.png" />';
- }
- }
-
- $print = $this->writePrint();
- $message = sprintf($this->__('Your browser is not up to date and is not able to run this publication. %sLearn more%s'), '<br /><a href="http://www.whatbrowser.org/intl/' . $this->config->defaultLang . '/" target="_blank">', '</a>');
-
- $splash = '';
- if ($this->theme->parametres->logoLoader && file_exists($this->themeRoot . $this->theme->parametres->logoLoader)) {
- $dim = CubeIT_Image::getimagesize($this->themeRoot . $this->theme->parametres->logoLoader);
- if ($dim !== false) {
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->logoLoader, 'data/images/' . $this->theme->parametres->logoLoader);
- $splash .= '<div class="logo"><img src="data/images/' . $this->theme->parametres->logoLoader . '" width="' . $dim[0] . '" height="' . $dim[1] . '" alt="" /></div>';
- }
- }
-
- $svgfiles = array($this->assets . '/images/interface.svg', WS_ICONS . '/' . $this->theme->parametres->iconSet . '/interface.svg');
- $svg = '';
- foreach ($svgfiles as $svgfile) {
- if (file_exists($svgfile)) {
- $svg .= file_get_contents($svgfile);
- } else {
- die($svgfile . ' does not exist');
- }
- }
-
- if ($this->phonegap) {
- $csp = "<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: 'unsafe-inline' *; style-src 'self' 'unsafe-inline'; font-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' " . implode(' ', array_unique($this->securityPolicyWhitelist)) . "; img-src * data:\">";
- }
- $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'pagesContents', 'description', 'print', 'hiddenContents', 'splash', 'cache', 'bgcolor', 'message', 'favicon', 'svg', 'beginbody', 'csp', 'opengraph', 'twittercard');
- foreach ($vars as $v) {
- if (isset($$v)) {
- $html = str_replace('<!-- $' . $v . ' -->', $$v, $html);
- } else {
- $html = str_replace('<!-- $' . $v . ' -->', '', $html);
- }
- }
-
- $scripts = array();
- foreach ($this->debugJsFiles as $js) {
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
- }
- foreach ($this->jsFiles as $js) {
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
- }
- foreach ($this->pluginJs as $js) {
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
- }
-
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
- $scripts[] = $iscript;
- $script = implode("\n\t\t", $scripts);
-
- $scripts = array();
- foreach ($this->testJsFiles as $js) {
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
- }
- $scripts[] = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
- $script_test = implode("\n\t\t", $scripts);
-
- $thtml = $uhtml;
-
- $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'pagesContents', 'print', 'hiddenContents', 'splash', 'cache', 'bgcolor', 'message', 'favicon');
- foreach ($vars as $v) {
- $uhtml = str_replace('<!-- $' . $v . ' -->', $$v, $uhtml);
- }
-
- $script .= "\n\t\t" . '<script type="text/javascript" charset="utf-8">window.tester = true;</script>';
- $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'print', 'hiddenContents', 'splash', 'message');
- foreach ($vars as $v) {
- $thtml = str_replace('<!-- $' . $v . ' -->', $$v, $thtml);
- }
-
- $this->vdir->file_put_contents('index.html', $html);
- $this->vdir->file_put_contents('indexu.html', $uhtml);
- $this->vdir->file_put_contents('indext.html', $thtml);
-
- // Write widget html
- if ($this->widget) {
- $whtml = file_get_contents($this->assets . '/widget.html');
- $script = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
- $script .= '<script type="text/javascript" charset="utf-8" src="data/widget.js"></script>';
-
- $style = '<link type="text/css" rel="stylesheet" href="style/widget.css">';
- $vars = array('titre', 'style', 'script');
- foreach ($vars as $v) {
- $whtml = str_replace('<!-- $' . $v . ' -->', $$v, $whtml);
- }
- $this->vdir->file_put_contents('widget.html', $whtml);
- }
- }
-
- function writeSEO() {
- foreach ($this->seoArticles as $seoArticle) {
- $html = file_get_contents($this->assets . '/_seo.html');
- $a = $seoArticle;
- unset($a['image']);
- $a['imageurl'] = 'https://workshop.fluidbook.com/services/facebook_thumbnail?id=15793&j=' . time();
- if ($seoArticle['image']) {
- $a['imageurl'] .= '&image=' . $seoArticle['image'];
- }
- $dim = CubeIT_Image::getimagesize($a['imageurl']);
- $a['imagewidth'] = $dim[0];
- $a['imageheight'] = $dim[1];
- foreach ($a as $k => $v) {
- $html = str_replace('$' . $k, $v, $html);
- }
- $this->vdir->file_put_contents('p/' . $seoArticle['url'], $html);
- }
- }
-
- protected function writeScorm() {
- $manifest = file_get_contents($this->assets . '/_imsmanifest.xml');
- if (!$this->book->parametres->scorm_title) {
- $this->book->parametres->scorm_title = $this->book->parametres->title;
- }
- if (!$this->book->parametres->scorm_id) {
- $this->book->parametres->scorm_id = 'fb_' . $this->book->parametres->id;
- }
- if (!$this->book->parametres->scorm_org) {
- $this->book->parametres->scorm_org = 'Fluidbook';
- }
- $vars = array('scorm_id', 'scorm_org', 'scorm_title');
- foreach ($vars as $v) {
- $manifest = str_replace('$' . $v, $this->book->parametres->$v, $manifest);
- }
- $this->vdir->file_put_contents('imsmanifest.xml', $manifest);
-
- $variables = [];
- $e = CubeIT_Text::explodeNewLines($this->book->parametres->scorm_variables);
- foreach ($e as $item) {
- $item = trim($item);
- if ($item == '') {
- continue;
- }
- $f = explode('=', $item, 2);
- $variables[$f[0]] = $f[1];
- }
- $this->config->scorm_variables = $this->book->parametres->scorm_variables = $variables;
- }
-
- protected function writePrint() {
-
- if (!$this->book->parametres->print && !$this->book->parametres->pdf) {
- return;
- }
-
- $this->vdir->copy(WS_BOOKS . '/final/' . $this->book->book_id . '/data/' . $this->book->parametres->pdfName, 'data/' . $this->book->parametres->pdfName);
- return '';
- }
-
- protected function addFilesInfos($key, $file) {
- if (!file_exists($file)) {
- return;
- }
- if (!isset($this->config->filesInfos)) {
- $this->config->filesInfos = array();
- }
- $infos = array('filesize' => filesize($file));
- $dim = CubeIT_Image::getimagesize($file);
- if ($dim !== false) {
- $infos['width'] = $dim[0];
- $infos['height'] = $dim[1];
- }
- $this->config->filesInfos[$key] = $infos;
- }
-
- protected function __($str) {
- if (!isset($this->config->l10n)) {
- $this->writeLangs();
- }
-
- if (isset($this->config->l10n['default']->$str)) {
- return $this->config->l10n['default']->$str;
- } else {
- return $str;
- }
- }
-
- protected function writeLangs() {
- global $core;
- $daoLang = new wsDAOLang($core->con);
- $lang = $daoLang->selectById($this->book->lang);
- $langs = $daoLang->selectAll();
-
- $traductions = (!count($this->book->traductions)) ? $lang->traductions : $this->book->traductions;
-
- $this->config->l10n = array();
- $this->config->l10n['default'] = $traductions;
- $this->config->defaultLang = $this->book->lang;
-
- foreach ($langs as $lang) {
- $this->config->l10n[$lang->lang_id] = $lang->traductions;
- }
- $iso = l10n::getISOcodes();
- if ($this->book->parametres->multilang != '') {
- $flagsDir = 'images/flags';
- if (!file_exists($flagsDir)) {
- mkdir($flagsDir);
- }
- $ml = str_replace("\r", "\n", $this->book->parametres->multilang);
- $ml = str_replace("\n\n", "\n", $ml);
- $e = explode("\n", $ml);
- $m = array();
- foreach ($e as $l1) {
- $l = explode(',', $l1);
- $flag = $l[1];
-
- $ll = explode('-', $l[0]);
-
- $this->vdir->copy(cubeMedia::getFlagFile($flag), $flagsDir . '/' . $flag . '.png');
- $l[3] = cubeText::ucfirst($iso[$l[0]]);
- $l[4] = cubeCountry::getCountryName($flag, $ll[0]);
- $m[] = implode(',', $l);
- }
-
- $this->config->multilang = implode("\n", $m);
- }
- }
-
- protected function writeExtras() {
- if ($this->theme->parametres->afterSearch != '') {
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->afterSearch, 'data/images/' . $this->theme->parametres->afterSearch);
- }
- if ($this->book->parametres->externalArchives != '') {
- $this->addFilesInfos('archives', $this->wdir . '/' . $this->book->parametres->externalArchives);
- $this->vdir->copy($this->wdir . '/' . $this->book->parametres->externalArchives, 'data/images/' . $this->book->parametres->externalArchives);
- }
-
- if ($this->book->parametres->navExtraImage != '') {
- $this->vdir->copy($this->wdir . '/' . $this->book->parametres->navExtraImage, 'data/images/' . $this->book->parametres->navExtraImage);
- }
-
- if ($this->book->parametres->navExtraImageMobile != '') {
- $this->vdir->copy($this->wdir . '/' . $this->book->parametres->navExtraImageMobile, 'data/images/' . $this->book->parametres->navExtraImageMobile);
- }
-
- for ($i = 1; $i <= 5; $i++) {
- $ic = $this->book->parametres->{'navExtraIcon' . $i};
- if ($ic != '') {
- $this->vdir->copy($this->wdir . '/' . $ic, 'data/images/' . $ic);
- }
- }
-
- }
-
- protected function writeLinks() {
- global $core;
-
- if ($this->book->parametres->customLinkClass == 'WescoSalesLink') {
- $this->specialJsFiles[] = 'js/libs/interact.min.js';
- $this->specialJsFiles[] = 'js/libs/fluidbook/special/wescosales.js';
- $this->specialCSS[] = 'wescosales';
- }
-
- if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
- $this->specialJsFiles[] = 'js/libs/fluidbook/special/atlanticdownload.js';
- $this->specialCSS[] = 'atlanticdownload';
- }
-
- $this->config->links = array();
- $this->config->clinks = array();
- $this->config->bookmarkGroups = array();
-
- $ignore = $this->book->parametres->ignoreLinksTypes;
- if (!$ignore) {
- $ignore = array();
- } else {
- $ignore = split(',', $ignore);
- }
-
- if ($this->book->parametres->externalChaptersHTML != '') {
- $d = $this->unzipFile($this->book->parametres->externalChaptersHTML, false, 'data/chapters/');
- $meta = $this->getConfigZIP($d['dir']);
- $this->config->externalChaptersSize = new stdClass();
- $this->config->externalChaptersSize->width = $meta['width'];
- $this->config->externalChaptersSize->height = $meta['height'];
- $this->vdir->copyDirectory($d['dir'], $d['fdir']);
- }
-
- $daoDoc = new wsDAODocument($core->con);
- $daoDoc->getLinksAndRulers($this->book_id, $links, $rulers);
-
- // Custom landing page content
- if ($this->book->parametres->landingPage != '') {
- $d = $this->unzipFile($this->book->parametres->landingPage, false, 'data/landing-page/');
- $this->vdir->copyDirectory($d['dir'], $d['fdir']);
- }
-
- if ($this->book->parametres->tabsHTML5 != '') {
- $links[] = [
- 'page' => 'background',
- 'top' => 0,
- 'left' => 0,
- 'width' => 100,
- 'height' => 100,
- 'type' => 6,
- 'to' => $this->book->parametres->tabsHTML5,
- 'alternative' => $this->book->parametres->tabsHTML5,
- 'image' => '',
- 'inline' => 1,
- 'interactive' => 1,
- 'class' => 'tabslink',
- ];
- }
-
-
- foreach ($links as $linkData) {
- if (isset($linkData['image']) && $linkData['image'] && $linkData['type'] != 28) {
- $dupData = $linkData;
- $dupData['image'] = '';
- $dupData['to'] = $linkData['image'];
- $dupData['type'] = 15;
- array_push($links, $dupData);
- }
- }
-
- $i = 0;
- $pages = array();
- $cpages = array();
- $css = array();
-
- usort($links, array($this, '_sortLinks'));
-
- foreach ($links as $linkData) {
- if (in_array($linkData['type'], $ignore)) {
- continue;
- }
- if ($linkData['type'] == 28) {
- $this->addSEOArticle($linkData['page'], $linkData['to'], $linkData['extra'], $linkData['image']);
- continue;
- }
- $link = wsHTML5Link::getInstance($this->base62($i), $linkData, $this);
- if (is_null($link)) {
- continue;
- }
-
- // Make old "aftersearch" link compatible with new "extra" menu option by extracting link URL
- if ($link->page == 'aftersearch') {
- $this->config->afterSearchLink = $link->to;
- $this->config->afterSearchTooltip = $link->infobulle;
- }
-
-
- $c = $link->getHTMLContainer();
- $css[] = $link->getCSSContainer();
- if (!isset($pages[$link->page])) {
- $pages[$link->page] = '';
- $cpages[$link->page] = '';
- }
- if ($link instanceof contentLink) {
- $cpages[$link->page] .= $c;
- } else {
- $pages[$link->page] .= $c;
- }
-
- if ($link->keep()) {
- $this->hiddenContents[] = $c;
- }
- $i++;
- }
-
- $allpages = range(0, $this->book->parametres->pages + 1);
- if ($this->book->parametres->themeEnableAfterSearch) {
- $allpages[] = 'aftersearch';
- }
- $allpages[] = 'background';
- $allpages[] = 'archives';
-
- foreach ($allpages as $i) {
-
- $c = '';
- $cc = '';
- if (isset($pages[$i])) {
- $c = $pages[$i];
- }
- if (isset($cpages[$i])) {
- $cc = $cpages[$i];
- }
- $this->config->links[$i] = $c;
- $this->config->clinks[$i] = $cc;
- }
- return $css;
- }
-
- public function addSEOArticle($page, $title, $intro, $image) {
- $this->seoArticles[$title] = ['title' => $title, 'description' => $intro, 'image' => $image, 'content' => '', 'page' => $page, 'url' => CubeIT_Text::str2URL($title) . '.html'];
- }
-
- public function _sortLinks($a, $b) {
- $priorities = array(26 => 1);
-
- $pa = isset($priorities[$a['type']]) ? $priorities[$a['type']] : 0;
- $pb = isset($priorities[$b['type']]) ? $priorities[$b['type']] : 0;
- return $pb - $pa;
- }
-
- public function addBookmarkGroup($link) {
- if ($link['left'] > $this->book->parametres->width) {
- //$link['page']++;
- }
- if ($link['page'] <= 0 || $link['page'] > $this->book->parametres->pages) {
- return;
- }
-
- $this->config->bookmarkGroups[] = array('page' => ($link['page']), 'nb' => $link['to'], 'name' => $link['extra']);
- }
-
- public function addAudiodescription($link) {
- $this->config->audiodescription[$link['page']] = $link['to'];
- $this->copyLinkFile($link['to'], 'data/audiodescription/');
- }
-
- protected function writeJs() {
- $config = $this->writeConfig();
- $this->vdir->file_put_contents('data/datas.js', $config);
- $finals = array('fluidbook' => $this->jsFiles);
- if ($this->book->parametres->scorm_enable) {
- $finals['scorm'] = array();
- $finals['scorm'][] = 'js/libs/scorm/apiwrapper.js';
- $finals['scorm'][] = 'js/libs/scorm/scorm.js';
- }
- if (count($this->specialJsFiles)) {
- $finals['special'] = $this->specialJsFiles;
- }
- if ($this->widget) {
- $finals['widget'] = $this->widgetJsFiles;
- }
-
- foreach ($finals as $jsfinal => $files) {
- $mintime = 0;
- $hash = hash('sha256', json_encode($files));
- $minimized = $this->assets . '/js/min/' . $jsfinal . '-' . $hash . '-min.js';
- if (!file_exists(dirname($minimized))) {
- mkdir(dirname($minimized));
- }
- if (file_exists($minimized)) {
- $mintime = filemtime($minimized);
- $reminimize = false;
- } else {
- $mintime = 0;
- $reminimize = true;
- }
-
- if (!$reminimize) {
- foreach ($files as $file) {
- if (filemtime($this->assets . '/' . $file) > $mintime) {
- $reminimize = true;
- break;
- }
- }
- }
-
- if (!$reminimize) {
- if (filemtime(__FILE__) > $mintime || (file_exists(__DIR__ . '/class.ws.html5.links.php') && filemtime(__DIR__ . '/class.ws.html5.links.php') > $mintime)) {
- $reminimize = true;
- }
- }
-
- if ($reminimize) {
- $js = '';
- foreach ($files as $file) {
- $js .= file_get_contents($this->assets . '/' . $file);
- $js .= ";\n\n";
- }
- $tmp = cubeFiles::tempnam();
- file_put_contents($tmp, $js);
-
- unlink($minimized);
-
- $uglify = new CubeIT_CommandLine('/usr/local/bin/uglifyjs');
- $uglify->setArg('o', $minimized);
- $uglify->setArg(null, $tmp);
- $uglify->execute();
- $uglify->debug();
-
- if (!file_exists($minimized)) {
- die('An error occured while uglifying : ' . $uglify->output);
- }
- }
- $dest = 'data/' . $jsfinal . '.js';
- $this->vdir->copy($minimized, $dest);
- }
-
-
- if ($this->phonegap) {
- $this->vdir->copy(WS_COMPILE_ASSETS . '/_html5/js/libs/phonegap/' . $this->phonegapVersion . '/cordova-' . $this->phonegap . '.js', 'data/cordova.js');
- }
-
- }
-
- public function writeTexts() {
- $this->daoBook->makeTextsIndexes($this->book, $this->pages, $index, $textes, true);
- $this->vdir->file_put_contents('data/search.index.js', 'var INDEX=' . $index . ';' . "\r");
- if ($this->book->parametres->highlightResults) {
- $this->vdir->file_put_contents('data/search.highlight.js', 'var HIGHLIGHTS=' . json_encode($this->daoBook->makeHighlightIndex($this->book, $this->pages)) . ";\r");
- }
- }
-
- public function supportSVG() {
- if (!$this->phonegap) {
- return false;
- } else if ($this->phonegap == 'ios') {
- return true;
- } else {
- return false;
- }
- }
-
- protected function writeConfig() {
- $this->config->numerotation = explode(',', $this->book->numerotation);
- $this->config->id = $this->book->book_id;
- $this->config->cid = $this->book->cid;
- $this->config->cacheDate = TIME;
- $this->config->width = $this->cssWidth;
- $this->config->height = $this->cssHeight;
- $this->config->optimalWidth = $this->optimalWidth;
- $this->config->optimalHeight = $this->optimalHeight;
- $this->config->chapters = $this->book->chapters;
- $this->config->videoFormats = $this->getVideosFormats(false);
- $this->config->htmlmultimedia = $this->htmlmultimedia;
- $this->config->phonegap = $this->phonegap;
- $this->config->retinaResolution = min($this->book->parametres->maxResolution, $this->maxRes);
- $this->config->pageLabels = $this->pageLabels;
- $this->config->pageZoomFactor = $this->z;
- $this->config->multiply = $this->multiply;
- $this->config->cssScale = $this->cssScale;
- $this->config->pdfZoomFactor = $this->pdf2htmlRatio;
- if ($this->home) {
- $this->config->home = 'http://home';
- }
- $this->config->multiApp = $this->multiApp;
- foreach ($this->additionalConfig as $k => $v) {
- $this->config->$k = $v;
- }
- if ($this->phonegap && ($this->book->parametres->offlineLink == '' || $this->book->parametres->offlineLink == 'http://')) {
- $this->config->share = false;
- }
-
- // We need to be able to reference both navOrder and navOrderH so convert both to arrays
- // We also make sure there are no empty items in the arrays (see: http://php.net/manual/en/function.array-filter.php#111091)
- $this->config->navOrder = array_filter(array_map('trim', explode(',', $this->config->navOrder)), 'strlen');
- $this->config->navOrderH = array_filter(array_map('trim', explode(',', $this->config->navOrderH)), 'strlen');
-
- $this->config->standalone = $this->standalone;
- if ($this->config->phonegap) {
- $this->config->manifest = $this->writeManifest();
- }
-
- if ($this->config->basket) {
- if (file_exists($this->config->basketReferences) || CubeIT_Util_Url::isDistant($this->config->basketReferences)) {
- $referencesFile = $this->config->basketReferences;
- } else {
- $referencesFile = $this->wdir . '/commerce/' . $this->config->basketReferences;
- }
-
- if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
- $ext = CubeIT_Files::getExtension($referencesFile);
- if ($ext == 'xlsx') {
- $this->config->basketReferences = wsUtil::excelToArray($referencesFile);
- if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
- $this->config->basketReferences = wsUtil::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy"));
- }
- }
- $this->log("Done cart references");
- }
- }
- $this->config->seoArticles = $this->seoArticles;
-
- return 'var DATAS=' . json_encode($this->config) . ';' . "\n";
- }
-
- protected function writeManifest() {
- $res = array();
- }
-
- protected function writeIcons() {
- $res = array();
- // Get the colors used to colorize graphics
- if ($this->theme->parametres->colorizeIcons) {
- $couleurI = $this->theme->parametres->couleurI;
- } else {
- $couleurI = 'FFFFFF';
- }
-
- $couleurM = $this->theme->parametres->subTextColor;
-
- $bookmarksDisabledColors = array('star' => $this->theme->parametres->bookmarkStarDisabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor);
- $bookmarksEnabledColors = array('star' => $this->theme->parametres->bookmarkStarEnabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor);
- $subTextColor = $this->theme->parametres->subTextColor;
-
- $arrowsColor = $this->theme->parametres->arrowsColor;
- // Set the icon list with the color
- $icons = array('interface-down' => $arrowsColor, 'interface-close' => $arrowsColor,
- 'interface-audio-description-on' => $arrowsColor, 'interface-audio-description-off' => $arrowsColor,
- 'help-fingers' => $couleurI, 'help-mouse' => $couleurI,
- 'bookmark-left-off' => $bookmarksDisabledColors, 'bookmark-left-on' => $bookmarksEnabledColors,
- 'bookmark-right-off' => $bookmarksDisabledColors, 'bookmark-right-on' => $bookmarksEnabledColors
- );
-
- $this->config->iconsDimensions = array();
- $makepng = !$this->supportSVG();
- $tmpdir = CubeIT_Files::tmpdir();
- foreach ($icons as $icon => $color) {
- wsTools::colorizeAndRasterizeIcon($this->theme->parametres->iconSet, $icon, $color, $tmpdir, 4, $w, $h);
- $this->config->iconsDimensions[$icon] = array($w, $h);
- }
- $this->vdir->copyDirectory($tmpdir, 'data/images');
- $this->vdir->addTemp($tmpdir);
- return $res;
- }
-
- protected function writeImages() {
- global $core;
-
- switch ($this->book->parametres->mobileVersion) {
- case 'html5-desktop':
- $this->backgroundsPrefix = array('t', 'p');
- $this->svg = true;
- break;
- case 'html5-images':
- $this->backgroundsPrefix = array('t');
- $this->svg = false;
- break;
- default:
- $this->backgroundsPrefix = array('p');
- $this->svg = true;
- break;
- }
-
- $thumbs = array();
- foreach ($this->pages as $page => $infos) {
- $docdir = wsDocument::getDir($infos['document_id']);
- if ($this->svg) {
- $full = $docdir . 'html/fp' . $infos['document_page'] . '.svg';
- $fullopt = $docdir . 'html/fo' . $infos['document_page'] . '%s.svg';
- $orig = $docdir . 'html/tp' . $infos['document_page'] . '.svg';
- $opt = $docdir . 'html/to' . $infos['document_page'] . '.svg';
-
- if (!file_exists($full) || filemtime($full) < 1503671520) {
- if (!isset($doc) || $doc->document_id != $infos['document_id']) {
- $dao = new wsDAODocument($core->con);
- $doc = $dao->selectById($infos['document_id']);
- }
- $doc->makeSVGFile($infos['document_page']);
- }
- wsDocument::extractTexts($full, $orig);
- wsTools::optimizeSVG($orig, $opt);
- wsTools::optimizeSVG($full, $fullopt, [150, 300]);
-
- if (in_array($page, $this->config->vectorPages)) {
- $this->vdir->copy(str_replace('%s', '-150', $fullopt), 'data/contents/p' . $page . '.svg');
- } else {
- $this->vdir->copy($opt, 'data/contents/p' . $page . '.svg');
- }
- }
-
-
- foreach ($this->getResolutions() as $r) {
- foreach ($this->backgroundsPrefix as $backgroundsPrefix) {
- $srcPrefix = $backgroundsPrefix;
- if ($backgroundsPrefix == 'p') {
- $srcPrefix = 'h';
- }
- $ok = $this->vdir->copy($docdir . 'html/' . $srcPrefix . $r . '-' . $infos['document_page'] . '.jpg', 'data/background/' . $r . '/' . $backgroundsPrefix . $page . '.jpg');
- if (!$ok && $r = 300) {
- $this->maxRes = 150;
- }
- }
- }
-
- $thumb = false;
- if ($this->book->parametres->pdfThumbnails) {
- $thumb = wsPDFConvert::getThumbFromPDF(WS_BOOKS . '/working/' . $this->book->book_id . '/' . $this->book->parametres->pdfThumbnails, $page);
- }
- if (!$thumb) {
- $thumb = $docdir . 'p' . $infos['document_page'] . '.jpg';
- }
-
- $thumbs[$page] = $thumb;
- $this->vdir->copy($thumb, 'data/thumbnails/p' . $page . '.jpg');
-
- if ($page == 1) {
- $this->_makeCover($docdir . 'html/t36-' . $infos['document_page'] . '.jpg');
- }
-
- $this->log('Copied image ' . $page);
- }
-
-
- $this->makeThumbSprites($thumbs);
- $this->log('Made thumbnails');
- }
-
- public function makeThumbSprites(array $thumbs) {
- $cols = 10;
- $rows = 10;
- $perSprite = $cols * $rows;
- $k = 0;
- $res = '';
- $pages = count($thumbs);
-
- $hash = '';
- for ($i = 1; $i <= $pages; $i += $perSprite) {
- $num = min(1 + $pages - $i, $perSprite);
- $srows = ceil($num / $cols);
- $files = array();
- $mtime = 0;
- for ($j = 0; $j < $perSprite; $j++) {
- $p = $i + $j;
- if ($p > $pages) {
- break;
- }
- $files[] = $thumbs[$p];
- $hash .= $thumbs[$p] . '--' . filemtime($thumbs[$p]);
- }
-
- $cache = WS_CACHE . '/thumbsprites/' . hash('sha256', $hash) . '.jpg';
- $dest = 'data/thumbnails/s' . $k . '.jpg';
- if (!file_exists($cache)) {
- $ratio = $this->width / $this->height;
- $thumbh = round(100 / $ratio);
- $cmd = 'montage ' . implode(' ', $files) . ' -geometry 100x' . $thumbh . '!+0+0 -background transparent -tile ' . $cols . 'x' . $srows . ' ' . $cache;
- $res .= `$cmd`;
- }
- $this->vdir->copy($cache, $dest);
- $k++;
- }
- return $res;
- }
-
- protected function _makeCover($orig) {
- $size = CubeIT_Image::getimagesize($orig);
- $w = $size[0];
- $h = $size[1];
-
- $tmp = cubeFiles::tempnam() . '.png';
-
- $c = new cubeCommandLine('convert');
- $c->setArg(null, ROOT . '/images/ws/shade-cover-app.png');
- $c->setManualArg('-resize ' . round($w / 3) . 'x' . $h);
- $c->setArg(null, $tmp);
- $c->execute();
-
- $res = cubeFiles::tempnam() . '.jpg';
-
- $convert = new cubeCommandLine('composite');
- $cmd = '-compose Multiply ';
- $cmd .= $tmp . ' ' . $orig . ' ';
- $cmd .= $res;
- $convert->setManualArg($cmd);
- $convert->execute();
-
- $this->vdir->copy($res, 'cover.jpg', true);
-
- unlink($tmp);
- }
-
- protected function _lessBoolean($val) {
- return $val ? 'true' : 'false';
- }
-
- protected function writeCSS($file, $links) {
- $res = array();
-
- $lessContents = '';
-
- $lessVariables = array();
- $lessVariables['slider-display'] = $this->_lessBoolean($this->theme->parametres->pagesBar);
- $lessVariables['slider-thumb-background'] = wsHTML5::colorToCSS($this->theme->parametres->pageBarThumbBack);
-
- // General theme
- $cssWidth = $this->cssWidth;
- $cssHeight = $this->cssHeight;
- $cssScale = $this->cssScale;
- $w2 = ($cssWidth * 2) . 'px';
-
-
- $h = $cssHeight . 'px';
-
- $wm = ($this->width * $this->multiply) . 'px';
- $hm = ($this->height * $this->multiply) . 'px';
- $w = $cssWidth . 'px';
- $offsetLeft = round(($this->optimalWidth - $cssWidth) / 2, 3);
- $offsetLeft2 = $offsetLeft * 2;
- $offsetTop = round(($this->optimalHeight - $cssHeight) / 2, 3);
- $navTop = ($cssHeight - 40 - 100) / 2;
- $leftOfRightPage = (floor($cssWidth) - 1) . 'px';
-
- $lessVariables['z'] = $this->z;
- $lessVariables['book-page-width'] = $w;
- $lessVariables['book-page-height'] = $h;
- $lessVariables['book-page-ratio'] = floatval($w) / floatval($h);
-
- $lessVariables['shadow-opacity'] = wsHTML5::colorToArray($this->theme->parametres->bookShadeColor)['opacity'] * 1.2;
- $lessVariables['edges-display'] = $this->_lessBoolean($this->theme->parametres->usePageEdges);
-
- $res[] = '.portrait #pages,.portrait .doublePage.page,.page,.doublePage._3d{width:' . $w . ';max-width:' . $w . ';height:' . $h . ';max-height:' . $h . '}';
- $res[] = '.doublePage,#pages,#links,#searchHighlights{width:' . $w2 . ';max-width:' . $w2 . ';height:' . $h . ';max-height:' . $h . '}';
- $res[] = '.landscape .doublePage._2d.axis_x.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(' . $w2 . ',0,0)') . '}';
- $res[] = '.landscape .doublePage._2d.axis_x.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(-' . $w2 . ',0,0)') . '}';
- $res[] = '.portrait .doublePage._2d.axis_x.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(' . $w . ',0,0)') . '}';
- $res[] = '.portrait .doublePage._2d.axis_x.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(-' . $w . ',0,0)') . '}';
- $res[] = '.doublePage._2d.axis_y.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(0,' . $h . ',0)') . '}';
- $res[] = '.doublePage._2d.axis_y.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(0,-' . $h . ',0)') . '}';
-
- $res[] = '.doublePage._3d{left:' . $w . ';}';
- $res[] = '#links.right{left:-' . $w . ';}';
- $res[] = '.landscape .page.right{left:' . $w . '}';
-
- $lessVariables['page-number-color'] = wsHTML5::colorToCSS($this->theme->parametres->colorPageNumber);
- $lessVariables['display-page-number'] = $this->_lessBoolean($this->theme->parametres->displayPageNumber);
- $lessVariables['page-transition-duration'] = $this->book->parametres->mobileTransitionDuration . 's';
-
-
- $res[] = '.background{width:100%;height:100%}';
-
- if ($this->cssSVGScale != 1) {
- $texts = '.texts{' . wsHTML5::writeCSSUA('transform-origin', 'top left') . ';';
- $texts .= wsHTML5::writeCSSUA('transform', 'scale(' . round((1 / $this->multiply) * $cssScale * $this->cssSVGScale, 3) . ')') . ';';
- $texts .= 'width:' . ($wm / $this->cssSVGScale) . 'px; max-width:' . ($wm / $this->cssSVGScale) . 'px;';
- $texts .= 'height:' . ($hm / $this->cssSVGScale) . 'px; max-height:' . ($hm / $this->cssSVGScale) . 'px;';
- $texts .= '}';
- } else {
- $texts = '.texts{width:' . floor(floatval($w) + 4) . 'px;height:' . floor(floatval($h) + 4) . 'px;}';
- }
- $res[] = $texts;
-
- // Theme
- $shade = '.page .shade{';
- $shade .= 'opacity:' . min(($this->theme->parametres->shadeAlpha * 2) / 100, 1) . ';';
- $shade .= '}';
- $res[] = $shade;
-
- // SVG
- $res[] = 'svg .fill-c-menu-back{fill:' . wsHTML5::colorToCSS($this->theme->parametres->couleurB) . ';}';
- $res[] = 'svg .fill-c-menu-text{fill:' . wsHTML5::colorToCSS($this->theme->parametres->subTextColor) . ';}';
-
- // Background
- $res[] = $this->_cssBackground();
-
- // Archives
- // Header
- $header = 'header{';
- $header .= 'height:' . $this->theme->parametres->menuHeight . 'px;';
- if ($this->theme->parametres->menuImage != '') {
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->menuImage, 'data/images/' . $this->theme->parametres->menuImage);
- $header .= 'background-image:url(../images/' . $this->theme->parametres->menuImage . ');';
- $header .= 'background-repeat:no-repeat;';
- $header .= 'background-size:100% ' . $this->theme->parametres->menuHeight . 'px;';
- } else {
- $header .= 'background-color:' . wsHTML5::colorToCSS($this->theme->parametres->menuColor) . ';';
- }
- $header .= '}';
- $res[] = $header;
-
- //Icons
- $res = array_merge($res, $this->writeIcons());
- $res[] = '#nav #locales{background-color:' . wsHTML5::colorToCSS($this->theme->parametres->couleurI) . ';}';
-
- // Logo
- $logo = '#logo{';
- if ($this->theme->parametres->logo) {
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->logo, 'data/images/' . $this->theme->parametres->logo);
- $dim = CubeIT_Image::getimagesize($this->themeRoot . '/' . $this->theme->parametres->logo);
- $logo .= 'background-image:url(../images/' . $this->theme->parametres->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;';
- }
- $logo .= '}';
- $res[] = $logo;
-
- // Credits
- $res[] = 'footer,footer a{color:' . wsHTML5::colorToCSS($this->theme->parametres->creditsColor) . ';}';
-
- // Arrows
- $lessVariables['arrows-background'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
- $lessVariables['arrows-color'] = wsHTML5::colorToCSS($this->theme->parametres->arrowsColor);
-
- // Loader
- $lessVariables['loader-background-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
- $lessVariables['loader-foreground-color'] = wsHTML5::colorToCSS($this->theme->parametres->arrowsColor);
-
- // Audio description buttons
- $lessVariables['audiodescription-background'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
- $lessVariables['audiodescription-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
-
- // Links Styles
- $lessVariables['links-color'] = wsHTML5::colorToCSS($this->theme->parametres->linksColor);
- $res = array_merge($res, $links);
-
- // Bookmarks
- if (!isset($this->book->parametres->bookmarkCornerSize)) {
- $this->book->parametres->bookmarkCornerSize = 10;
- }
- $lessVariables['bookmark-corner-size'] = round($this->width * $this->book->parametres->bookmarkCornerSize * 0.0075 * $this->z) . 'px';
- $lessVariables['bookmark-corner-offset'] = $this->book->parametres->bookmarkOffset . 'px';
-
- // Menus
- $menuColor = new CubeIT_Graphics_Color($this->theme->parametres->couleurB);
- $menuColor->setAlpha(1);
- $menuTextColor = wsHTML5::colorToCSS($this->theme->parametres->subTextColor);
- $menuBreakpoint = empty($this->book->parametres->menuBreakpoint) ? '1023px' : $this->book->parametres->menuBreakpoint;
-
- $lessVariables['menu-breakpoint'] = $menuBreakpoint;
- $lessVariables['menu-background'] = $menuColor->toCSS();
- if ($this->theme->parametres->subSecondaryColor) {
- $lessVariables['menu-button-background'] = wsHTML5::colorToCSS($this->theme->parametres->subSecondaryColor);
- } else {
- $lessVariables['menu-background-green'] = 'max(45, min(255-45, green(@menu-background)))';
- $lessVariables['menu-background-red'] = 'max(45, min(255-45, red(@menu-background)))';
- $lessVariables['menu-background-blue'] = 'max(45, min(255-45, blue(@menu-background)))';
- $lessVariables['menu-button-background'] = 'overlay(rgb(@menu-background-red, @menu-background-green, @menu-background-blue), #c0c0c0)';
- }
-
- $lessVariables['menu-text'] = $menuTextColor;
- $lessVariables['menu-field-background'] = wsHTML5::colorToCSS($this->theme->parametres->subFieldColor);
- $lessVariables['menu-field-text'] = wsHTML5::colorToCSS($this->theme->parametres->subTextFieldColor);
- $lessVariables['menu-select-background'] = wsHTML5::colorToCSS($this->theme->parametres->subSelectColor);
- $lessVariables['menu-select-text'] = wsHTML5::colorToCSS($this->theme->parametres->subTextSelectColor);
- $lessVariables['icon-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurI);
- $lessVariables['menu-overlay'] = wsHTML5::colorToCSS($this->theme->parametres->popupVideoOverlay);
-
- // Chapters
-
-
- foreach ($this->book->chapters as $chapter) {
- if (substr($chapter->page, 0, 1) != '#') {
- continue;
- }
- if ($chapter->color == '') {
- continue;
- }
- $color = trim($chapter->color, '#');
- $lessContents .= '.mview.c_' . $color . '{.menu-color(#' . $color . ');}';
- }
-
- // Archives
- if ($this->book->parametres->externalArchivesBack) {
- $this->vdir->copy($this->wdir . '/' . $this->book->parametres->externalArchivesBack, 'data/images/' . $this->book->parametres->externalArchivesBack);
- $res[] = '.mview.archives{background-image:url("../images/' . $this->book->parametres->externalArchivesBack . '");}';
- }
-
- # Index
- $ratio = $this->width / $this->height;
- $thumbh = round(100 / $ratio);
- $this->config->thumbHeight = $thumbh;
- $lessVariables['thumb-height'] = $thumbh . 'px';
-
- #tooltip
- $lessVariables['tooltip-background'] = wsHTML5::colorToCSS($this->theme->parametres->tooltipBackColor);
- $lessVariables['tooltip-color'] = wsHTML5::colorToCSS($this->theme->parametres->tooltipTextColor);
-
- # ZoomPopup close button background
- $res[] = '.zoomPopupClose {background-color:' . wsHTML5::colorToCSS($this->theme->parametres->couleurB) . ';}';
-
-
- $this->_writeLess($lessVariables, $lessContents);
-
- $res = array_chunk($res, 3500);
- foreach ($res as $k => $css) {
- $this->stylesheets[] = 'data/style/style_' . $k . '.css';
- $this->vdir->file_put_contents(sprintf($file, $k), implode("\n", $css));
- $this->log('Write CSS ' . sprintf($file, $k));
- }
- return count($res);
- }
-
- protected function _writeLess($variables, $lessContents = '') {
- if ($this->widget) {
- $this->lessFiles[] = 'widget';
- }
- foreach ($this->specialCSS as $s) {
- $this->lessFiles[] = 'special/' . $s;
- }
-
- $tmp = CubeIT_Files::tmpdir();
-
- $from = $this->assets . '/style/*';
- `cp -r $from $tmp`;
-
- $bookVariables = array();
- foreach ($variables as $k => $v) {
- $bookVariables[] = '@' . trim($k) . ':' . $v . ';';
- }
- file_put_contents($tmp . '/book-variables.less', implode("\n", $bookVariables));
- file_put_contents($tmp . '/additional.less', $lessContents);
-
- foreach ($this->lessFiles as $f) {
- $source_less = $this->assets . '/style/' . $f . '.less';
- $destination_less = $tmp . '/' . $f . '.less';
- $destination_css = $tmp . '/' . $f . '.css';
-
- if (!file_exists($source_less)) {
- continue;
- }
-
- // LESS file might be in a subfolder, so create if it doesn't exist
- if (!is_dir(dirname($destination_less))) {
- mkdir(dirname($destination_less), 0777, true);
- }
-
- // Less files must be copied to temporary directory so they'll
- // have access to the variables generated in book-variables.less
- copy($source_less, $destination_less);
- $less = new CubeIT_CommandLine('/usr/local/bin/lessc');
- $less->setArg(null, $destination_less);
- $less->setArg(null, $destination_css);
- $less->execute();
- $less->debug();
- if (!file_exists($destination_css)) {
- die($less->output);
- }
- $this->vdir->copy($destination_css, 'style/' . $f . '.css');
- if ($f != 'widget') {
- $this->stylesheets[] = 'style/' . $f . '.css';
- }
- }
- }
-
- protected function _cssBackground() {
- $body = '#background,#splash{';
- $body .= 'background-color:#' . $this->theme->parametres->backgroundColor . ' !important;';
- switch ($this->theme->parametres->repeat) {
- case wsTheme::REPEAT:
- $body .= 'background-repeat:repeat;';
- break;
- case wsTheme::NONE:
- $body .= 'background-repeat:no-repeat;';
- break;
- case wsTheme::RATIO:
- $body .= 'background-repeat:no-repeat;';
- $body .= 'background-size:cover;';
- break;
- case wsTheme::STRETCH:
- $body .= 'background-repeat:no-repeat;';
- $body .= 'background-size:100% 100%;';
- break;
- }
- if ($this->theme->parametres->backgroundImage != '') {
- $bi = $this->themeRoot . '/' . $this->theme->parametres->backgroundImage;
- if (file_exists($bi)) {
- $dbi = CubeIT_Image::getimagesize($bi);
- $this->config->backgroundImageDimensions = array('width' => $dbi[0], 'height' => $dbi[1]);
- }
-
- $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->backgroundImage, 'data/images/' . $this->theme->parametres->backgroundImage);
- $body .= 'background-image:url(../images/' . $this->theme->parametres->backgroundImage . ');';
- $body .= 'background-position:';
-
- switch ($this->theme->parametres->backgroundVAlign) {
- case wsTheme::TOP:
- $body .= 'top';
- break;
- case wsTheme::MIDDLE:
- $body .= 'center';
- break;
- case wsTheme::BOTTOM:
- $body .= 'bottom';
- break;
- }
- $body .= ' ';
- switch ($this->theme->parametres->backgroundHAlign) {
- case wsTheme::LEFT:
- $body .= 'left';
- break;
- case wsTheme::CENTER:
- $body .= 'center';
- break;
- case wsTheme::RIGHT:
- $body .= 'right';
- break;
- }
- $body .= ';';
- }
-
- $body .= '}';
-
- return $body;
- }
-
- public static function writeCSSUA($property, $value) {
- $res = array();
- foreach (self::$uaPrefixes as $prefix) {
- $res[] = $prefix . $property . ':' . $value;
- }
- return implode(';', $res);
- }
-
- protected function base62($val) {
- $chars = '0123456789abcdefghijklmnopqrstuvwxyz';
- $base = strlen($chars);
- $str = '';
- do {
- $i = $val % $base;
- $str = $chars[$i] . $str;
- $val = ($val - $i) / $base;
- } while ($val > 0);
- return $str;
- }
-
- public function copyLinkDir($source, $dest) {
- $this->vdir->copyDirectory($source, $dest);
- }
-
- public function simpleCopyLinkFile($source, $dest, $addVdir = true) {
- if ($addVdir) {
- $dest = $dest;
- }
-
- $this->vdir->copy($source, $dest);
- }
-
- public function copyLinkFile($source, $dest, $video = false) {
- if ($video && $this->book->parametres->mobileVideosPath != '') {
-
- }
-
- $origDir = $this->wdir;
- $types = $this->getVideosFormats();
- if ($video) {
- wsTools::encodeWebVideos($origDir . $source, null, true);
- $e = explode('.', $source);
- array_pop($e);
- $base = implode('.', $e);
- $source = array();
- foreach ($types as $type) {
- $source[] = $base . '.' . $type;
- }
- }
-
- if (!is_array($source)) {
- $source = array($source);
- }
-
- foreach ($source as $so) {
- $s = $origDir . $so;
- if (file_exists($s)) {
- $d = $dest . '/' . $so;
- $this->simpleCopyLinkFile($s, $d, false);
- }
- }
- }
-
- public function __destruct() {
-
- }
-
-
- public function unzipFile($file, $moveAssets = false, $baseDir = null) {
- $fdir = is_null($baseDir) ? 'data/links/' . str_replace('.', '_', $file) : $baseDir;
-
- $tmp = CubeIT_Files::tmpdir();
- $dir = $tmp . '/' . $fdir;
- if (file_exists($dir) && is_file($dir)) {
- unlink($dir);
- }
- if (!file_exists($dir)) {
- mkdir($dir, 0777, true);
- }
- $unzip = new cubeCommandLine('unzip');
- $unzip->setArg(null, $this->wdir . '/' . $file);
- $unzip->setArg('d', $dir);
- $unzip->execute();
-
- if ($moveAssets) {
- `mv $dir/Assets/* $dir`;
- rmdir($dir . '/Assets');
- }
-
- return array('dir' => $dir, 'fdir' => $fdir);
- }
-
- public function getConfigZIP($d) {
- $res = array('width' => 0, 'height' => 0);
- if (file_exists($d . '/index.html')) {
- $doc = new DOMDocument();
- $doc->loadHTMLFile($d . '/index.html');
- $xpath = new DOMXPath($doc);
- $c = $xpath->query("//canvas");
- foreach ($c as $canvas) {
- /* @var $canvas DOMElement */
- $res['width'] = intval((string)$canvas->getAttribute('width'));
- $res['height'] = intval((string)$canvas->getAttribute('height'));
- }
-
- $r = array('html' => 'index.html', 'inject' => array(), 'injectcss' => array(), 'injectjs' => array());
- } else {
- $r = array('html' => false, 'inject' => array(file_get_contents($d . '/init.js')), 'injectcss' => array('multimedia.css'), 'injectjs' => array('multimedia.js'));
- }
- $res = array_merge($res, $r);
- return $res;
- }
+ $favicon = '';
+ $hasIos = false;
+ if ($this->theme->parametres->iosicon != '') {
+ $hasIos = true;
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->iosicon, 'data/apple-touch-icon.png');
+ $favicon .= '<link rel="apple-touch-icon" href="data/apple-touch-icon.png" />';
+ }
+ if ($this->theme->parametres->favicon != '') {
+
+ $pngFile = $this->themeRoot . '/' . $this->theme->parametres->favicon;
+ $icoFile = $this->themeRoot . '/favicon.ico';
+ if (!file_exists($icoFile) || filemtime($icoFile) < filemtime($pngFile) || filemtime(__FILE__) > filemtime($icoFile)) {
+ $tmp = CubeIT_Files::tempnam() . '.png';
+ $convert = "convert $pngFile -resize 64x64^ -gravity center $tmp";
+ `$convert`;
+
+ $icotool = new cubeCommandLine('icotool');
+ $icotool->setArg('c');
+ $icotool->setArg('o', $icoFile);
+ $icotool->setArg(null, $tmp);
+ $icotool->execute();
+
+ unlink($tmp);
+ }
+ $this->vdir->copy($pngFile, 'data/favicon.png');
+ $this->vdir->copy($icoFile, 'data/favicon.ico');
+ $favicon .= '<link rel="shortcut icon" href="data/favicon.ico" />';
+ $favicon .= '<link rel="icon" type="image/vnd.microsoft.icon" href="data/favicon.ico" />';
+ $favicon .= '<link rel="icon" type="image/png" href="data/favicon.png" />';
+ if (!$hasIos) {
+ $favicon .= '<link rel="apple-touch-icon" href="data/favicon.png" />';
+ }
+ }
+
+ $print = $this->writePrint();
+ $message = sprintf($this->__('Your browser is not up to date and is not able to run this publication. %sLearn more%s'), '<br /><a href="http://www.whatbrowser.org/intl/' . $this->config->defaultLang . '/" target="_blank">', '</a>');
+
+ $splash = '';
+ if ($this->theme->parametres->logoLoader && file_exists($this->themeRoot . $this->theme->parametres->logoLoader)) {
+ $dim = CubeIT_Image::getimagesize($this->themeRoot . $this->theme->parametres->logoLoader);
+ if ($dim !== false) {
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->logoLoader, 'data/images/' . $this->theme->parametres->logoLoader);
+ $splash .= '<div class="logo"><img src="data/images/' . $this->theme->parametres->logoLoader . '" width="' . $dim[0] . '" height="' . $dim[1] . '" alt="" /></div>';
+ }
+ }
+
+ $svgfiles = array($this->assets . '/images/interface.svg', WS_ICONS . '/' . $this->theme->parametres->iconSet . '/interface.svg');
+ $svg = '';
+ foreach ($svgfiles as $svgfile) {
+ if (file_exists($svgfile)) {
+ $svg .= file_get_contents($svgfile);
+ } else {
+ die($svgfile . ' does not exist');
+ }
+ }
+
+ if ($this->phonegap) {
+ $csp = "<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: 'unsafe-inline' *; style-src 'self' 'unsafe-inline'; font-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' " . implode(' ', array_unique($this->securityPolicyWhitelist)) . "; img-src * data:\">";
+ }
+ $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'pagesContents', 'description', 'print', 'hiddenContents', 'splash', 'cache', 'bgcolor', 'message', 'favicon', 'svg', 'beginbody', 'csp', 'opengraph', 'twittercard');
+ foreach ($vars as $v) {
+ if (isset($$v)) {
+ $html = str_replace('<!-- $' . $v . ' -->', $$v, $html);
+ } else {
+ $html = str_replace('<!-- $' . $v . ' -->', '', $html);
+ }
+ }
+
+ $scripts = array();
+ foreach ($this->debugJsFiles as $js) {
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
+ }
+ foreach ($this->jsFiles as $js) {
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
+ }
+ foreach ($this->pluginJs as $js) {
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
+ }
+
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
+ $scripts[] = $iscript;
+ $script = implode("\n\t\t", $scripts);
+
+ $scripts = array();
+ foreach ($this->testJsFiles as $js) {
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="' . $js . '"></script>';
+ }
+ $scripts[] = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
+ $script_test = implode("\n\t\t", $scripts);
+
+ $thtml = $uhtml;
+
+ $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'pagesContents', 'print', 'hiddenContents', 'splash', 'cache', 'bgcolor', 'message', 'favicon');
+ foreach ($vars as $v) {
+ $uhtml = str_replace('<!-- $' . $v . ' -->', $$v, $uhtml);
+ }
+
+ $script .= "\n\t\t" . '<script type="text/javascript" charset="utf-8">window.tester = true;</script>';
+ $vars = array('titre', 'credits', 'statsfooter', 'ga', 'style', 'script', 'print', 'hiddenContents', 'splash', 'message');
+ foreach ($vars as $v) {
+ $thtml = str_replace('<!-- $' . $v . ' -->', $$v, $thtml);
+ }
+
+ $this->vdir->file_put_contents('index.html', $html);
+ $this->vdir->file_put_contents('indexu.html', $uhtml);
+ $this->vdir->file_put_contents('indext.html', $thtml);
+
+ // Write widget html
+ if ($this->widget) {
+ $whtml = file_get_contents($this->assets . '/widget.html');
+ $script = '<script type="text/javascript" charset="utf-8" src="data/datas.js"></script>';
+ $script .= '<script type="text/javascript" charset="utf-8" src="data/widget.js"></script>';
+
+ $style = '<link type="text/css" rel="stylesheet" href="style/widget.css">';
+ $vars = array('titre', 'style', 'script');
+ foreach ($vars as $v) {
+ $whtml = str_replace('<!-- $' . $v . ' -->', $$v, $whtml);
+ }
+ $this->vdir->file_put_contents('widget.html', $whtml);
+ }
+ }
+
+ function writeSEO()
+ {
+ foreach ($this->seoArticles as $seoArticle) {
+ $html = file_get_contents($this->assets . '/_seo.html');
+ $a = $seoArticle;
+ unset($a['image']);
+ $a['imageurl'] = 'https://workshop.fluidbook.com/services/facebook_thumbnail?id=15793&j=' . time();
+ if ($seoArticle['image']) {
+ $a['imageurl'] .= '&image=' . $seoArticle['image'];
+ }
+ $dim = CubeIT_Image::getimagesize($a['imageurl']);
+ $a['imagewidth'] = $dim[0];
+ $a['imageheight'] = $dim[1];
+ foreach ($a as $k => $v) {
+ $html = str_replace('$' . $k, $v, $html);
+ }
+ $this->vdir->file_put_contents('p/' . $seoArticle['url'], $html);
+ }
+ }
+
+ protected function writeScorm()
+ {
+ $manifest = file_get_contents($this->assets . '/_imsmanifest.xml');
+ if (!$this->book->parametres->scorm_title) {
+ $this->book->parametres->scorm_title = $this->book->parametres->title;
+ }
+ if (!$this->book->parametres->scorm_id) {
+ $this->book->parametres->scorm_id = 'fb_' . $this->book->parametres->id;
+ }
+ if (!$this->book->parametres->scorm_org) {
+ $this->book->parametres->scorm_org = 'Fluidbook';
+ }
+ $vars = array('scorm_id', 'scorm_org', 'scorm_title');
+ foreach ($vars as $v) {
+ $manifest = str_replace('$' . $v, $this->book->parametres->$v, $manifest);
+ }
+ $this->vdir->file_put_contents('imsmanifest.xml', $manifest);
+
+ $variables = [];
+ $e = CubeIT_Text::explodeNewLines($this->book->parametres->scorm_variables);
+ foreach ($e as $item) {
+ $item = trim($item);
+ if ($item == '') {
+ continue;
+ }
+ $f = explode('=', $item, 2);
+ $variables[$f[0]] = $f[1];
+ }
+ $this->config->scorm_variables = $this->book->parametres->scorm_variables = $variables;
+ }
+
+ protected function writePrint()
+ {
+
+ if (!$this->book->parametres->print && !$this->book->parametres->pdf) {
+ return;
+ }
+
+ $this->vdir->copy(WS_BOOKS . '/final/' . $this->book->book_id . '/data/' . $this->book->parametres->pdfName, 'data/' . $this->book->parametres->pdfName);
+ return '';
+ }
+
+ protected function addFilesInfos($key, $file)
+ {
+ if (!file_exists($file)) {
+ return;
+ }
+ if (!isset($this->config->filesInfos)) {
+ $this->config->filesInfos = array();
+ }
+ $infos = array('filesize' => filesize($file));
+ $dim = CubeIT_Image::getimagesize($file);
+ if ($dim !== false) {
+ $infos['width'] = $dim[0];
+ $infos['height'] = $dim[1];
+ }
+ $this->config->filesInfos[$key] = $infos;
+ }
+
+ protected function __($str)
+ {
+ if (!isset($this->config->l10n)) {
+ $this->writeLangs();
+ }
+
+ if (isset($this->config->l10n['default']->$str)) {
+ return $this->config->l10n['default']->$str;
+ } else {
+ return $str;
+ }
+ }
+
+ protected function writeLangs()
+ {
+ global $core;
+ $daoLang = new wsDAOLang($core->con);
+ $lang = $daoLang->selectById($this->book->lang);
+ $langs = $daoLang->selectAll();
+
+ $traductions = (!count($this->book->traductions)) ? $lang->traductions : $this->book->traductions;
+
+ $this->config->l10n = array();
+ $this->config->l10n['default'] = $traductions;
+ $this->config->defaultLang = $this->book->lang;
+
+ foreach ($langs as $lang) {
+ $this->config->l10n[$lang->lang_id] = $lang->traductions;
+ }
+ $iso = l10n::getISOcodes();
+ if ($this->book->parametres->multilang != '') {
+ $flagsDir = 'images/flags';
+ if (!file_exists($flagsDir)) {
+ mkdir($flagsDir);
+ }
+ $ml = str_replace("\r", "\n", $this->book->parametres->multilang);
+ $ml = str_replace("\n\n", "\n", $ml);
+ $e = explode("\n", $ml);
+ $m = array();
+ foreach ($e as $l1) {
+ $l = explode(',', $l1);
+ $flag = $l[1];
+
+ $ll = explode('-', $l[0]);
+
+ $this->vdir->copy(cubeMedia::getFlagFile($flag), $flagsDir . '/' . $flag . '.png');
+ $l[3] = cubeText::ucfirst($iso[$l[0]]);
+ $l[4] = cubeCountry::getCountryName($flag, $ll[0]);
+ $m[] = implode(',', $l);
+ }
+
+ $this->config->multilang = implode("\n", $m);
+ }
+ }
+
+ protected function writeExtras()
+ {
+ if ($this->theme->parametres->afterSearch != '') {
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->afterSearch, 'data/images/' . $this->theme->parametres->afterSearch);
+ }
+ if ($this->book->parametres->externalArchives != '') {
+ $this->addFilesInfos('archives', $this->wdir . '/' . $this->book->parametres->externalArchives);
+ $this->vdir->copy($this->wdir . '/' . $this->book->parametres->externalArchives, 'data/images/' . $this->book->parametres->externalArchives);
+ }
+
+ if ($this->book->parametres->navExtraImage != '') {
+ $this->vdir->copy($this->wdir . '/' . $this->book->parametres->navExtraImage, 'data/images/' . $this->book->parametres->navExtraImage);
+ }
+
+ if ($this->book->parametres->navExtraImageMobile != '') {
+ $this->vdir->copy($this->wdir . '/' . $this->book->parametres->navExtraImageMobile, 'data/images/' . $this->book->parametres->navExtraImageMobile);
+ }
+
+ for ($i = 1; $i <= 5; $i++) {
+ $ic = $this->book->parametres->{'navExtraIcon' . $i};
+ if ($ic != '') {
+ $this->vdir->copy($this->wdir . '/' . $ic, 'data/images/' . $ic);
+ }
+ }
+
+ }
+
+ protected function writeLinks()
+ {
+ global $core;
+
+ if ($this->book->parametres->customLinkClass == 'WescoSalesLink') {
+ $this->specialJsFiles[] = 'js/libs/interact.min.js';
+ $this->specialJsFiles[] = 'js/libs/fluidbook/special/wescosales.js';
+ $this->specialCSS[] = 'wescosales';
+ }
+
+ if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
+ $this->specialJsFiles[] = 'js/libs/fluidbook/special/atlanticdownload.js';
+ $this->specialCSS[] = 'atlanticdownload';
+ }
+
+ $this->config->links = array();
+ $this->config->clinks = array();
+ $this->config->bookmarkGroups = array();
+
+ $ignore = $this->book->parametres->ignoreLinksTypes;
+ if (!$ignore) {
+ $ignore = array();
+ } else {
+ $ignore = split(',', $ignore);
+ }
+
+ if ($this->book->parametres->externalChaptersHTML != '') {
+ $d = $this->unzipFile($this->book->parametres->externalChaptersHTML, false, 'data/chapters/');
+ $meta = $this->getConfigZIP($d['dir']);
+ $this->config->externalChaptersSize = new stdClass();
+ $this->config->externalChaptersSize->width = $meta['width'];
+ $this->config->externalChaptersSize->height = $meta['height'];
+ $this->vdir->copyDirectory($d['dir'], $d['fdir']);
+ }
+
+ $daoDoc = new wsDAODocument($core->con);
+ $daoDoc->getLinksAndRulers($this->book_id, $links, $rulers);
+
+ // Custom landing page content
+ if ($this->book->parametres->landingPage != '') {
+ $d = $this->unzipFile($this->book->parametres->landingPage, false, 'data/landing-page/');
+ $this->vdir->copyDirectory($d['dir'], $d['fdir']);
+ }
+
+ if ($this->book->parametres->tabsHTML5 != '') {
+ $links[] = [
+ 'page' => 'background',
+ 'top' => 0,
+ 'left' => 0,
+ 'width' => 100,
+ 'height' => 100,
+ 'type' => 6,
+ 'to' => $this->book->parametres->tabsHTML5,
+ 'alternative' => $this->book->parametres->tabsHTML5,
+ 'image' => '',
+ 'inline' => 1,
+ 'interactive' => 1,
+ 'class' => 'tabslink',
+ ];
+ }
+
+
+ foreach ($links as $linkData) {
+ if (isset($linkData['image']) && $linkData['image'] && $linkData['type'] != 28) {
+ $dupData = $linkData;
+ $dupData['image'] = '';
+ $dupData['to'] = $linkData['image'];
+ $dupData['type'] = 15;
+ array_push($links, $dupData);
+ }
+ }
+
+ $i = 0;
+ $pages = array();
+ $cpages = array();
+ $css = array();
+
+ usort($links, array($this, '_sortLinks'));
+
+ foreach ($links as $linkData) {
+ if (in_array($linkData['type'], $ignore)) {
+ continue;
+ }
+ if ($linkData['type'] == 28) {
+ $this->addSEOArticle($linkData['page'], $linkData['to'], $linkData['extra'], $linkData['image']);
+ continue;
+ }
+ $link = wsHTML5Link::getInstance($this->base62($i), $linkData, $this);
+ if (is_null($link)) {
+ continue;
+ }
+
+ // Make old "aftersearch" link compatible with new "extra" menu option by extracting link URL
+ if ($link->page == 'aftersearch') {
+ $this->config->afterSearchLink = $link->to;
+ $this->config->afterSearchTooltip = $link->infobulle;
+ }
+
+
+ $c = $link->getHTMLContainer();
+ $css[] = $link->getCSSContainer();
+ if (!isset($pages[$link->page])) {
+ $pages[$link->page] = '';
+ $cpages[$link->page] = '';
+ }
+ if ($link instanceof contentLink) {
+ $cpages[$link->page] .= $c;
+ } else {
+ $pages[$link->page] .= $c;
+ }
+
+ if ($link->keep()) {
+ $this->hiddenContents[] = $c;
+ }
+ $i++;
+ }
+
+ $allpages = range(0, $this->book->parametres->pages + 1);
+ if ($this->book->parametres->themeEnableAfterSearch) {
+ $allpages[] = 'aftersearch';
+ }
+ $allpages[] = 'background';
+ $allpages[] = 'archives';
+
+ foreach ($allpages as $i) {
+
+ $c = '';
+ $cc = '';
+ if (isset($pages[$i])) {
+ $c = $pages[$i];
+ }
+ if (isset($cpages[$i])) {
+ $cc = $cpages[$i];
+ }
+ $this->config->links[$i] = $c;
+ $this->config->clinks[$i] = $cc;
+ }
+ return $css;
+ }
+
+ public function addSEOArticle($page, $title, $intro, $image)
+ {
+ $this->seoArticles[$title] = ['title' => $title, 'description' => $intro, 'image' => $image, 'content' => '', 'page' => $page, 'url' => CubeIT_Text::str2URL($title) . '.html'];
+ }
+
+ public function _sortLinks($a, $b)
+ {
+ $priorities = array(26 => 1);
+
+ $pa = isset($priorities[$a['type']]) ? $priorities[$a['type']] : 0;
+ $pb = isset($priorities[$b['type']]) ? $priorities[$b['type']] : 0;
+ return $pb - $pa;
+ }
+
+ public function addBookmarkGroup($link)
+ {
+ if ($link['left'] > $this->book->parametres->width) {
+ //$link['page']++;
+ }
+ if ($link['page'] <= 0 || $link['page'] > $this->book->parametres->pages) {
+ return;
+ }
+
+ $this->config->bookmarkGroups[] = array('page' => ($link['page']), 'nb' => $link['to'], 'name' => $link['extra']);
+ }
+
+ public function addAudiodescription($link)
+ {
+ $this->config->audiodescription[$link['page']] = $link['to'];
+ $this->copyLinkFile($link['to'], 'data/audiodescription/');
+ }
+
+ protected function writeJs()
+ {
+ $config = $this->writeConfig();
+ $this->vdir->file_put_contents('data/datas.js', $config);
+ $finals = array('fluidbook' => $this->jsFiles);
+ if ($this->book->parametres->scorm_enable) {
+ $finals['scorm'] = array();
+ $finals['scorm'][] = 'js/libs/scorm/apiwrapper.js';
+ $finals['scorm'][] = 'js/libs/scorm/scorm.js';
+ }
+ if (count($this->specialJsFiles)) {
+ $finals['special'] = $this->specialJsFiles;
+ }
+ if ($this->widget) {
+ $finals['widget'] = $this->widgetJsFiles;
+ }
+
+ foreach ($finals as $jsfinal => $files) {
+ $mintime = 0;
+ $hash = hash('sha256', json_encode($files));
+ $minimized = $this->assets . '/js/min/' . $jsfinal . '-' . $hash . '-min.js';
+ if (!file_exists(dirname($minimized))) {
+ mkdir(dirname($minimized));
+ }
+ if (file_exists($minimized)) {
+ $mintime = filemtime($minimized);
+ $reminimize = false;
+ } else {
+ $mintime = 0;
+ $reminimize = true;
+ }
+
+ if (!$reminimize) {
+ foreach ($files as $file) {
+ if (filemtime($this->assets . '/' . $file) > $mintime) {
+ $reminimize = true;
+ break;
+ }
+ }
+ }
+
+ if (!$reminimize) {
+ if (filemtime(__FILE__) > $mintime || (file_exists(__DIR__ . '/class.ws.html5.links.php') && filemtime(__DIR__ . '/class.ws.html5.links.php') > $mintime)) {
+ $reminimize = true;
+ }
+ }
+
+ if ($reminimize) {
+ $js = '';
+ foreach ($files as $file) {
+ $js .= file_get_contents($this->assets . '/' . $file);
+ $js .= ";\n\n";
+ }
+ $tmp = cubeFiles::tempnam();
+ file_put_contents($tmp, $js);
+
+ unlink($minimized);
+
+ $uglify = new CubeIT_CommandLine('/usr/local/bin/uglifyjs');
+ $uglify->setArg('o', $minimized);
+ $uglify->setArg(null, $tmp);
+ $uglify->execute();
+ $uglify->debug();
+
+ if (!file_exists($minimized)) {
+ die('An error occured while uglifying : ' . $uglify->output);
+ }
+ }
+ $dest = 'data/' . $jsfinal . '.js';
+ $this->vdir->copy($minimized, $dest);
+ }
+
+
+ if ($this->phonegap) {
+ $this->vdir->copy(WS_COMPILE_ASSETS . '/_html5/js/libs/phonegap/' . $this->phonegapVersion . '/cordova-' . $this->phonegap . '.js', 'data/cordova.js');
+ }
+
+ }
+
+ public function writeTexts()
+ {
+ $this->daoBook->makeTextsIndexes($this->book, $this->pages, $index, $textes, true);
+ $this->vdir->file_put_contents('data/search.index.js', 'var INDEX=' . $index . ';' . "\r");
+ if ($this->book->parametres->highlightResults) {
+ $this->vdir->file_put_contents('data/search.highlight.js', 'var HIGHLIGHTS=' . json_encode($this->daoBook->makeHighlightIndex($this->book, $this->pages)) . ";\r");
+ }
+ if ($this->book->parametres->searchWordSelectionAlgorithm == 'expression') {
+ $this->vdir->file_put_contents('data/search.texts.js', 'var TEXTS=' . $textes . ";\r");
+ }
+ }
+
+ public function supportSVG()
+ {
+ if (!$this->phonegap) {
+ return false;
+ } else if ($this->phonegap == 'ios') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected function writeConfig()
+ {
+ $this->config->numerotation = explode(',', $this->book->numerotation);
+ $this->config->id = $this->book->book_id;
+ $this->config->cid = $this->book->cid;
+ $this->config->cacheDate = TIME;
+ $this->config->width = $this->cssWidth;
+ $this->config->height = $this->cssHeight;
+ $this->config->optimalWidth = $this->optimalWidth;
+ $this->config->optimalHeight = $this->optimalHeight;
+ $this->config->chapters = $this->book->chapters;
+ $this->config->videoFormats = $this->getVideosFormats(false);
+ $this->config->htmlmultimedia = $this->htmlmultimedia;
+ $this->config->phonegap = $this->phonegap;
+ $this->config->retinaResolution = min($this->book->parametres->maxResolution, $this->maxRes);
+ $this->config->pageLabels = $this->pageLabels;
+ $this->config->pageZoomFactor = $this->z;
+ $this->config->multiply = $this->multiply;
+ $this->config->cssScale = $this->cssScale;
+ $this->config->pdfZoomFactor = $this->pdf2htmlRatio;
+ if ($this->home) {
+ $this->config->home = 'http://home';
+ }
+ $this->config->multiApp = $this->multiApp;
+ foreach ($this->additionalConfig as $k => $v) {
+ $this->config->$k = $v;
+ }
+ if ($this->phonegap && ($this->book->parametres->offlineLink == '' || $this->book->parametres->offlineLink == 'http://')) {
+ $this->config->share = false;
+ }
+
+ // We need to be able to reference both navOrder and navOrderH so convert both to arrays
+ // We also make sure there are no empty items in the arrays (see: http://php.net/manual/en/function.array-filter.php#111091)
+ $this->config->navOrder = array_filter(array_map('trim', explode(',', $this->config->navOrder)), 'strlen');
+ $this->config->navOrderH = array_filter(array_map('trim', explode(',', $this->config->navOrderH)), 'strlen');
+
+ $this->config->standalone = $this->standalone;
+ if ($this->config->phonegap) {
+ $this->config->manifest = $this->writeManifest();
+ }
+
+ if ($this->config->basket) {
+ if (file_exists($this->config->basketReferences) || CubeIT_Util_Url::isDistant($this->config->basketReferences)) {
+ $referencesFile = $this->config->basketReferences;
+ } else {
+ $referencesFile = $this->wdir . '/commerce/' . $this->config->basketReferences;
+ }
+
+ if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) {
+ $ext = CubeIT_Files::getExtension($referencesFile);
+ if ($ext == 'xlsx') {
+ $this->config->basketReferences = wsUtil::excelToArray($referencesFile);
+ if ($this->book->parametres->customLinkClass == 'AtlanticDownloadLink') {
+ $this->config->basketReferences = wsUtil::atlanticReferences($this->config->basketReferences, 'local/', array($this, 'log'), array($this->vdir, "copy"));
+ }
+ }
+ $this->log("Done cart references");
+ }
+ }
+ $this->config->seoArticles = $this->seoArticles;
+
+ return 'var DATAS=' . json_encode($this->config) . ';' . "\n";
+ }
+
+ protected function writeManifest()
+ {
+ $res = array();
+ }
+
+ protected function writeIcons()
+ {
+ $res = array();
+ // Get the colors used to colorize graphics
+ if ($this->theme->parametres->colorizeIcons) {
+ $couleurI = $this->theme->parametres->couleurI;
+ } else {
+ $couleurI = 'FFFFFF';
+ }
+
+ $couleurM = $this->theme->parametres->subTextColor;
+
+ $bookmarksDisabledColors = array('star' => $this->theme->parametres->bookmarkStarDisabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor);
+ $bookmarksEnabledColors = array('star' => $this->theme->parametres->bookmarkStarEnabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor);
+ $subTextColor = $this->theme->parametres->subTextColor;
+
+ $arrowsColor = $this->theme->parametres->arrowsColor;
+ // Set the icon list with the color
+ $icons = array('interface-down' => $arrowsColor, 'interface-close' => $arrowsColor,
+ 'interface-audio-description-on' => $arrowsColor, 'interface-audio-description-off' => $arrowsColor,
+ 'help-fingers' => $couleurI, 'help-mouse' => $couleurI,
+ 'bookmark-left-off' => $bookmarksDisabledColors, 'bookmark-left-on' => $bookmarksEnabledColors,
+ 'bookmark-right-off' => $bookmarksDisabledColors, 'bookmark-right-on' => $bookmarksEnabledColors
+ );
+
+ $this->config->iconsDimensions = array();
+ $makepng = !$this->supportSVG();
+ $tmpdir = CubeIT_Files::tmpdir();
+ foreach ($icons as $icon => $color) {
+ wsTools::colorizeAndRasterizeIcon($this->theme->parametres->iconSet, $icon, $color, $tmpdir, 4, $w, $h);
+ $this->config->iconsDimensions[$icon] = array($w, $h);
+ }
+ $this->vdir->copyDirectory($tmpdir, 'data/images');
+ $this->vdir->addTemp($tmpdir);
+ return $res;
+ }
+
+ protected function writeImages()
+ {
+ global $core;
+
+ switch ($this->book->parametres->mobileVersion) {
+ case 'html5-desktop':
+ $this->backgroundsPrefix = array('t', 'p');
+ $this->svg = true;
+ break;
+ case 'html5-images':
+ $this->backgroundsPrefix = array('t');
+ $this->svg = false;
+ break;
+ default:
+ $this->backgroundsPrefix = array('p');
+ $this->svg = true;
+ break;
+ }
+
+ $thumbs = array();
+ foreach ($this->pages as $page => $infos) {
+ $docdir = wsDocument::getDir($infos['document_id']);
+ if ($this->svg) {
+ $full = $docdir . 'html/fp' . $infos['document_page'] . '.svg';
+ $fullopt = $docdir . 'html/fo' . $infos['document_page'] . '%s.svg';
+ $orig = $docdir . 'html/tp' . $infos['document_page'] . '.svg';
+ $opt = $docdir . 'html/to' . $infos['document_page'] . '.svg';
+
+ if (!file_exists($full) || filemtime($full) < 1503671520) {
+ if (!isset($doc) || $doc->document_id != $infos['document_id']) {
+ $dao = new wsDAODocument($core->con);
+ $doc = $dao->selectById($infos['document_id']);
+ }
+ $doc->makeSVGFile($infos['document_page']);
+ }
+ wsDocument::extractTexts($full, $orig);
+ wsTools::optimizeSVG($orig, $opt);
+ wsTools::optimizeSVG($full, $fullopt, [150, 300]);
+
+ if (in_array($page, $this->config->vectorPages)) {
+ $this->vdir->copy(str_replace('%s', '-150', $fullopt), 'data/contents/p' . $page . '.svg');
+ } else {
+ $this->vdir->copy($opt, 'data/contents/p' . $page . '.svg');
+ }
+ }
+
+
+ foreach ($this->getResolutions() as $r) {
+ foreach ($this->backgroundsPrefix as $backgroundsPrefix) {
+ $srcPrefix = $backgroundsPrefix;
+ if ($backgroundsPrefix == 'p') {
+ $srcPrefix = 'h';
+ }
+ $ok = $this->vdir->copy($docdir . 'html/' . $srcPrefix . $r . '-' . $infos['document_page'] . '.jpg', 'data/background/' . $r . '/' . $backgroundsPrefix . $page . '.jpg');
+ if (!$ok && $r = 300) {
+ $this->maxRes = 150;
+ }
+ }
+ }
+
+ $thumb = false;
+ if ($this->book->parametres->pdfThumbnails) {
+ $thumb = wsPDFConvert::getThumbFromPDF(WS_BOOKS . '/working/' . $this->book->book_id . '/' . $this->book->parametres->pdfThumbnails, $page);
+ }
+ if (!$thumb) {
+ $thumb = $docdir . 'p' . $infos['document_page'] . '.jpg';
+ }
+
+ $thumbs[$page] = $thumb;
+ $this->vdir->copy($thumb, 'data/thumbnails/p' . $page . '.jpg');
+
+ if ($page == 1) {
+ $this->_makeCover($docdir . 'html/t36-' . $infos['document_page'] . '.jpg');
+ }
+
+ $this->log('Copied image ' . $page);
+ }
+
+
+ $this->makeThumbSprites($thumbs);
+ $this->log('Made thumbnails');
+ }
+
+ public function makeThumbSprites(array $thumbs)
+ {
+ $cols = 10;
+ $rows = 10;
+ $perSprite = $cols * $rows;
+ $k = 0;
+ $res = '';
+ $pages = count($thumbs);
+
+ $hash = '';
+ for ($i = 1; $i <= $pages; $i += $perSprite) {
+ $num = min(1 + $pages - $i, $perSprite);
+ $srows = ceil($num / $cols);
+ $files = array();
+ $mtime = 0;
+ for ($j = 0; $j < $perSprite; $j++) {
+ $p = $i + $j;
+ if ($p > $pages) {
+ break;
+ }
+ $files[] = $thumbs[$p];
+ $hash .= $thumbs[$p] . '--' . filemtime($thumbs[$p]);
+ }
+
+ $cache = WS_CACHE . '/thumbsprites/' . hash('sha256', $hash) . '.jpg';
+ $dest = 'data/thumbnails/s' . $k . '.jpg';
+ if (!file_exists($cache)) {
+ $ratio = $this->width / $this->height;
+ $thumbh = round(100 / $ratio);
+ $cmd = 'montage ' . implode(' ', $files) . ' -geometry 100x' . $thumbh . '!+0+0 -background transparent -tile ' . $cols . 'x' . $srows . ' ' . $cache;
+ $res .= `$cmd`;
+ }
+ $this->vdir->copy($cache, $dest);
+ $k++;
+ }
+ return $res;
+ }
+
+ protected function _makeCover($orig)
+ {
+ $size = CubeIT_Image::getimagesize($orig);
+ $w = $size[0];
+ $h = $size[1];
+
+ $tmp = cubeFiles::tempnam() . '.png';
+
+ $c = new cubeCommandLine('convert');
+ $c->setArg(null, ROOT . '/images/ws/shade-cover-app.png');
+ $c->setManualArg('-resize ' . round($w / 3) . 'x' . $h);
+ $c->setArg(null, $tmp);
+ $c->execute();
+
+ $res = cubeFiles::tempnam() . '.jpg';
+
+ $convert = new cubeCommandLine('composite');
+ $cmd = '-compose Multiply ';
+ $cmd .= $tmp . ' ' . $orig . ' ';
+ $cmd .= $res;
+ $convert->setManualArg($cmd);
+ $convert->execute();
+
+ $this->vdir->copy($res, 'cover.jpg', true);
+
+ unlink($tmp);
+ }
+
+ protected function _lessBoolean($val)
+ {
+ return $val ? 'true' : 'false';
+ }
+
+ protected function writeCSS($file, $links)
+ {
+ $res = array();
+
+ $lessContents = '';
+
+ $lessVariables = array();
+ $lessVariables['slider-display'] = $this->_lessBoolean($this->theme->parametres->pagesBar);
+ $lessVariables['slider-thumb-background'] = wsHTML5::colorToCSS($this->theme->parametres->pageBarThumbBack);
+
+ // General theme
+ $cssWidth = $this->cssWidth;
+ $cssHeight = $this->cssHeight;
+ $cssScale = $this->cssScale;
+ $w2 = ($cssWidth * 2) . 'px';
+
+
+ $h = $cssHeight . 'px';
+
+ $wm = ($this->width * $this->multiply) . 'px';
+ $hm = ($this->height * $this->multiply) . 'px';
+ $w = $cssWidth . 'px';
+ $offsetLeft = round(($this->optimalWidth - $cssWidth) / 2, 3);
+ $offsetLeft2 = $offsetLeft * 2;
+ $offsetTop = round(($this->optimalHeight - $cssHeight) / 2, 3);
+ $navTop = ($cssHeight - 40 - 100) / 2;
+ $leftOfRightPage = (floor($cssWidth) - 1) . 'px';
+
+ $lessVariables['z'] = $this->z;
+ $lessVariables['book-page-width'] = $w;
+ $lessVariables['book-page-height'] = $h;
+ $lessVariables['book-page-ratio'] = floatval($w) / floatval($h);
+
+ $lessVariables['shadow-opacity'] = wsHTML5::colorToArray($this->theme->parametres->bookShadeColor)['opacity'] * 1.2;
+ $lessVariables['edges-display'] = $this->_lessBoolean($this->theme->parametres->usePageEdges);
+
+ $res[] = '.portrait #pages,.portrait .doublePage.page,.page,.doublePage._3d{width:' . $w . ';max-width:' . $w . ';height:' . $h . ';max-height:' . $h . '}';
+ $res[] = '.doublePage,#pages,#links,#searchHighlights{width:' . $w2 . ';max-width:' . $w2 . ';height:' . $h . ';max-height:' . $h . '}';
+ $res[] = '.landscape .doublePage._2d.axis_x.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(' . $w2 . ',0,0)') . '}';
+ $res[] = '.landscape .doublePage._2d.axis_x.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(-' . $w2 . ',0,0)') . '}';
+ $res[] = '.portrait .doublePage._2d.axis_x.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(' . $w . ',0,0)') . '}';
+ $res[] = '.portrait .doublePage._2d.axis_x.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(-' . $w . ',0,0)') . '}';
+ $res[] = '.doublePage._2d.axis_y.next{' . wsHTML5::writeCSSUA('transform', 'translate3d(0,' . $h . ',0)') . '}';
+ $res[] = '.doublePage._2d.axis_y.prev{' . wsHTML5::writeCSSUA('transform', 'translate3d(0,-' . $h . ',0)') . '}';
+
+ $res[] = '.doublePage._3d{left:' . $w . ';}';
+ $res[] = '#links.right{left:-' . $w . ';}';
+ $res[] = '.landscape .page.right{left:' . $w . '}';
+
+ $lessVariables['page-number-color'] = wsHTML5::colorToCSS($this->theme->parametres->colorPageNumber);
+ $lessVariables['display-page-number'] = $this->_lessBoolean($this->theme->parametres->displayPageNumber);
+ $lessVariables['page-transition-duration'] = $this->book->parametres->mobileTransitionDuration . 's';
+
+
+ $res[] = '.background{width:100%;height:100%}';
+
+ if ($this->cssSVGScale != 1) {
+ $texts = '.texts{' . wsHTML5::writeCSSUA('transform-origin', 'top left') . ';';
+ $texts .= wsHTML5::writeCSSUA('transform', 'scale(' . round((1 / $this->multiply) * $cssScale * $this->cssSVGScale, 3) . ')') . ';';
+ $texts .= 'width:' . ($wm / $this->cssSVGScale) . 'px; max-width:' . ($wm / $this->cssSVGScale) . 'px;';
+ $texts .= 'height:' . ($hm / $this->cssSVGScale) . 'px; max-height:' . ($hm / $this->cssSVGScale) . 'px;';
+ $texts .= '}';
+ } else {
+ $texts = '.texts{width:' . floor(floatval($w) + 4) . 'px;height:' . floor(floatval($h) + 4) . 'px;}';
+ }
+ $res[] = $texts;
+
+ // Theme
+ $shade = '.page .shade{';
+ $shade .= 'opacity:' . min(($this->theme->parametres->shadeAlpha * 2) / 100, 1) . ';';
+ $shade .= '}';
+ $res[] = $shade;
+
+ // SVG
+ $res[] = 'svg .fill-c-menu-back{fill:' . wsHTML5::colorToCSS($this->theme->parametres->couleurB) . ';}';
+ $res[] = 'svg .fill-c-menu-text{fill:' . wsHTML5::colorToCSS($this->theme->parametres->subTextColor) . ';}';
+
+ // Background
+ $res[] = $this->_cssBackground();
+
+ // Archives
+ // Header
+ $header = 'header{';
+ $header .= 'height:' . $this->theme->parametres->menuHeight . 'px;';
+ if ($this->theme->parametres->menuImage != '') {
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->menuImage, 'data/images/' . $this->theme->parametres->menuImage);
+ $header .= 'background-image:url(../images/' . $this->theme->parametres->menuImage . ');';
+ $header .= 'background-repeat:no-repeat;';
+ $header .= 'background-size:100% ' . $this->theme->parametres->menuHeight . 'px;';
+ } else {
+ $header .= 'background-color:' . wsHTML5::colorToCSS($this->theme->parametres->menuColor) . ';';
+ }
+ $header .= '}';
+ $res[] = $header;
+
+ //Icons
+ $res = array_merge($res, $this->writeIcons());
+ $res[] = '#nav #locales{background-color:' . wsHTML5::colorToCSS($this->theme->parametres->couleurI) . ';}';
+
+ // Logo
+ $logo = '#logo{';
+ if ($this->theme->parametres->logo) {
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->logo, 'data/images/' . $this->theme->parametres->logo);
+ $dim = CubeIT_Image::getimagesize($this->themeRoot . '/' . $this->theme->parametres->logo);
+ $logo .= 'background-image:url(../images/' . $this->theme->parametres->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;';
+ }
+ $logo .= '}';
+ $res[] = $logo;
+
+ // Credits
+ $res[] = 'footer,footer a{color:' . wsHTML5::colorToCSS($this->theme->parametres->creditsColor) . ';}';
+
+ // Arrows
+ $lessVariables['arrows-background'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
+ $lessVariables['arrows-color'] = wsHTML5::colorToCSS($this->theme->parametres->arrowsColor);
+
+ // Loader
+ $lessVariables['loader-background-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
+ $lessVariables['loader-foreground-color'] = wsHTML5::colorToCSS($this->theme->parametres->arrowsColor);
+
+ // Audio description buttons
+ $lessVariables['audiodescription-background'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
+ $lessVariables['audiodescription-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurA);
+
+ // Links Styles
+ $lessVariables['links-color'] = wsHTML5::colorToCSS($this->theme->parametres->linksColor);
+ $res = array_merge($res, $links);
+
+ // Bookmarks
+ if (!isset($this->book->parametres->bookmarkCornerSize)) {
+ $this->book->parametres->bookmarkCornerSize = 10;
+ }
+ $lessVariables['bookmark-corner-size'] = round($this->width * $this->book->parametres->bookmarkCornerSize * 0.0075 * $this->z) . 'px';
+ $lessVariables['bookmark-corner-offset'] = $this->book->parametres->bookmarkOffset . 'px';
+
+ // Menus
+ $menuColor = new CubeIT_Graphics_Color($this->theme->parametres->couleurB);
+ $menuColor->setAlpha(1);
+ $menuTextColor = wsHTML5::colorToCSS($this->theme->parametres->subTextColor);
+ $menuBreakpoint = empty($this->book->parametres->menuBreakpoint) ? '1023px' : $this->book->parametres->menuBreakpoint;
+
+ $lessVariables['menu-breakpoint'] = $menuBreakpoint;
+ $lessVariables['menu-background'] = $menuColor->toCSS();
+ if ($this->theme->parametres->subSecondaryColor) {
+ $lessVariables['menu-button-background'] = wsHTML5::colorToCSS($this->theme->parametres->subSecondaryColor);
+ } else {
+ $lessVariables['menu-background-green'] = 'max(45, min(255-45, green(@menu-background)))';
+ $lessVariables['menu-background-red'] = 'max(45, min(255-45, red(@menu-background)))';
+ $lessVariables['menu-background-blue'] = 'max(45, min(255-45, blue(@menu-background)))';
+ $lessVariables['menu-button-background'] = 'overlay(rgb(@menu-background-red, @menu-background-green, @menu-background-blue), #c0c0c0)';
+ }
+
+ $lessVariables['menu-text'] = $menuTextColor;
+ $lessVariables['menu-field-background'] = wsHTML5::colorToCSS($this->theme->parametres->subFieldColor);
+ $lessVariables['menu-field-text'] = wsHTML5::colorToCSS($this->theme->parametres->subTextFieldColor);
+ $lessVariables['menu-select-background'] = wsHTML5::colorToCSS($this->theme->parametres->subSelectColor);
+ $lessVariables['menu-select-text'] = wsHTML5::colorToCSS($this->theme->parametres->subTextSelectColor);
+ $lessVariables['icon-color'] = wsHTML5::colorToCSS($this->theme->parametres->couleurI);
+ $lessVariables['menu-overlay'] = wsHTML5::colorToCSS($this->theme->parametres->popupVideoOverlay);
+
+ // Chapters
+
+
+ foreach ($this->book->chapters as $chapter) {
+ if (substr($chapter->page, 0, 1) != '#') {
+ continue;
+ }
+ if ($chapter->color == '') {
+ continue;
+ }
+ $color = trim($chapter->color, '#');
+ $lessContents .= '.mview.c_' . $color . '{.menu-color(#' . $color . ');}';
+ }
+
+ // Archives
+ if ($this->book->parametres->externalArchivesBack) {
+ $this->vdir->copy($this->wdir . '/' . $this->book->parametres->externalArchivesBack, 'data/images/' . $this->book->parametres->externalArchivesBack);
+ $res[] = '.mview.archives{background-image:url("../images/' . $this->book->parametres->externalArchivesBack . '");}';
+ }
+
+ # Index
+ $ratio = $this->width / $this->height;
+ $thumbh = round(100 / $ratio);
+ $this->config->thumbHeight = $thumbh;
+ $lessVariables['thumb-height'] = $thumbh . 'px';
+
+ #tooltip
+ $lessVariables['tooltip-background'] = wsHTML5::colorToCSS($this->theme->parametres->tooltipBackColor);
+ $lessVariables['tooltip-color'] = wsHTML5::colorToCSS($this->theme->parametres->tooltipTextColor);
+
+ # ZoomPopup close button background
+ $res[] = '.zoomPopupClose {background-color:' . wsHTML5::colorToCSS($this->theme->parametres->couleurB) . ';}';
+
+
+ $this->_writeLess($lessVariables, $lessContents);
+
+ $res = array_chunk($res, 3500);
+ foreach ($res as $k => $css) {
+ $this->stylesheets[] = 'data/style/style_' . $k . '.css';
+ $this->vdir->file_put_contents(sprintf($file, $k), implode("\n", $css));
+ $this->log('Write CSS ' . sprintf($file, $k));
+ }
+ return count($res);
+ }
+
+ protected function _writeLess($variables, $lessContents = '')
+ {
+ if ($this->widget) {
+ $this->lessFiles[] = 'widget';
+ }
+ foreach ($this->specialCSS as $s) {
+ $this->lessFiles[] = 'special/' . $s;
+ }
+
+ $tmp = CubeIT_Files::tmpdir();
+
+ $from = $this->assets . '/style/*';
+ `cp -r $from $tmp`;
+
+ $bookVariables = array();
+ foreach ($variables as $k => $v) {
+ $bookVariables[] = '@' . trim($k) . ':' . $v . ';';
+ }
+ file_put_contents($tmp . '/book-variables.less', implode("\n", $bookVariables));
+ file_put_contents($tmp . '/additional.less', $lessContents);
+
+ foreach ($this->lessFiles as $f) {
+ $source_less = $this->assets . '/style/' . $f . '.less';
+ $destination_less = $tmp . '/' . $f . '.less';
+ $destination_css = $tmp . '/' . $f . '.css';
+
+ if (!file_exists($source_less)) {
+ continue;
+ }
+
+ // LESS file might be in a subfolder, so create if it doesn't exist
+ if (!is_dir(dirname($destination_less))) {
+ mkdir(dirname($destination_less), 0777, true);
+ }
+
+ // Less files must be copied to temporary directory so they'll
+ // have access to the variables generated in book-variables.less
+ copy($source_less, $destination_less);
+ $less = new CubeIT_CommandLine('/usr/local/bin/lessc');
+ $less->setArg(null, $destination_less);
+ $less->setArg(null, $destination_css);
+ $less->execute();
+ $less->debug();
+ if (!file_exists($destination_css)) {
+ die($less->output);
+ }
+ $this->vdir->copy($destination_css, 'style/' . $f . '.css');
+ if ($f != 'widget') {
+ $this->stylesheets[] = 'style/' . $f . '.css';
+ }
+ }
+ }
+
+ protected function _cssBackground()
+ {
+ $body = '#background,#splash{';
+ $body .= 'background-color:#' . $this->theme->parametres->backgroundColor . ' !important;';
+ switch ($this->theme->parametres->repeat) {
+ case wsTheme::REPEAT:
+ $body .= 'background-repeat:repeat;';
+ break;
+ case wsTheme::NONE:
+ $body .= 'background-repeat:no-repeat;';
+ break;
+ case wsTheme::RATIO:
+ $body .= 'background-repeat:no-repeat;';
+ $body .= 'background-size:cover;';
+ break;
+ case wsTheme::STRETCH:
+ $body .= 'background-repeat:no-repeat;';
+ $body .= 'background-size:100% 100%;';
+ break;
+ }
+ if ($this->theme->parametres->backgroundImage != '') {
+ $bi = $this->themeRoot . '/' . $this->theme->parametres->backgroundImage;
+ if (file_exists($bi)) {
+ $dbi = CubeIT_Image::getimagesize($bi);
+ $this->config->backgroundImageDimensions = array('width' => $dbi[0], 'height' => $dbi[1]);
+ }
+
+ $this->vdir->copy($this->themeRoot . '/' . $this->theme->parametres->backgroundImage, 'data/images/' . $this->theme->parametres->backgroundImage);
+ $body .= 'background-image:url(../images/' . $this->theme->parametres->backgroundImage . ');';
+ $body .= 'background-position:';
+
+ switch ($this->theme->parametres->backgroundVAlign) {
+ case wsTheme::TOP:
+ $body .= 'top';
+ break;
+ case wsTheme::MIDDLE:
+ $body .= 'center';
+ break;
+ case wsTheme::BOTTOM:
+ $body .= 'bottom';
+ break;
+ }
+ $body .= ' ';
+ switch ($this->theme->parametres->backgroundHAlign) {
+ case wsTheme::LEFT:
+ $body .= 'left';
+ break;
+ case wsTheme::CENTER:
+ $body .= 'center';
+ break;
+ case wsTheme::RIGHT:
+ $body .= 'right';
+ break;
+ }
+ $body .= ';';
+ }
+
+ $body .= '}';
+
+ return $body;
+ }
+
+ public static function writeCSSUA($property, $value)
+ {
+ $res = array();
+ foreach (self::$uaPrefixes as $prefix) {
+ $res[] = $prefix . $property . ':' . $value;
+ }
+ return implode(';', $res);
+ }
+
+ protected function base62($val)
+ {
+ $chars = '0123456789abcdefghijklmnopqrstuvwxyz';
+ $base = strlen($chars);
+ $str = '';
+ do {
+ $i = $val % $base;
+ $str = $chars[$i] . $str;
+ $val = ($val - $i) / $base;
+ } while ($val > 0);
+ return $str;
+ }
+
+ public function copyLinkDir($source, $dest)
+ {
+ $this->vdir->copyDirectory($source, $dest);
+ }
+
+ public function simpleCopyLinkFile($source, $dest, $addVdir = true)
+ {
+ if ($addVdir) {
+ $dest = $dest;
+ }
+
+ $this->vdir->copy($source, $dest);
+ }
+
+ public function copyLinkFile($source, $dest, $video = false)
+ {
+ if ($video && $this->book->parametres->mobileVideosPath != '') {
+
+ }
+
+ $origDir = $this->wdir;
+ $types = $this->getVideosFormats();
+ if ($video) {
+ wsTools::encodeWebVideos($origDir . $source, null, true);
+ $e = explode('.', $source);
+ array_pop($e);
+ $base = implode('.', $e);
+ $source = array();
+ foreach ($types as $type) {
+ $source[] = $base . '.' . $type;
+ }
+ }
+
+ if (!is_array($source)) {
+ $source = array($source);
+ }
+
+ foreach ($source as $so) {
+ $s = $origDir . $so;
+ if (file_exists($s)) {
+ $d = $dest . '/' . $so;
+ $this->simpleCopyLinkFile($s, $d, false);
+ }
+ }
+ }
+
+ public function __destruct()
+ {
+
+ }
+
+
+ public function unzipFile($file, $moveAssets = false, $baseDir = null)
+ {
+ $fdir = is_null($baseDir) ? 'data/links/' . str_replace('.', '_', $file) : $baseDir;
+
+ $tmp = CubeIT_Files::tmpdir();
+ $dir = $tmp . '/' . $fdir;
+ if (file_exists($dir) && is_file($dir)) {
+ unlink($dir);
+ }
+ if (!file_exists($dir)) {
+ mkdir($dir, 0777, true);
+ }
+ $unzip = new cubeCommandLine('unzip');
+ $unzip->setArg(null, $this->wdir . '/' . $file);
+ $unzip->setArg('d', $dir);
+ $unzip->execute();
+
+ if ($moveAssets) {
+ `mv $dir/Assets/* $dir`;
+ rmdir($dir . '/Assets');
+ }
+
+ return array('dir' => $dir, 'fdir' => $fdir);
+ }
+
+ public function getConfigZIP($d)
+ {
+ $res = array('width' => 0, 'height' => 0);
+ if (file_exists($d . '/index.html')) {
+ $doc = new DOMDocument();
+ $doc->loadHTMLFile($d . '/index.html');
+ $xpath = new DOMXPath($doc);
+ $c = $xpath->query("//canvas");
+ foreach ($c as $canvas) {
+ /* @var $canvas DOMElement */
+ $res['width'] = intval((string)$canvas->getAttribute('width'));
+ $res['height'] = intval((string)$canvas->getAttribute('height'));
+ }
+
+ $r = array('html' => 'index.html', 'inject' => array(), 'injectcss' => array(), 'injectjs' => array());
+ } else {
+ $r = array('html' => false, 'inject' => array(file_get_contents($d . '/init.js')), 'injectcss' => array('multimedia.css'), 'injectjs' => array('multimedia.js'));
+ }
+ $res = array_merge($res, $r);
+ return $res;
+ }
}