Git Product home page Git Product logo

skrol29 / opentbs Goto Github PK

View Code? Open in Web Editor NEW
64.0 7.0 17.0 3.47 MB

With OpenTBS you can merge OpenOffice - LibreOffice and Ms Office documents with PHP using the TinyButStrong template engine. Simple use OpenOffice - LibreOffice or Ms Office to edit your templates : DOCX, XLSX, PPTX, ODT, OSD, ODP and other formats. That is the Natural Template philosophy.

Home Page: http://www.tinybutstrong.com/opentbs.php

PHP 64.17% HTML 35.83%
php template-engine docx pptx xlsx odt ods odp microsoft-office libreoffice

opentbs's Introduction

OpenTBS

http://www.tinybutstrong.com/opentbs.php

With OpenTBS you can merge LibreOffice, OpenOffice and Ms Office documents with PHP using the TinyButStrong template engine. Simple use OpenOffice - LibreOffice or Ms Office to edit your templates : DOCX, XLSX, PPTX, ODT, ODS, ODP and other formats. That is the Natural Template philosophy.

Now OpenTBS can also read data in workbooks (XLSX and ODS files).

Documentation

For documentation see http://www.tinybutstrong.com/opentbs.php?doc

Demo

For online demo see http://www.tinybutstrong.com/opentbs.php?demo

Download

https://github.com/Skrol29/opentbs/releases

Licence

OpenTBS is released under the LGPL (Lesser General Public Licence) version 3.0.

Distribution repository

OpenTBS in on GitHub since version 1.3.2.

OpenTBS versions 1.9.11 or later can be installed with Composer.

OpenTBS is also on Packagist.

opentbs's People

Contributors

roxblnfk avatar skrol29 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

opentbs's Issues

Capture output of $tbs->PlugIn(OPENTBS_DEBUG_XML_SHOW)?

Sorry if this is a dumb question but Is there a way I can make the above return the DEBUG output, rather than immediately echoing it to the caller?

I'd like to do something like this:

$debugOutput = $tbs->PlugIn(OPENTBS_DEBUG_XML_SHOW);

and process $debugOutput before sending to the user.

I tried but $debugOutput was always empty.

Feature request: changepic from image-data instead of image-file?

Hi,

thank you for this nice package!

It would be nice to be able to insert picture (and maybe other file-data) from a PHP string instead of a file-name, as an additional option. Of course, one can always first copy the data to a temporary file on the server and then insert this file, but it would be convenient to be able to add the file-data directly without having to dump it to disk.

Relative paths

Documentation clearly states that relative paths are supported, however I could make it work.

Quick look inside the code gives me an idea that in fact only absolute paths are supported.

Any plans to path paths relative to template path (or something else)?

Question

Hi,

Can you give an example of how to add a new slide to the archive with the code below from the documentation please ?

I dont Inderstand what the variable $Data should contain.

// OpenTBS >= 1.6.0
$TBS->Plugin(OPENTBS_ADDFILE, $Name, $Data, $DataType=OPENTBS_STRING, $Compress=true);

Thank you.

Word found unreadable content in [file name]

Word found unreadable content in [file name]. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.

This started happening a day or two ago. Is this an issue with Word, or OpenTBS?

MergeBlock issue with .pptx

Hi,

Don't know if it's a relevant issue, but I had diffculties to use $TBS->MergeBlock() in tables or textareas in Powerpoint 2016. Merging wasn't working everytime and didn't know why.
I noticed first that using tables it was working, until I changed some format thing or row/column size... wasn't ok with that.
Finally, I noticed that some ok my template codes where underlined in red for mispelling. So, deactivating the automatic spellcheker for my tables and textareas solved everything so far !

NB : A huge thanks to @Skrol29 for those amazing scripts !

Replacing charts in a multi-slide powerpoint presentation does not work correctly if charts on different slides share a name.

Hi,

