Skip to main content
Participating Frequently
July 1, 2024
Question

Scripting - Why certain Linked Smart Objects with Broken Link don't return "link" property?

  • July 1, 2024
  • 1 reply
  • 554 views

Hello to all,

 

A quick scripting question:

Is there a way to determine which linked smart object with broken link will return link, and which won't?

 

This is the script I am running:

function s2t(str) { return stringIDToTypeID(str); }
function c2t(ch) { return charIDToTypeID(ch); }

function gather_smart_objects(){
    var doc_ref = new ActionReference();
    doc_ref.putIdentifier(s2t("document"), activeDocument.id);
    var doc_descriptor = executeActionGet(doc_ref);
    var layer_count = doc_descriptor.getInteger(s2t("numberOfLayers"));
    var nr_of_smart_linked = 0;
    var nr_of_smart_linked_with_missing_link = 0;
    for(var layer_index = 1; layer_index <= layer_count; ++layer_index){
        var layer_ref = new ActionReference();
        layer_ref.putProperty(s2t("property"), s2t("layerKind"));
        layer_ref.putIndex(s2t("layer"), layer_index);
        var layer_descriptor = executeActionGet(layer_ref);
        if(layer_descriptor.getInteger(s2t("layerKind")) == 5){
            var layer_id_ref = new ActionReference();
            layer_id_ref.putProperty(s2t("property"), s2t("layerID"));
            layer_id_ref.putIndex(s2t("layer"), layer_index);
            var layer_id_descriptor = executeActionGet(layer_id_ref);
            var layer_id = layer_id_descriptor.getInteger(s2t("layerID"));
            var action_ref = new ActionReference();
            action_ref.putIdentifier(c2t('Lyr '), layer_id);
            var action_descriptor = executeActionGet(action_ref);
            var smart_object = action_descriptor.getObjectValue(s2t("smartObject"));
            if (smart_object.hasKey(s2t("linked")) && smart_object.getBoolean(s2t("linked"))) {
                ++nr_of_smart_linked;
                if (!smart_object.hasKey(s2t("link"))) {
                    ++nr_of_smart_linked_with_missing_link;
                }
            }
        }
    }
    alert(nr_of_smart_linked);
    alert(nr_of_smart_linked_with_missing_link);
}

gather_smart_objects();

 

I have 121 linked smart objects with broken links in my psd.

 

nr_of_smart_linked evaluates to 121, 

nr_of_smart_linked_with_missing_link evaluates to 22. 

 

For this psd, I always get the same results, so it's not random, but I am lost as to understand why those 22 never give back the link.

 

Any help, even a direction in which to continue the investigation, would be much appreciated.

This topic has been closed for replies.

1 reply

c.pfaffenbichler
Community Expert
Community Expert
July 1, 2024

Please provide the sample file or a better description with screenshots to illustrate. 

BorisTAuthor
Participating Frequently
July 1, 2024

The numbers are there simply for the demonstration purposes. I have encountered this behavior in other psds that are missing smart object links. Unfortunately, I am not able to share the file in question.

 

The most important thing is that I have a clean machine, freshly installed photoshop, I have received this psd, so none of the links actually exist on my machine. That's why they are broken. And that was the intention.

 

When I run the script above, I get the result that some broken links have "link" property and others don't. That's the best way i can describe the setup. And the details are in the script code.

BorisTAuthor
Participating Frequently
July 2, 2024
quote

Exactly. 

Did you try using the value of the boolean property in an if-clause or not? 

 

Does this provide the same »faulty« result? 

function s2t(str) { return stringIDToTypeID(str); }
function c2t(ch) { return charIDToTypeID(ch); }

function gather_smart_objects(){
    var doc_ref = new ActionReference();
    doc_ref.putIdentifier(s2t("document"), activeDocument.id);
    var doc_descriptor = executeActionGet(doc_ref);
    var layer_count = doc_descriptor.getInteger(s2t("numberOfLayers"));
    var nr_of_smart_linked = 0;
    var nr_of_smart_linked_with_missing_link = 0;
    for(var layer_index = 1; layer_index <= layer_count; ++layer_index){
        var layer_ref = new ActionReference();
        layer_ref.putProperty(s2t("property"), s2t("layerKind"));
        layer_ref.putIndex(s2t("layer"), layer_index);
        var layer_descriptor = executeActionGet(layer_ref);
        if(layer_descriptor.getInteger(s2t("layerKind")) == 5){
            var layer_id_ref = new ActionReference();
            layer_id_ref.putProperty(s2t("property"), s2t("layerID"));
            layer_id_ref.putIndex(s2t("layer"), layer_index);
            var layer_id_descriptor = executeActionGet(layer_id_ref);
            var layer_id = layer_id_descriptor.getInteger(s2t("layerID"));
            var action_ref = new ActionReference();
            action_ref.putIdentifier(c2t('Lyr '), layer_id);
            var action_descriptor = executeActionGet(action_ref);
            var smart_object = action_descriptor.getObjectValue(s2t("smartObject"));
            if (smart_object.hasKey(s2t("linked")) && smart_object.getBoolean(s2t("linked"))) {
                ++nr_of_smart_linked;
                if (smart_object.getBoolean(stringIDToTypeID('linkMissing')) == true) {
/*if (!smart_object.hasKey(s2t("link"))) {*/
                    ++nr_of_smart_linked_with_missing_link;
                }
            }
        }
    }
    alert(nr_of_smart_linked);
    alert(nr_of_smart_linked_with_missing_link);
}