my situation is as follows:
I have a 4 slide presentation and on each slide there is one chart with "Chart1" in its alternative text field.
After sequentially selecting each slide with OPENTBS_SELECT_SLIDE and replacing the data of Chart1 with OPENTBS_CHART only the data on the first slide changes. This seems like a bug to me, unless the chart name should be unique within the entire presentation (in which case that should be mentioned in the docs in my opinion).

After some debugging I found the reason:

$ChartRef is the name of the Chart as specified in the alt text field (so "Chart1" in our case).

The function OpenXML_ChartInit() builds an array of all charts used in the presentation with the powerpoint-internal chart name as keys.
In the function OpenXML_ChartFind, which is executed every time OPENTBS_CHART is called, we try accessing this array with $ChartRef as a key (which is dangerous in the first place since if we decide to put chart1, chart2, etc. or any name that is coincidentally also used by powerpoint internally then we end up selecting completely different charts! This should also be in the documentation).

Since "Chart1" is not an array key, we fetch the correct chart on the currently open slide (which is the first slide in the presentation) with MsPowerpoint_SearchInSlides(). After the chart has been fetched, this chart is added to the chart array returned by OpenXML_ChartInit() using $ChartRef as the key.

After selecting the 2nd slide in the presentation with OPENTBS_SELECT_SLIDE I want to change the data of Chart1. The OPENTBS_CHART command calls the function OpenXML_ChartFind again and checks if "Chart1" is an array key in the chart array mentioned earlier. Since it was added earlier when we were changing data on slide 1. This means every time we want to change a chart with name "Chart1" on any slide in the presentation we end up changing the first occurence of "Chart1".

Fix:

For my use case, simply removing the 'is $ChartRef an array key'-Check fixed the issue. Alternatively, appending the current slide ID ($this->TbsCurrIdx) to $ChartRef should resolve this issue. without breaking anything.

Thanks!

Autoload plugin

Hello. Can't add plugin support. Sample code (one of the options):

$tbs = new OpenTBS();
$ok = class_exists('clsTbsAggregate', true);
$tbs->PlugIn(TBS_INSTALL, 'clsTbsAggregate');

After running the script, a notification will appear
<br /><b>TinyButStrong Error</b> with plug-in 'clsTbsAggregate': no class named 'clsTbsAggregate' is found, and no function named 'tbspi_clsTbsAggregate_OnInstall' is found.<br />

At the same time, there is a class.

ope=changepic does not replace SVG, only the preview-bitmap

No clue, if this is the right place to mention issues, but here goes.

If I make an empty powerpoint, and I insert an image with SVG file as source, Powerpoint creates a bitmap-preview of that SVG and gives both resources for the same picture.

OpenTBS then replaces the 'main' image (the bitmap preview), but not the 'svg extra data'. When opening the presentation, you'll see the original SVG file because that data is untouched and used by office.

Original image in the input-powerpoint:

            <p:pic>
                <p:nvPicPr>
                    <p:cNvPr id="5" name="Graphic 4" descr="[flag;ope=changepic;tagpos=inside;]">
                        <a:extLst>
                            <a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}">
                                <a16:creationId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" id="{C57ABE97-03D1-4C1A-87CD-E9EAF41007A4}" />
                            </a:ext>
                        </a:extLst>
                    </p:cNvPr>
                    <p:cNvPicPr>
                        <a:picLocks noChangeAspect="1" />
                    </p:cNvPicPr>
                    <p:nvPr />
                </p:nvPicPr>
                <p:blipFill>
                    <a:blip r:embed="rId2">
                        <a:extLst>
                            <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                                <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0" />
                            </a:ext>
                            <a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}">
                                <asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="rId3" />
                            </a:ext>
                        </a:extLst>
                    </a:blip>
                    <a:stretch>
                        <a:fillRect />
                    </a:stretch>
                </p:blipFill>
                <p:spPr>
                    <a:xfrm>
                        <a:off x="1809750" y="571500" />
                        <a:ext cx="8572500" cy="5715000" />
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                        <a:avLst />
                    </a:prstGeom>
                </p:spPr>
            </p:pic>

And the output of that picture after OpenTBS:

            <p:pic>
                <p:nvPicPr>
                    <p:cNvPr id="5" name="Graphic 4" descr="">
                        <a:extLst>
                            <a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}">
                                <a16:creationId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" id="{C57ABE97-03D1-4C1A-87CD-E9EAF41007A4}" />
                            </a:ext>
                        </a:extLst>
                    </p:cNvPr>
                    <p:cNvPicPr>
                        <a:picLocks noChangeAspect="1" />
                    </p:cNvPicPr>
                    <p:nvPr />
                </p:nvPicPr>
                <p:blipFill>
                    <a:blip r:embed="opentbs1">
                        <a:extLst>
                            <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                                <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0" />
                            </a:ext>
                            <a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}">
                                <asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="rId3" />
                            </a:ext>
                        </a:extLst>
                    </a:blip>
                    <a:stretch>
                        <a:fillRect />
                    </a:stretch>
                </p:blipFill>
                <p:spPr>
                    <a:xfrm>
                        <a:off x="1809750" y="571500" />
                        <a:ext cx="8572500" cy="5715000" />
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                        <a:avLst />
                    </a:prstGeom>
                </p:spPr>
            </p:pic>

You'll notice that OpenTBS replaced the first reference, on the a:blip tag (the r:embed property is changed to the new picture).

But inside that tag, there is a asvg:svgBlip tag which still points to the same resource as before (r:embed="rId3").
If I edit that file to change the 2nd reference also to r:embed="opentbs1" , the edit actually works!

Removing data source from .docx after merge...

Usually, after performing a mailmerge, the document is 'flattened' and all merge fields / source data is removed. I can't see any option to do this and when I load the target document, it displays "Opening this document will run the following SQL command...". Here is my code to do the mail merge:

	$TBS = new clsTinyButStrong;
	$TBS->Plugin(TBS_INSTALL, OPENTBS_PLUGIN);
	$TBS->PlugIn(OPENTBS_SELECT_HEADER);	// process merge fields in header
	$TBS->PlugIn(OPENTBS_SELECT_FOOTER);	// process merge fields in footer
	$TBS->MergeBlock('',$this->aMergeData);
	$TBS->LoadTemplate($this->sSourceFilename, OPENTBS_ALREADY_UTF8);
	$TBS->Show(OPENTBS_FILE, $this->sTargetFilename);

text:span elements shadow TBS tags

Hi,

I have the problem that my version of Libreoffice sometimes likes to insert superfluous text:span elements. The problem is that this result in OpenTBS failing to substitute tag. For example I have the tag
[onshow.orchestra:treasurer:email]
which sometimes is "cut" into pieces in content.xml like
<text:span text:style-name="T27">[</text:span><text:span text:style-name="T24">onshow.orchestra:treasurer:email]</text:span>
So in this particular case the leading square-bracket is separated by this span element.

Is there a way to make OpenTBS "fix" this issue or to prevent LibreOffice from doing things like this?

Here is the particular Office-file:

instrument-insurance-record.odt

In this particular example the [onshow.orchestra:treasurer:email] is correctly substituted in the field below the signature, but not in the sender-address-field of the letter.

Any known work-around, except unzipping, editing and re-packing the document?

Kind thanks

Claus

Picture replacement don't work with different open close chars.

Standard open and close chars are: "[" and "]", when it's changed to another for example: "{" and "}" picture replacement don't work correctly.

There is hard coded "[" and "]" in tbs_plugin_opentbs.php on line 657:

# $tag = "[$name;ope=changepic;tagpos=inside;$prms_flat]";

simple fix:
$tag = $this->TBS->_ChrOpen."$name;ope=changepic;tagpos=inside;$prms_flat".$this->TBS->_ChrClose;

Multi-Lines not managed when reading ODS file

Hi