gather_smart_objects();

 


Hi, 

 

I forgot to add, Thank You for Your time.

 

First, to answer Your question, Yes, I have used the "linkMissing" property.

 

Second, I was able to create the .psd that produces this behavior. The steps are rather simple, the important part is to make it on the different machine to the one that You are trying to test on.

 

The steps are:

 

  1.  Create first .psd file
  2.  Create second .psd file
  3.  In the second .psd file, add first .psd using "File -> Place Linked..."
  4.  Rename or delete Your first .psd file.

 

If on the second .psd You run the script below, You will see that there will be 3 alerts, first two will say that there is 1 object each (1 smart object, 1 smart object with 'linkMissing' property set to False). The third alert will say there is no smart object with 'linkMissing' property set to False and missing 'link' property.

 

Now, I've created the provided .psd in the exact same way. And, if You download my psd, and run the script on it, the last alert will also say there is 1 smart object with 'linkMissing' property set to False and missing 'link' property.

 

 

 

 

function s2t(str) { return stringIDToTypeID(str); }
function c2t(ch) { return charIDToTypeID(ch); }

function gather_smart_objects(){
    try {
        var doc_ref = new ActionReference();
        doc_ref.putIdentifier(s2t("document"), activeDocument.id);
        var doc_descriptor = executeActionGet(doc_ref);
        var layer_count = doc_descriptor.getInteger(s2t("numberOfLayers"));
        var linked_smart_objects = 0;
        var linked_smart_objects_link_missing = 0;
        var linked_smart_objects_link_missing_no_link_property = 0;
        for (var layer_index = 1; layer_index <= layer_count; ++layer_index) {
            var layer_ref = new ActionReference();
            layer_ref.putProperty(s2t("property"), s2t("layerKind"));
            layer_ref.putIndex(s2t("layer"), layer_index);
            var layer_descriptor = executeActionGet(layer_ref);
            if (layer_descriptor.getInteger(s2t("layerKind")) == 5) {
                var layer_id_ref = new ActionReference();
                layer_id_ref.putProperty(s2t("property"), s2t("layerID"));
                layer_id_ref.putIndex(s2t("layer"), layer_index);
                var layer_id_descriptor = executeActionGet(layer_id_ref);
                var layer_id = layer_id_descriptor.getInteger(s2t("layerID"));
                var action_ref = new ActionReference();
                action_ref.putIdentifier(c2t('Lyr '), layer_id);
                var action_descriptor = executeActionGet(action_ref);
                var smart_object = action_descriptor.getObjectValue(s2t("smartObject"));
                if (smart_object.hasKey(s2t("linked")) && smart_object.getBoolean(s2t("linked"))) {
                    ++linked_smart_objects;
                    if (smart_object.getBoolean(s2t("linkMissing"))) {
                        ++linked_smart_objects_link_missing;
                        if (!smart_object.hasKey(s2t("link"))) {
                            ++linked_smart_objects_link_missing_no_link_property;
                        }
                    }
                }
            }
        }

        alert("Linked smart objects: " + linked_smart_objects);
        alert("Linked smart objects with 'linkMissing' set to True: " + linked_smart_objects_link_missing);
        alert("Linked smart objects with 'linkMissing' set to True and no 'link' property: " + linked_smart_objects_link_missing_no_link_property);
    } catch (e) {
        alert("Something went wrong. Reason: " + e);
    }
}

gather_smart_objects();
alert("Done!");

 

 

I am running all this on Mac, Photoshop in question is

 

Adobe Photoshop Version: 25.9.1 20240610.r.626 e3aae35 x64

 

Please, bear in mind that I wasn't very careful with the active object insid the script, my Photoshop only had one .psd open at all times, when running the script.