tbs_class.php : @Version 3.13.2
tbs_plugin_opentbs.php : @Version 1.10.7

We use openTbs.Plugin to read ODS file in which some cells contain multi-lines of string.

To reproduce :
In tbs_plugin_opentbs.php :: Sheet_VisitCells()
-> log $cell->Txt => text where multi-lines are made by </text:p><text:p/><text:p> (text:p/ could be multiple)
-> log $val after OpenDoc_GetCellValue() => return only first line

Looks like OpenDoc_GetCellValue() uses text:p to split text but in case of multi-lines it returns only the first one

We made an (ugly) override in Sheet_VisitCells() just before $val = $this->OpenDoc_GetCellValue($cell);

$cell->Txt = preg_replace_callback(
    '#(</text:p>)(<text:p/>)*(<text:p>)#', 
    function($matches) {
        $return = "\n";
        if (!empty($matches[2])) {
            for ($i=0; $i < substr_count($matches[0], $matches[2]); $i++) {
                $return .= "\n";
            }
        }
        return $return;
    }, 
    $cell->Txt
); 

Thanks
Nicolas

Applying styles to Excel cells

Hi, is there any detail description of how to deal with styles in Excel documents?

So far, this is what I found

  • If I create a new cell style it will be in styles.xml in cellStyles section
  • Knowing the name of my style I have to find xfId
    <cellStyles count="4">
        <cellStyle name="b" xfId="1" xr:uid="{A7F9842F-456D-3F46-9279-08C7AB310620}"/>
        <cellStyle name="g" xfId="2" xr:uid="{AEB4E562-675A-AE4F-A58D-992F5F115901}"/>
        <cellStyle name="n" xfId="3" xr:uid="{9D709C8C-79FD-E446-BF82-0F2831F359C2}"/>
        <cellStyle name="Normal" xfId="0" builtinId="0"/>
    </cellStyles>
  • Knowing the value of xfid I have to find a correspondent xf tag in cellXfs section
    <cellXfs count="44">

        ...  

        <xf numFmtId="0" fontId="15" fillId="9" borderId="1" xfId="1">
            <alignment horizontal="center"/>
        </xf>
        <xf numFmtId="0" fontId="14" fillId="8" borderId="1" xfId="2">
            <alignment horizontal="center"/>
        </xf>
        <xf numFmtId="0" fontId="16" fillId="10" borderId="1" xfId="3">
            <alignment horizontal="center"/>
        </xf>

        ...

    </cellXfs>
  • The index or in other words "position" of xf tag inside the cellXfs section will be the style number that I have to assign to the cell to have this cell styled.

Questions,

  • Is there any way to access styles.xml file in OpenTBS to calculate the "position" of my style within cellXfs knowing the name of my created style?
  • I tried to "re-assign" the value of style attribute in generated document, but it did not work for me. The final document had "internal" index for the style instead of a new index that I wanted to assign.
    For example, my cellXfs has 44 styles (in other words - xf tags), for some cells I want to assign an alternative style by having this construction in cells [row.cell.st;att=c#s] where row.cell is some value from MergeBlock. By having this [row.cell.st][row.cell.st;att=c#s] I can confirm that the value of row.cell.st is correct, but this does not affect the attribure within worksheets/_ref/sheet1.xml
    <c r="E4" s="41">
        <v>2</v>
    </c>

Where 41 is an internal style that I was trying to "override". Am I doing something wrong? How to assign a new value to s attribute? [row.cell.st;att=c#s] did not work for me.

Change color in powerpoint chart.

Hello ,
I'm trying to change the color of a chart in a powerpoint template.
I've managed to change text color looping through all slide with "OPENTBS_SELECT_SLIDE" and changing the color with $TBS->Source = str_replace("1E3C72", "00ffab", $TBS->Source);

How can I change the color of the chart ?
Thanks

Something like "block=tbs:sheet" possible?

I am not sure if this is the right place to ask, but I could not find another possibility:

I would like to repeat sheets in an ODS file instead of repeating rows in a sheet or cells in a row.
However it seems block=tbs:sheet does not exist.
And even if something like that is possible, LibreOffice does not allow sheet names including [ ] brackets.

Any way to solve this?

Exchange images using MergeBlock()

Hi,
I am having trouble exchanging images using the MergeBlock() function.
Maybe I am not using it correct or I'm missing something, not exactly sure, please see my example below.

include_once('tinybutstrong/tinybutstrong/tbs_class.php');
include_once('tinybutstrong/opentbs/tbs_plugin_opentbs.php');

$tinyButStrong = new clsTinyButStrong();
$tinyButStrong->PlugIn(TBS_INSTALL, OPENTBS_PLUGIN);
$tinyButStrong->LoadTemplate("test.docx", OPENTBS_ALREADY_UTF8);
echo time() . "</br>Before:</br><textarea rows='35' cols='200'>" . $tinyButStrong->Source . "</textarea>";
$pics = [["pics" => "test.png"]];
$blockSrc = $tinyButStrong->GetBlockSource("block1");
$tinyButStrong->MergeBlock(
    "block1",
    $pics
);

echo "</br>After:</br><textarea rows='35' cols='200'>" . $tinyButStrong->Source . "</textarea>";
$tinyButStrong->Show(OPENTBS_FILE, "test.docx");

template.docx: template.docx
test.png: test

Used versions:
php: 8.1.8
opentbs: 1.10.7

When comparing the BlockSource before and after the MergeBlock() call, you can see that tbs does not replace correct and corrupts the file contents.

Any help or conclusion is well appreciated, thanks in advance.

(works just fine with php 7.2 & opentbs 1.9.4)

Can I use sub blocks?

I am trying to create a template in LibreOffice Writer that uses subblocks. I can get the first-level block working but not the second?

The data is in a php array and is in a format like this (which I took from the example in the main docs re: "Automatic subblocks". So what I want to achieve is a table with rows by "moduleName" within each row contains another table of values for the label, name and value from the fieldData array:
Screenshot from 2020-04-22 15-37-21

I've tried various forms of the subblock template directive (I tried replacing ".val" with .label, .name and .value obviously) but can never get it to display any data in the rendered document. Here is the relevant part of the template:
Screenshot from 2020-04-22 15-36-56

And this is what gets rendered:
Screenshot from 2020-04-22 15-45-06

Any ideas? Thanks.

Adjusted pictures in repeated block cause document to become unreadable

Hello!
We have a problem with documents becoming unreadable when pictures in a repeating block (sub-block) configuration are adjusted.

image
I have a template like the above image where this block needs to be repeated an amount of times. Inside is a sub-block that contains a picture. This placeholder picture is replaced by a picture from an array like so:

[
    "findings" => [
        [
            "proofsegments" => [
                [
                    "image" => <pathtoimage>,
                ],
                [
                    "image" => <pathtoanotherimage>,
                ],
            ]
        ],
        [
            "proofsegments" => [
                [
                    "image" => <pathtoimage>,
                ],
                [
                    "image" => <pathtoanotherimage>,
                ],
            ]
        ],
    ],
];

This works fine as long as the image is not adjusted. To prevent the image potentially being wider than the page we use adjust=samewidth to make the image taller as necessary. This produces an unreadable document. The reason for this is twofold.

  1. The new height that is supposed to replace the old height in the xml replaces another portion of the xml
    <a:ext cx="5788152" cy="3090672"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom>6259281pPr></pic:pic>

It should be that the value 6259281 replaces the value of cy attribute in the <a:ext/> tag.

  1. The NewRid is also misplaced, breaking the neighboring xml tag.
    <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1Copentbs114:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>

It seems the misplaced alterations always are placed too far to the right. Adjusting pictures works fine when not in a repeating block.
In the function TbsPicAdjust the new height is replacing the old one in $Txt via $Txt = substr_replace($Txt, $new, $beg, $len); It appears that $beg now has a value that is too large causing the replacement to occur too far to the right. In my specific case subtracting 66 from $b placed the new height at the correct spot, but in another test with a different template document without sub-blocks the height was misplaced by a different amount. I suspect a similar thing is happening in TbsPicExternalPath or TbsPicAdd.

Thank you for your time!

The argument locale is ignored when merging a date

Hello,

We noticed a bug in the merging of dates in the latest version of opentbs.

We are using the following to merge a date :

[datetime.date;frm=dddd dd mmmm yyyy;locale]

Which is replaced with opentbs 1.9.11 by :
lundi 07 juin 2021

(We also have set the locale with a call to setlocale(LC_TIME, "fr_FR.utf8");)

But in the latest version of opentbs (1.10.2), we have the following :

Monday 07 June 2021

The locale seems to be ignored.
We had to rollback to the version 1.9.11

intl / l10n / number formatting

Is there any support for number locales different from EN/US? I know I can tell OpenTBS with e.g. ope=tbs:percent (or curr, etc.) that field is numeric. However, the number itself does not seem to be converted to the documents language.

Maybe related: if I format a cell in the template as percentage, the value will be displayed as zero after merging. In the XML I find something like this:

<table:table-cell table:style-name="Tabelle3.F3" office:value-type="percentage" office:value="0">
  <text:p text:style-name="P11">
    0.0068
  </text:p>
</table:table-cell>

So it seems that LibreOffice remembers the invalid number from the template, resulting from the TBS template field in square brackets. Also, if using e.g. German then we have a comma as decimal separator and a point to separate thousands, e.g. US 1,000.56 is 1.000,56 in German and a couple of other languages.

Is there any experience with OpenTBS in the context of non-US English?

Kind thanks for any hints!

changepic of block of images

Hi im trying to use a array of images like in the demo example, but i.m having some problems. I´m using the same code of the demo but i cant change the alt text of image that just stop work. I going explain what is going on below:

when i use the exactily image of docx, without change any thing in the image alt text, its work properly , but If change anything in alttext of the image, dont work anymore, even if in the end, the content of the alt text of the image is the same. its happens because when anyone save the document, the document.xml of the docx changes. So i did a diff with the document.xml of the docx documents, with exactly the same content and in result is show below:

image
the red is of the original docx, with the original image of the demo example
the green is of the saved docx, with the same content in alt text of the image, but i saved as a new docx file

to discover where is the problem i resolve to modifie the document.xml and recover docx document to make a merge thats workout. And i realized that when a leave only one "descr" attribute in document.xml reference the image that will iterate in array it workout.

Could be in first time that descr attribute appear in document.xml or second, both works since i leave only one reference.

Example:
Works:
image

works:
image

dont work
image

I have no ideia how can i solve this problem! cause i need to leave docx model free for changes.

Random XML rendering (blip/embed)

Hello,

Thanks again for sharing your Library.
I'm embedding images on a Word (docx) document and I'm actually facing a strange issue. There are somes XML attributes that are html encoded and some not.

On a file with 23 embed attributes, 2 are wrong like this one

<a:blip r:embed=&quot;rId12" cstate="print">

Other are corrects like the Following :

<a:blip r:embed="rId12" cstate="print">

When I checked function that generate this line, the quote symbol is correct

// phpdocx/classes/CreateElement.php:180
protected function generateBLIP($cstate = 'print')
    {
        $xml = '<' . CreateImage::NAMESPACEWORD1 .
                ':blip r:embed="rId' . $this->getRId() .
                '" cstate="' . $cstate .
                '"></' . CreateImage::NAMESPACEWORD1 .
                ':blip>__GENERATEBLIPFILL__';

        $this->_xml = str_replace('__GENERATEBLIPFILL__', $xml, $this->_xml);
    }

Did I do something wrong?

Version used: 3.10.1
PHP: 5.5.9 & 7.2.7

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.